From 1d84834a35194ddc98e743e78299f35a22b5403f Mon Sep 17 00:00:00 2001 From: otsmr Date: Tue, 8 Apr 2025 14:00:23 +0200 Subject: [PATCH] improve sending image directly to other user --- lib/main.dart | 2 - lib/src/components/user_context_menu.dart | 7 +- lib/src/providers/send_next_media_to.dart | 12 --- .../share_image_editor_view.dart | 32 ++++--- .../camera_to_share/share_image_view.dart | 10 +-- .../views/chats/chat_item_details_view.dart | 88 ++++++++++--------- lib/src/views/chats/chat_list_view.dart | 9 +- lib/src/views/chats/media_viewer_view.dart | 21 ++--- lib/src/views/home_view.dart | 9 +- 9 files changed, 87 insertions(+), 103 deletions(-) delete mode 100644 lib/src/providers/send_next_media_to.dart diff --git a/lib/main.dart b/lib/main.dart index fedb5eb..d63fd11 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,7 +7,6 @@ import 'package:twonly/src/providers/api_provider.dart'; import 'package:flutter/material.dart'; import 'package:logging/logging.dart'; import 'package:twonly/src/providers/hive.dart'; -import 'package:twonly/src/providers/send_next_media_to.dart'; import 'package:twonly/src/providers/settings_change_provider.dart'; import 'package:twonly/src/services/fcm_service.dart'; import 'package:twonly/src/services/notification_service.dart'; @@ -45,7 +44,6 @@ void main() async { runApp( MultiProvider( providers: [ - ChangeNotifierProvider(create: (_) => SendNextMediaTo()), ChangeNotifierProvider(create: (_) => settingsController), ], child: MyApp(), diff --git a/lib/src/components/user_context_menu.dart b/lib/src/components/user_context_menu.dart index 402e6a9..2f8a7bd 100644 --- a/lib/src/components/user_context_menu.dart +++ b/lib/src/components/user_context_menu.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:pie_menu/pie_menu.dart'; -import 'package:provider/provider.dart'; import 'package:twonly/src/database/twonly_database.dart'; -import 'package:twonly/src/providers/send_next_media_to.dart'; import 'package:twonly/src/utils/misc.dart'; +import 'package:twonly/src/views/camera_to_share/share_image_view.dart'; import 'package:twonly/src/views/chats/chat_item_details_view.dart'; import 'package:twonly/src/views/contact/contact_verify_view.dart'; import 'package:twonly/src/views/home_view.dart'; @@ -53,9 +52,7 @@ class _UserContextMenuState extends State { PieAction( tooltip: Text(context.lang.contextMenuSendImage), onSelect: () { - context - .read() - .updateSendNextMediaTo(widget.contact.userId.toInt()); + globalSendNextMediaToUser = widget.contact; globalUpdateOfHomeViewPageIndex(0); }, child: const FaIcon(FontAwesomeIcons.camera), diff --git a/lib/src/providers/send_next_media_to.dart b/lib/src/providers/send_next_media_to.dart deleted file mode 100644 index 8cabd54..0000000 --- a/lib/src/providers/send_next_media_to.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/foundation.dart'; - -// This provider will update the UI on changes in the contact list -class SendNextMediaTo with ChangeNotifier, DiagnosticableTreeMixin { - int? _sendNextMediaToUserId; - - int? get sendNextMediaToUserId => _sendNextMediaToUserId; - void updateSendNextMediaTo(int? userId) { - _sendNextMediaToUserId = userId; - notifyListeners(); - } -} diff --git a/lib/src/views/camera_to_share/share_image_editor_view.dart b/lib/src/views/camera_to_share/share_image_editor_view.dart index 60a6245..5be9d36 100644 --- a/lib/src/views/camera_to_share/share_image_editor_view.dart +++ b/lib/src/views/camera_to_share/share_image_editor_view.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/components/image_editor/action_button.dart'; import 'package:twonly/src/components/media_view_sizing.dart'; @@ -8,7 +7,6 @@ import 'package:twonly/src/components/notification_badge.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/providers/api/media.dart'; -import 'package:twonly/src/providers/send_next_media_to.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/camera_to_share/share_image_view.dart'; @@ -39,6 +37,7 @@ class _ShareImageEditorView extends State { int maxShowTime = 999999; String? sendNextMediaToUserName; double tabDownPostion = 0; + bool sendingImage = false; ImageItem currentImage = ImageItem(); ScreenshotController screenshotController = ScreenshotController(); @@ -261,11 +260,9 @@ class _ShareImageEditorView extends State { Widget build(BuildContext context) { pixelRatio = MediaQuery.of(context).devicePixelRatio; - int? sendNextMediaToUserId = - context.watch().sendNextMediaToUserId; - - if (sendNextMediaToUserId != null) { - updateAsync(sendNextMediaToUserId); + if (globalSendNextMediaToUser != null) { + sendNextMediaToUserName = + getContactDisplayName(globalSendNextMediaToUser!); } return Scaffold( @@ -410,9 +407,22 @@ class _ShareImageEditorView extends State { if (sendNextMediaToUserName != null) SizedBox(width: 10), if (sendNextMediaToUserName == null) SizedBox(width: 20), FilledButton.icon( - icon: FaIcon(FontAwesomeIcons.solidPaperPlane), + icon: sendingImage + ? SizedBox( + height: 12, + width: 12, + child: CircularProgressIndicator( + strokeWidth: 2, + color: Theme.of(context).colorScheme.inversePrimary, + ), + ) + : FaIcon(FontAwesomeIcons.solidPaperPlane), onPressed: () async { - if (sendNextMediaToUserId != null) { + if (sendingImage) return; + setState(() { + sendingImage = true; + }); + if (globalSendNextMediaToUser != null) { Uint8List? imageBytes = await getMergedImage(); if (!context.mounted) return; if (imageBytes == null) { @@ -420,15 +430,13 @@ class _ShareImageEditorView extends State { return; } sendImage( - [sendNextMediaToUserId], + [globalSendNextMediaToUser!.userId], imageBytes, _isRealTwonly, maxShowTime, ); Navigator.popUntil(context, (route) => route.isFirst); globalUpdateOfHomeViewPageIndex(1); - - // send hier... return; } Future imageBytes = getMergedImage(); diff --git a/lib/src/views/camera_to_share/share_image_view.dart b/lib/src/views/camera_to_share/share_image_view.dart index 0756786..cf31141 100644 --- a/lib/src/views/camera_to_share/share_image_view.dart +++ b/lib/src/views/camera_to_share/share_image_view.dart @@ -3,7 +3,6 @@ import 'dart:collection'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/components/best_friends_selector.dart'; import 'package:twonly/src/components/flame.dart'; @@ -13,10 +12,11 @@ import 'package:twonly/src/components/verified_shield.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/providers/api/media.dart'; -import 'package:twonly/src/providers/send_next_media_to.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/views/home_view.dart'; +Contact? globalSendNextMediaToUser; + class ShareImageView extends StatefulWidget { const ShareImageView( {super.key, @@ -47,10 +47,8 @@ class _ShareImageView extends State { void initState() { super.initState(); - int? sendNextMediaToUserId = - context.read().sendNextMediaToUserId; - if (sendNextMediaToUserId != null) { - _selectedUserIds.add(sendNextMediaToUserId); + if (globalSendNextMediaToUser != null) { + _selectedUserIds.add(globalSendNextMediaToUser!.userId); } Stream> allContacts = diff --git a/lib/src/views/chats/chat_item_details_view.dart b/lib/src/views/chats/chat_item_details_view.dart index adfc82a..0d1f09d 100644 --- a/lib/src/views/chats/chat_item_details_view.dart +++ b/lib/src/views/chats/chat_item_details_view.dart @@ -3,7 +3,6 @@ import 'dart:collection'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/components/animate_icon.dart'; import 'package:twonly/src/components/better_text.dart'; @@ -16,8 +15,8 @@ import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/json_models/message.dart'; import 'package:twonly/src/providers/api/api.dart'; import 'package:twonly/src/providers/api/media.dart'; -import 'package:twonly/src/providers/send_next_media_to.dart'; import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/views/camera_to_share/share_image_view.dart'; import 'package:twonly/src/views/chats/media_viewer_view.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/views/contact/contact_view.dart'; @@ -25,10 +24,10 @@ import 'package:twonly/src/views/home_view.dart'; class ChatListEntry extends StatelessWidget { const ChatListEntry( - this.message, this.userId, this.lastMessageFromSameUser, this.reactions, + this.message, this.contact, this.lastMessageFromSameUser, this.reactions, {super.key}); final Message message; - final int userId; + final Contact contact; final bool lastMessageFromSameUser; final List reactions; @@ -71,10 +70,13 @@ class ChatListEntry extends StatelessWidget { } else { child = Text(content.text, style: TextStyle(fontSize: 14)); } - children.add(Padding( - padding: EdgeInsets.only(left: 3), - child: child, - )); + children.insert( + 0, + Padding( + padding: EdgeInsets.only(left: 3), + child: child, + ), + ); } } @@ -136,7 +138,7 @@ class ChatListEntry extends StatelessWidget { Navigator.push( context, MaterialPageRoute(builder: (context) { - return MediaViewerView(userId); + return MediaViewerView(contact); }), ); } else { @@ -354,38 +356,40 @@ class _ChatItemDetailsViewState extends State { body: SafeArea( child: Column( children: [ - Expanded( - child: ListView.builder( - itemCount: messages.length, - reverse: true, - itemBuilder: (context, i) { - bool lastMessageFromSameUser = false; - if (i > 0) { - lastMessageFromSameUser = - (messages[i - 1].messageOtherId == null && - messages[i].messageOtherId == null) || - (messages[i - 1].messageOtherId != null && - messages[i].messageOtherId != null); - } - Message msg = messages[i]; - List reactions = []; - if (reactionsToMyMessages.containsKey(msg.messageId)) { - reactions = reactionsToMyMessages[msg.messageId]!; - } - if (msg.messageOtherId != null && - reactionsToOtherMessages - .containsKey(msg.messageOtherId!)) { - reactions = reactionsToOtherMessages[msg.messageOtherId!]!; - } - return ChatListEntry( - msg, - widget.userid, - lastMessageFromSameUser, - reactions, - ); - }, + if (user != null) + Expanded( + child: ListView.builder( + itemCount: messages.length, + reverse: true, + itemBuilder: (context, i) { + bool lastMessageFromSameUser = false; + if (i > 0) { + lastMessageFromSameUser = + (messages[i - 1].messageOtherId == null && + messages[i].messageOtherId == null) || + (messages[i - 1].messageOtherId != null && + messages[i].messageOtherId != null); + } + Message msg = messages[i]; + List reactions = []; + if (reactionsToMyMessages.containsKey(msg.messageId)) { + reactions = reactionsToMyMessages[msg.messageId]!; + } + if (msg.messageOtherId != null && + reactionsToOtherMessages + .containsKey(msg.messageOtherId!)) { + reactions = + reactionsToOtherMessages[msg.messageOtherId!]!; + } + return ChatListEntry( + msg, + user!, + lastMessageFromSameUser, + reactions, + ); + }, + ), ), - ), Padding( padding: const EdgeInsets.only( bottom: 30, left: 20, right: 20, top: 10), @@ -436,9 +440,7 @@ class _ChatItemDetailsViewState extends State { : IconButton( icon: FaIcon(FontAwesomeIcons.camera), onPressed: () { - context - .read() - .updateSendNextMediaTo(widget.userid); + globalSendNextMediaToUser = user; globalUpdateOfHomeViewPageIndex(0); Navigator.popUntil( context, (route) => route.isFirst); diff --git a/lib/src/views/chats/chat_list_view.dart b/lib/src/views/chats/chat_list_view.dart index 15d7e36..eafa807 100644 --- a/lib/src/views/chats/chat_list_view.dart +++ b/lib/src/views/chats/chat_list_view.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:convert'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/components/flame.dart'; import 'package:twonly/src/components/initialsavatar.dart'; @@ -13,8 +12,8 @@ import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/json_models/message.dart'; import 'package:twonly/src/providers/api/media.dart'; -import 'package:twonly/src/providers/send_next_media_to.dart'; import 'package:twonly/src/utils/misc.dart'; +import 'package:twonly/src/views/camera_to_share/share_image_view.dart'; import 'package:twonly/src/views/chats/chat_item_details_view.dart'; import 'package:twonly/src/views/chats/media_viewer_view.dart'; import 'package:twonly/src/views/home_view.dart'; @@ -277,9 +276,7 @@ class _UserListItem extends State { leading: ContactAvatar(contact: widget.user), onTap: () { if (currentMessage == null) { - context - .read() - .updateSendNextMediaTo(widget.user.userId.toInt()); + globalSendNextMediaToUser = widget.user; globalUpdateOfHomeViewPageIndex(0); return; } @@ -301,7 +298,7 @@ class _UserListItem extends State { Navigator.push( context, MaterialPageRoute(builder: (context) { - return MediaViewerView(widget.user.userId); + return MediaViewerView(widget.user); }), ); default: diff --git a/lib/src/views/chats/media_viewer_view.dart b/lib/src/views/chats/media_viewer_view.dart index 1540d96..3bf1213 100644 --- a/lib/src/views/chats/media_viewer_view.dart +++ b/lib/src/views/chats/media_viewer_view.dart @@ -5,7 +5,6 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:lottie/lottie.dart'; import 'package:no_screenshot/no_screenshot.dart'; -import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/components/animate_icon.dart'; import 'package:twonly/src/components/media_view_sizing.dart'; @@ -14,17 +13,17 @@ import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/json_models/message.dart'; import 'package:twonly/src/providers/api/api.dart'; import 'package:twonly/src/providers/api/media.dart'; -import 'package:twonly/src/providers/send_next_media_to.dart'; import 'package:twonly/src/services/notification_service.dart'; import 'package:twonly/src/utils/misc.dart'; +import 'package:twonly/src/views/camera_to_share/share_image_view.dart'; import 'package:twonly/src/views/chats/chat_item_details_view.dart'; import 'package:twonly/src/views/home_view.dart'; final _noScreenshot = NoScreenshot.instance; class MediaViewerView extends StatefulWidget { - final int userId; - const MediaViewerView(this.userId, {super.key}); + final Contact contact; + const MediaViewerView(this.contact, {super.key}); @override State createState() => _MediaViewerViewState(); @@ -59,8 +58,8 @@ class _MediaViewerViewState extends State { } Future asyncLoadNextMedia(bool firstRun) async { - Stream> messages = - twonlyDatabase.messagesDao.watchMediaMessageNotOpened(widget.userId); + Stream> messages = twonlyDatabase.messagesDao + .watchMediaMessageNotOpened(widget.contact.userId); _subscription = messages.listen((messages) { for (Message msg in messages) { @@ -329,7 +328,7 @@ class _MediaViewerViewState extends State { child: GestureDetector( onTap: () { sendTextMessage( - widget.userId, + widget.contact.userId, TextMessageContent( text: emoji, responseToMessageId: @@ -400,7 +399,7 @@ class _MediaViewerViewState extends State { }); encryptAndSendMessage( null, - widget.userId, + widget.contact.userId, MessageJson( kind: MessageKind.storedMediaFile, messageId: allMediaFiles.first.messageId, @@ -477,7 +476,7 @@ class _MediaViewerViewState extends State { Navigator.push( context, MaterialPageRoute(builder: (context) { - return ChatItemDetailsView(widget.userId); + return ChatItemDetailsView(widget.contact.userId); }), ); }, @@ -491,9 +490,7 @@ class _MediaViewerViewState extends State { IconButton.outlined( icon: FaIcon(FontAwesomeIcons.camera), onPressed: () async { - context - .read() - .updateSendNextMediaTo(widget.userId.toInt()); + globalSendNextMediaToUser = widget.contact; globalUpdateOfHomeViewPageIndex(0); Navigator.popUntil(context, (route) => route.isFirst); }, diff --git a/lib/src/views/home_view.dart b/lib/src/views/home_view.dart index 0f872c7..1715778 100644 --- a/lib/src/views/home_view.dart +++ b/lib/src/views/home_view.dart @@ -1,9 +1,8 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:pie_menu/pie_menu.dart'; -import 'package:provider/provider.dart'; -import 'package:twonly/src/providers/send_next_media_to.dart'; import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/views/camera_to_share/share_image_view.dart'; import 'camera_to_share/camera_preview_view.dart'; import 'chats/chat_list_view.dart'; import 'package:flutter/material.dart'; @@ -29,7 +28,7 @@ class HomeViewState extends State { homeViewPageController = PageController(initialPage: widget.initialPage); globalUpdateOfHomeViewPageIndex = (index) { if (index == 1) { - context.read().updateSendNextMediaTo(null); + globalSendNextMediaToUser = null; } homeViewPageController.jumpToPage(index); setState(() { @@ -92,7 +91,7 @@ class HomeViewState extends State { controller: homeViewPageController, onPageChanged: (index) { if (index == 1) { - context.read().updateSendNextMediaTo(null); + globalSendNextMediaToUser = null; } activePageIdx = index; setState(() {}); @@ -121,7 +120,7 @@ class HomeViewState extends State { onTap: (int index) { activePageIdx = index; if (index == 1) { - context.read().updateSendNextMediaTo(null); + globalSendNextMediaToUser = null; } setState(() { homeViewPageController.animateToPage(