From 071c5c2a0d53b6fbd4eca81839c3e4184baafc54 Mon Sep 17 00:00:00 2001 From: otsmr Date: Tue, 28 Oct 2025 13:23:35 +0100 Subject: [PATCH] purge text messages fix multiple bugs --- lib/main.dart | 3 +- lib/src/database/daos/contacts.dao.dart | 13 ++++- lib/src/database/daos/messages.dao.dart | 56 ++++++++++++------- lib/src/database/tables/groups.table.dart | 2 +- lib/src/database/twonly.db.g.dart | 2 +- lib/src/localization/app_de.arb | 7 ++- lib/src/localization/app_en.arb | 7 ++- .../generated/app_localizations.dart | 30 ++++++++++ .../generated/app_localizations_de.dart | 15 +++++ .../generated/app_localizations_en.dart | 15 +++++ .../api/mediafiles/upload.service.dart | 14 +++-- .../mediafiles/mediafile.service.dart | 2 + lib/src/utils/misc.dart | 15 +++-- .../camera_preview_components/send_to.dart | 8 +-- .../views/camera/share_image_editor_view.dart | 7 ++- lib/src/views/chats/archived_chats.view.dart | 3 +- lib/src/views/chats/chat_list.view.dart | 2 +- .../chat_list_components/group_list_item.dart | 9 ++- .../last_message_time.dart | 20 ++++--- lib/src/views/chats/chat_messages.view.dart | 5 +- .../message_send_state_icon.dart | 10 ++++ lib/src/views/contact/contact.view.dart | 5 +- .../memories/memories_photo_slider.view.dart | 22 +++++++- .../views/settings/profile/profile.view.dart | 1 + .../views/settings/settings_main.view.dart | 3 +- 25 files changed, 207 insertions(+), 69 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 1004f5c..ec86621 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -57,13 +57,12 @@ void main() async { await initFileDownloader(); unawaited(MediaFileService.purgeTempFolder()); + await twonlyDB.messagesDao.purgeMessageTable(); // await twonlyDB.messagesDao.resetPendingDownloadState(); // await twonlyDB.messageRetransmissionDao.purgeOldRetransmissions(); // await twonlyDB.signalDao.purgeOutDatedPreKeys(); - // Purge media files in the background - // unawaited(purgeReceivedMediaFiles()); // unawaited(purgeSendMediaFiles()); // unawaited(performTwonlySafeBackup()); diff --git a/lib/src/database/daos/contacts.dao.dart b/lib/src/database/daos/contacts.dao.dart index 6792ad0..07a730e 100644 --- a/lib/src/database/daos/contacts.dao.dart +++ b/lib/src/database/daos/contacts.dao.dart @@ -121,7 +121,7 @@ class ContactsDao extends DatabaseAccessor with _$ContactsDaoMixin { } } -String getContactDisplayName(Contact user) { +String getContactDisplayName(Contact user, {int? maxLength}) { var name = user.username; if (user.nickName != null && user.nickName != '') { name = user.nickName!; @@ -131,12 +131,19 @@ String getContactDisplayName(Contact user) { if (user.accountDeleted) { name = applyStrikethrough(name); } - if (name.length > 27) { - return '${name.substring(0, 27 - 3)}...'; + if (maxLength != null) { + name = substringBy(name, maxLength); } return name; } +String substringBy(String string, int maxLength) { + if (string.length > maxLength) { + return '${string.substring(0, maxLength - 3)}...'; + } + return string; +} + String getContactDisplayNameOld(old.Contact user) { var name = user.username; if (user.nickName != null && user.nickName != '') { diff --git a/lib/src/database/daos/messages.dao.dart b/lib/src/database/daos/messages.dao.dart index 02aac49..bc6a26e 100644 --- a/lib/src/database/daos/messages.dao.dart +++ b/lib/src/database/daos/messages.dao.dart @@ -68,16 +68,20 @@ class MessagesDao extends DatabaseAccessor with _$MessagesDaoMixin { } Stream> watchByGroupId(String groupId) { - return ((select(messages)..where((t) => t.groupId.equals(groupId))) + return ((select(messages) + ..where( + (t) => + t.groupId.equals(groupId) & + (t.isDeletedFromSender.equals(true) | + ((t.type.equals(MessageType.text.name) & + t.content.isNotNull()) | + (t.type.equals(MessageType.media.name) & + t.mediaId.isNotNull()))), + )) ..orderBy([(t) => OrderingTerm.asc(t.createdAt)])) .watch(); } - // Stream> watchMembersByGroupId(String groupId) { - // return (select(groupMembers)..where((t) => t.groupId.equals(groupId))) - // .watch(); - // } - Stream> watchMembersByGroupId(String groupId) { final query = (select(groupMembers).join([ leftOuterJoin( @@ -101,21 +105,31 @@ class MessagesDao extends DatabaseAccessor with _$MessagesDaoMixin { .watchSingleOrNull(); } - // Future removeOldMessages() { - // return (update(messages) - // ..where( - // (t) => - // (t.openedAt.isSmallerThanValue( - // DateTime.now().subtract(const Duration(days: 1)), - // ) | - // (t.sendAt.isSmallerThanValue( - // DateTime.now().subtract(const Duration(days: 3)), - // ) & - // t.errorWhileSending.equals(true))) & - // t.kind.equals(MessageKind.textMessage.name), - // )) - // .write(const MessagesCompanion(contentJson: Value(null))); - // } + Future purgeMessageTable() async { + final allGroups = await select(groups).get(); + + for (final group in allGroups) { + final deletionTime = DateTime.now().subtract( + Duration( + milliseconds: group.deleteMessagesAfterMilliseconds, + ), + ); + final affected = await (delete(messages) + ..where( + (m) => + m.groupId.equals(group.groupId) & + // m.messageId.equals(lastMessage.messageId).not() & + (m.mediaStored.equals(true) & + m.isDeletedFromSender.equals(true) | + m.mediaStored.equals(false)) & + (m.openedAt.isSmallerThanValue(deletionTime) | + (m.isDeletedFromSender.equals(true) & + m.createdAt.isSmallerThanValue(deletionTime))), + )) + .go(); + Log.info('Deleted $affected messages.'); + } + } // Future> getAllMessagesPendingDownloading() { // return (select(messages) diff --git a/lib/src/database/tables/groups.table.dart b/lib/src/database/tables/groups.table.dart index bd1ad71..9bbac87 100644 --- a/lib/src/database/tables/groups.table.dart +++ b/lib/src/database/tables/groups.table.dart @@ -18,7 +18,7 @@ class Groups extends Table { boolean().withDefault(const Constant(false))(); IntColumn get deleteMessagesAfterMilliseconds => - integer().withDefault(const Constant(1000 * 60 * 24))(); + integer().withDefault(const Constant(1000 * 60 * 60 * 24))(); DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); diff --git a/lib/src/database/twonly.db.g.dart b/lib/src/database/twonly.db.g.dart index 95b15a5..9c63e40 100644 --- a/lib/src/database/twonly.db.g.dart +++ b/lib/src/database/twonly.db.g.dart @@ -734,7 +734,7 @@ class $GroupsTable extends Groups with TableInfo<$GroupsTable, Group> { 'delete_messages_after_milliseconds', aliasedName, false, type: DriftSqlType.int, requiredDuringInsert: false, - defaultValue: const Constant(1000 * 60 * 24)); + defaultValue: const Constant(1000 * 60 * 60 * 24)); static const VerificationMeta _createdAtMeta = const VerificationMeta('createdAt'); @override diff --git a/lib/src/localization/app_de.arb b/lib/src/localization/app_de.arb index 375158c..9b1026f 100644 --- a/lib/src/localization/app_de.arb +++ b/lib/src/localization/app_de.arb @@ -352,5 +352,10 @@ "received": "Empfangen", "opened": "Geöffnet", "waitingForInternet": "Warten auf Internet", - "editHistory": "Bearbeitungshistorie" + "editHistory": "Bearbeitungshistorie", + "archivedChats": "Archivierte Chats", + "durationShortSecond": "Sek.", + "durationShortMinute": "Min.", + "durationShortHour": "Std", + "durationShortDays": "Tagen" } \ No newline at end of file diff --git a/lib/src/localization/app_en.arb b/lib/src/localization/app_en.arb index d169e57..795dfb6 100644 --- a/lib/src/localization/app_en.arb +++ b/lib/src/localization/app_en.arb @@ -508,5 +508,10 @@ "received": "Received", "opened": "Opened", "waitingForInternet": "Waiting for internet", - "editHistory": "Edit history" + "editHistory": "Edit history", + "archivedChats": "Archived chats", + "durationShortSecond": "Sec.", + "durationShortMinute": "Min.", + "durationShortHour": "Hrs.", + "durationShortDays": "Days" } \ No newline at end of file diff --git a/lib/src/localization/generated/app_localizations.dart b/lib/src/localization/generated/app_localizations.dart index d2f423d..90fd5c2 100644 --- a/lib/src/localization/generated/app_localizations.dart +++ b/lib/src/localization/generated/app_localizations.dart @@ -2155,6 +2155,36 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Edit history'** String get editHistory; + + /// No description provided for @archivedChats. + /// + /// In en, this message translates to: + /// **'Archived chats'** + String get archivedChats; + + /// No description provided for @durationShortSecond. + /// + /// In en, this message translates to: + /// **'Sec.'** + String get durationShortSecond; + + /// No description provided for @durationShortMinute. + /// + /// In en, this message translates to: + /// **'Min.'** + String get durationShortMinute; + + /// No description provided for @durationShortHour. + /// + /// In en, this message translates to: + /// **'Hrs.'** + String get durationShortHour; + + /// No description provided for @durationShortDays. + /// + /// In en, this message translates to: + /// **'Days'** + String get durationShortDays; } class _AppLocalizationsDelegate diff --git a/lib/src/localization/generated/app_localizations_de.dart b/lib/src/localization/generated/app_localizations_de.dart index b4ed1fe..e41102a 100644 --- a/lib/src/localization/generated/app_localizations_de.dart +++ b/lib/src/localization/generated/app_localizations_de.dart @@ -1143,4 +1143,19 @@ class AppLocalizationsDe extends AppLocalizations { @override String get editHistory => 'Bearbeitungshistorie'; + + @override + String get archivedChats => 'Archivierte Chats'; + + @override + String get durationShortSecond => 'Sek.'; + + @override + String get durationShortMinute => 'Min.'; + + @override + String get durationShortHour => 'Std'; + + @override + String get durationShortDays => 'Tagen'; } diff --git a/lib/src/localization/generated/app_localizations_en.dart b/lib/src/localization/generated/app_localizations_en.dart index 3337bed..71ffab8 100644 --- a/lib/src/localization/generated/app_localizations_en.dart +++ b/lib/src/localization/generated/app_localizations_en.dart @@ -1136,4 +1136,19 @@ class AppLocalizationsEn extends AppLocalizations { @override String get editHistory => 'Edit history'; + + @override + String get archivedChats => 'Archived chats'; + + @override + String get durationShortSecond => 'Sec.'; + + @override + String get durationShortMinute => 'Min.'; + + @override + String get durationShortHour => 'Hrs.'; + + @override + String get durationShortDays => 'Days'; } diff --git a/lib/src/services/api/mediafiles/upload.service.dart b/lib/src/services/api/mediafiles/upload.service.dart index 5e97149..55a7ba0 100644 --- a/lib/src/services/api/mediafiles/upload.service.dart +++ b/lib/src/services/api/mediafiles/upload.service.dart @@ -71,7 +71,8 @@ Future insertMediaFileInMessagesTable( } Future startBackgroundMediaUpload(MediaFileService mediaService) async { - if (mediaService.mediaFile.uploadState == UploadState.initialized) { + if (mediaService.mediaFile.uploadState == UploadState.initialized || + mediaService.mediaFile.uploadState == UploadState.preprocessing) { await mediaService.setUploadState(UploadState.preprocessing); if (!mediaService.tempPath.existsSync()) { await mediaService.compressMedia(); @@ -84,7 +85,9 @@ Future startBackgroundMediaUpload(MediaFileService mediaService) async { if (!mediaService.uploadRequestPath.existsSync()) { await _createUploadRequest(mediaService); } - await mediaService.setUploadState(UploadState.uploading); + if (mediaService.uploadRequestPath.existsSync()) { + await mediaService.setUploadState(UploadState.uploading); + } } if (mediaService.mediaFile.uploadState == UploadState.uploading) { @@ -109,8 +112,6 @@ Future _encryptMediaFiles(MediaFileService mediaService) async { mediaService.encryptedPath .writeAsBytesSync(Uint8List.fromList(secretBox.cipherText)); - - await mediaService.setUploadState(UploadState.uploading); } Future _createUploadRequest(MediaFileService media) async { @@ -121,6 +122,11 @@ Future _createUploadRequest(MediaFileService media) async { final messages = await twonlyDB.messagesDao.getMessagesByMediaId(media.mediaFile.mediaId); + if (messages.isEmpty) { + // There where no user selected who should receive the image, so waiting with this step... + return; + } + for (final message in messages) { final groupMembers = await twonlyDB.groupsDao.getGroupMembers(message.groupId); diff --git a/lib/src/services/mediafiles/mediafile.service.dart b/lib/src/services/mediafiles/mediafile.service.dart index e0fcb7e..e2852d6 100644 --- a/lib/src/services/mediafiles/mediafile.service.dart +++ b/lib/src/services/mediafiles/mediafile.service.dart @@ -53,6 +53,8 @@ class MediaFileService { 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 (message.senderId == null) { // Media was send by me diff --git a/lib/src/utils/misc.dart b/lib/src/utils/misc.dart index b488fdb..4517571 100644 --- a/lib/src/utils/misc.dart +++ b/lib/src/utils/misc.dart @@ -89,27 +89,26 @@ String errorCodeToText(BuildContext context, ErrorCode code) { case ErrorCode.PlanUpgradeNotYearly: return context.lang.errorPlanUpgradeNotYearly; } - return code.toString(); // Fallback for unrecognized keys + return code.toString(); } -String formatDuration(int seconds) { +String formatDuration(BuildContext context, int seconds) { if (seconds < 60) { - return '$seconds Sec.'; + return '$seconds ${context.lang.durationShortSecond}'; } else if (seconds < 3600) { final minutes = seconds ~/ 60; - return '$minutes Min.'; + return '$minutes ${context.lang.durationShortMinute}'; } else if (seconds < 86400) { final hours = seconds ~/ 3600; - return '$hours Hrs.'; // Assuming "Stu." is for hours + return '$hours ${context.lang.durationShortHour}'; } else { final days = seconds ~/ 86400; - return '$days Days'; + return '$days ${context.lang.durationShortDays}'; } } InputDecoration getInputDecoration(BuildContext context, String hintText) { - final primaryColor = - Theme.of(context).colorScheme.primary; // Get the primary color + final primaryColor = Theme.of(context).colorScheme.primary; return InputDecoration( hintText: hintText, focusedBorder: OutlineInputBorder( diff --git a/lib/src/views/camera/camera_preview_components/send_to.dart b/lib/src/views/camera/camera_preview_components/send_to.dart index b061a9b..76e7a7c 100644 --- a/lib/src/views/camera/camera_preview_components/send_to.dart +++ b/lib/src/views/camera/camera_preview_components/send_to.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/utils/misc.dart'; class SendToWidget extends StatelessWidget { @@ -40,7 +41,7 @@ class SendToWidget extends StatelessWidget { style: textStyle, ), Text( - sendTo, + substringBy(sendTo, 20), textAlign: TextAlign.center, style: boldTextStyle, // Use the bold text style here ), @@ -48,9 +49,4 @@ class SendToWidget extends StatelessWidget { ), ); } - - String getContactDisplayName(String contact) { - // Replace this with your actual logic to get the contact display name - return contact; // Placeholder implementation - } } diff --git a/lib/src/views/camera/share_image_editor_view.dart b/lib/src/views/camera/share_image_editor_view.dart index 6cf4910..d84708d 100644 --- a/lib/src/views/camera/share_image_editor_view.dart +++ b/lib/src/views/camera/share_image_editor_view.dart @@ -7,6 +7,7 @@ import 'package:flutter/services.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:hashlib/random.dart'; import 'package:screenshot/screenshot.dart'; +import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/tables/mediafiles.table.dart'; import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/services/api/mediafiles/upload.service.dart'; @@ -75,8 +76,8 @@ class _ShareImageEditorView extends State { if (widget.imageBytesFuture != null) { loadImage(widget.imageBytesFuture!); } else { - if (widget.mediaFileService.storedPath.existsSync()) { - loadImage(widget.mediaFileService.storedPath.readAsBytes()); + if (widget.mediaFileService.tempPath.existsSync()) { + loadImage(widget.mediaFileService.tempPath.readAsBytes()); } } } @@ -482,7 +483,7 @@ class _ShareImageEditorView extends State { label: Text( (widget.sendToGroup == null) ? context.lang.shareImagedEditorShareWith - : widget.sendToGroup!.groupName, + : substringBy(widget.sendToGroup!.groupName, 15), style: const TextStyle(fontSize: 17), ), ), diff --git a/lib/src/views/chats/archived_chats.view.dart b/lib/src/views/chats/archived_chats.view.dart index a785c0b..0f0847a 100644 --- a/lib/src/views/chats/archived_chats.view.dart +++ b/lib/src/views/chats/archived_chats.view.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/database/twonly.db.dart'; +import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/views/chats/chat_list_components/group_list_item.dart'; class ArchivedChatsView extends StatefulWidget { @@ -40,7 +41,7 @@ class _ArchivedChatsViewState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Archivierte Chats'), + title: Text(context.lang.archivedChats), ), body: ListView( children: _groupsArchived.map((group) { diff --git a/lib/src/views/chats/chat_list.view.dart b/lib/src/views/chats/chat_list.view.dart index ca1acca..575300d 100644 --- a/lib/src/views/chats/chat_list.view.dart +++ b/lib/src/views/chats/chat_list.view.dart @@ -252,7 +252,7 @@ class _ChatListViewState extends State { if (_groupsArchived.isEmpty) return Container(); return ListTile( title: Text( - 'Archivierte Chats (${_groupsArchived.length})', + '${context.lang.archivedChats} (${_groupsArchived.length})', textAlign: TextAlign.center, style: const TextStyle(fontSize: 13), ), diff --git a/lib/src/views/chats/chat_list_components/group_list_item.dart b/lib/src/views/chats/chat_list_components/group_list_item.dart index 597f622..729ba02 100644 --- a/lib/src/views/chats/chat_list_components/group_list_item.dart +++ b/lib/src/views/chats/chat_list_components/group_list_item.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:mutex/mutex.dart'; import 'package:twonly/globals.dart'; +import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/tables/mediafiles.table.dart'; import 'package:twonly/src/database/tables/messages.table.dart'; import 'package:twonly/src/database/twonly.db.dart'; @@ -208,10 +209,12 @@ class _UserListItem extends State { group: widget.group, child: ListTile( title: Text( - widget.group.groupName, + substringBy(widget.group.groupName, 30), ), subtitle: (_currentMessage == null) - ? Text(context.lang.chatsTapToSend) + ? (widget.group.totalMediaCounter == 0) + ? Text(context.lang.chatsTapToSend) + : LastMessageTime(dateTime: widget.group.lastMessageExchange) : Row( children: [ MessageSendStateIcon( @@ -222,7 +225,7 @@ class _UserListItem extends State { const Text('•'), const SizedBox(width: 5), if (_currentMessage != null) - LastMessageTime(message: _currentMessage!), + LastMessageTime(message: _currentMessage), FlameCounterWidget( groupId: widget.group.groupId, prefix: true, diff --git a/lib/src/views/chats/chat_list_components/last_message_time.dart b/lib/src/views/chats/chat_list_components/last_message_time.dart index b81981a..6b82d30 100644 --- a/lib/src/views/chats/chat_list_components/last_message_time.dart +++ b/lib/src/views/chats/chat_list_components/last_message_time.dart @@ -6,9 +6,10 @@ import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/utils/misc.dart'; class LastMessageTime extends StatefulWidget { - const LastMessageTime({required this.message, super.key}); + const LastMessageTime({this.message, this.dateTime, super.key}); - final Message message; + final Message? message; + final DateTime? dateTime; @override State createState() => _LastMessageTimeState(); @@ -24,12 +25,17 @@ class _LastMessageTimeState extends State { // Change the color every 200 milliseconds updateTime = Timer.periodic(const Duration(milliseconds: 500), (timer) async { - final lastAction = await twonlyDB.messagesDao - .getLastMessageAction(widget.message.messageId); - setState(() { + if (widget.message != null) { + final lastAction = await twonlyDB.messagesDao + .getLastMessageAction(widget.message!.messageId); lastMessageInSeconds = DateTime.now() - .difference(lastAction?.actionAt ?? widget.message.createdAt) + .difference(lastAction?.actionAt ?? widget.message!.createdAt) .inSeconds; + } else if (widget.dateTime != null) { + lastMessageInSeconds = + DateTime.now().difference(widget.dateTime!).inSeconds; + } + setState(() { if (lastMessageInSeconds < 0) { lastMessageInSeconds = 0; } @@ -46,7 +52,7 @@ class _LastMessageTimeState extends State { @override Widget build(BuildContext context) { return Text( - formatDuration(lastMessageInSeconds), + formatDuration(context, lastMessageInSeconds), style: const TextStyle(fontSize: 12), ); } diff --git a/lib/src/views/chats/chat_messages.view.dart b/lib/src/views/chats/chat_messages.view.dart index 5ed959f..e7191dd 100644 --- a/lib/src/views/chats/chat_messages.view.dart +++ b/lib/src/views/chats/chat_messages.view.dart @@ -5,6 +5,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:mutex/mutex.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; import 'package:twonly/globals.dart'; +import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/database/tables/messages.table.dart'; import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/model/memory_item.model.dart'; @@ -241,7 +242,9 @@ class _ChatMessagesViewState extends State { color: Colors.transparent, child: Row( children: [ - Text(group.groupName), + Text( + substringBy(widget.group.groupName, 20), + ), const SizedBox(width: 10), VerifiedShield(key: verifyShieldKey, group: group), const SizedBox(width: 10), diff --git a/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart b/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart index 9e50231..cb378a9 100644 --- a/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart +++ b/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart @@ -144,6 +144,16 @@ class _MessageSendStateIconState extends State { case MessageSendState.sending: icon = getLoaderIcon(color); text = context.lang.messageSendState_Sending; + + if (mediaFile != null) { + if (mediaFile.uploadState == UploadState.uploadLimitReached) { + text = 'Upload Limit erreicht'; + } + if (mediaFile.uploadState == UploadState.preprocessing) { + text = 'Wird verarbeitet'; + } + } + hasLoader = true; case MessageSendState.receiving: icon = getLoaderIcon(color); diff --git a/lib/src/views/contact/contact.view.dart b/lib/src/views/contact/contact.view.dart index 2df4ce8..b615549 100644 --- a/lib/src/views/contact/contact.view.dart +++ b/lib/src/views/contact/contact.view.dart @@ -24,7 +24,8 @@ class _ContactViewState extends State { Future handleUserRemoveRequest(Contact contact) async { final remove = await showAlertDialog( context, - context.lang.contactRemoveTitle(getContactDisplayName(contact)), + context.lang + .contactRemoveTitle(getContactDisplayName(contact, maxLength: 20)), context.lang.contactRemoveBody, ); if (remove) { @@ -124,7 +125,7 @@ class _ContactViewState extends State { child: VerifiedShield(key: GlobalKey(), contact: contact), ), Text( - getContactDisplayName(contact), + getContactDisplayName(contact, maxLength: 20), style: const TextStyle(fontSize: 20), ), // if (flameCounter > 0) diff --git a/lib/src/views/memories/memories_photo_slider.view.dart b/lib/src/views/memories/memories_photo_slider.view.dart index 55e298b..99b1aa2 100644 --- a/lib/src/views/memories/memories_photo_slider.view.dart +++ b/lib/src/views/memories/memories_photo_slider.view.dart @@ -5,6 +5,8 @@ import 'package:photo_view/photo_view_gallery.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/database/tables/mediafiles.table.dart'; import 'package:twonly/src/model/memory_item.model.dart'; +import 'package:twonly/src/services/api/mediafiles/upload.service.dart'; +import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/views/camera/share_image_editor_view.dart'; import 'package:twonly/src/views/components/alert_dialog.dart'; @@ -117,12 +119,28 @@ class _MemoriesPhotoSliderViewState extends State { FilledButton.icon( icon: const FaIcon(FontAwesomeIcons.solidPaperPlane), onPressed: () async { + final orgMediaService = + widget.galleryItems[currentIndex].mediaService; + + final newMediaService = await initializeMediaUpload( + orgMediaService.mediaFile.type, + gUser.defaultShowTime, + ); + if (newMediaService == null) { + Log.error('Could not create new mediaFIle'); + return; + } + + orgMediaService.storedPath + .copySync(newMediaService.tempPath.path); + + if (!context.mounted) return; + await Navigator.push( context, MaterialPageRoute( builder: (context) => ShareImageEditorView( - mediaFileService: widget - .galleryItems[currentIndex].mediaService, + mediaFileService: newMediaService, sharedFromGallery: true, ), ), diff --git a/lib/src/views/settings/profile/profile.view.dart b/lib/src/views/settings/profile/profile.view.dart index 104bde0..8659f75 100644 --- a/lib/src/views/settings/profile/profile.view.dart +++ b/lib/src/views/settings/profile/profile.view.dart @@ -114,6 +114,7 @@ Future showDisplayNameChangeDialog( content: TextField( controller: controller, autofocus: true, + maxLength: 30, decoration: InputDecoration( hintText: context.lang.settingsProfileEditDisplayNameNew, ), diff --git a/lib/src/views/settings/settings_main.view.dart b/lib/src/views/settings/settings_main.view.dart index b58efcd..6c818b5 100644 --- a/lib/src/views/settings/settings_main.view.dart +++ b/lib/src/views/settings/settings_main.view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:twonly/globals.dart'; +import 'package:twonly/src/database/daos/contacts.dao.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/views/components/avatar_icon.component.dart'; import 'package:twonly/src/views/components/better_list_title.dart'; @@ -63,7 +64,7 @@ class _SettingsMainViewState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - gUser.displayName, + substringBy(gUser.displayName, 27), style: const TextStyle(fontSize: 20), textAlign: TextAlign.left, ),