clean code and fix tap issue

This commit is contained in:
otsmr 2025-05-29 11:39:54 +02:00
parent 96f4b5a136
commit f362695f6e
13 changed files with 519 additions and 320 deletions

View file

@ -15,7 +15,7 @@ import 'package:twonly/src/database/tables/messages_table.dart';
import 'package:twonly/src/providers/connection_provider.dart'; import 'package:twonly/src/providers/connection_provider.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/views/camera/camera_send_to_view.dart'; import 'package:twonly/src/views/camera/camera_send_to_view.dart';
import 'package:twonly/src/views/chats/chat_item_details_view.dart'; import 'package:twonly/src/views/chats/chat_messages_view.dart';
import 'package:twonly/src/views/chats/media_viewer_view.dart'; import 'package:twonly/src/views/chats/media_viewer_view.dart';
import 'package:twonly/src/views/chats/start_new_chat.dart'; import 'package:twonly/src/views/chats/start_new_chat.dart';
import 'package:twonly/src/views/settings/settings_main_view.dart'; import 'package:twonly/src/views/settings/settings_main_view.dart';
@ -383,7 +383,7 @@ class _UserListItem extends State<UserListItem> {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return ChatItemDetailsView(widget.user); return ChatMessagesView(widget.user);
}), }),
); );
}, },

View file

@ -0,0 +1,100 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_media_entry.dart';
import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_reaction_row.dart';
import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_entry.dart';
import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_response_columns.dart';
import 'package:twonly/src/views/chats/chat_messages_components/sliding_response.dart';
import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/model/json/message.dart';
class ChatListEntry extends StatefulWidget {
const ChatListEntry(
this.message,
this.contact,
this.lastMessageFromSameUser,
this.textReactions,
this.otherReactions, {
super.key,
required this.onResponseTriggered,
});
final Message message;
final Contact contact;
final bool lastMessageFromSameUser;
final List<Message> textReactions;
final List<Message> otherReactions;
final Function(Message) onResponseTriggered;
@override
State<ChatListEntry> createState() => _ChatListEntryState();
}
class _ChatListEntryState extends State<ChatListEntry> {
MessageContent? content;
String? textMessage;
@override
void initState() {
super.initState();
final msgContent = MessageContent.fromJson(
widget.message.kind, jsonDecode(widget.message.contentJson!));
if (msgContent is TextMessageContent) {
textMessage = msgContent.text;
}
content = msgContent;
}
@override
Widget build(BuildContext context) {
if (content == null) return Container();
bool right = widget.message.messageOtherId == null;
return Align(
alignment: right ? Alignment.centerRight : Alignment.centerLeft,
child: Padding(
padding: widget.lastMessageFromSameUser
? EdgeInsets.only(top: 5, bottom: 0, right: 10, left: 10)
: EdgeInsets.only(top: 5, bottom: 20, right: 10, left: 10),
child: Column(
mainAxisAlignment:
right ? MainAxisAlignment.end : MainAxisAlignment.start,
crossAxisAlignment:
right ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children: [
SlidingResponse(
child: Stack(
alignment: right ? Alignment.centerRight : Alignment.centerLeft,
children: [
(textMessage != null)
? ChatTextEntry(
message: widget.message, text: textMessage!)
: ChatMediaEntry(
message: widget.message,
contact: widget.contact,
content: content!,
),
Positioned(
bottom: 5,
left: 5,
right: 5,
child: ReactionRow(
otherReactions: widget.otherReactions,
message: widget.message,
),
),
],
),
onResponseTriggered: () {
widget.onResponseTriggered(widget.message);
},
),
ChatTextResponseColumns(
textReactions: widget.textReactions,
right: right,
)
],
),
),
);
}
}

View file

@ -0,0 +1,100 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_media_entry.dart';
import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_reaction_row.dart';
import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_entry.dart';
import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_response_columns.dart';
import 'package:twonly/src/views/chats/chat_messages_components/sliding_response.dart';
import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/model/json/message.dart';
class ChatListEntry extends StatefulWidget {
const ChatListEntry(
this.message,
this.contact,
this.lastMessageFromSameUser,
this.textReactions,
this.otherReactions, {
super.key,
required this.onResponseTriggered,
});
final Message message;
final Contact contact;
final bool lastMessageFromSameUser;
final List<Message> textReactions;
final List<Message> otherReactions;
final Function(Message) onResponseTriggered;
@override
State<ChatListEntry> createState() => _ChatListEntryState();
}
class _ChatListEntryState extends State<ChatListEntry> {
MessageContent? content;
String? textMessage;
@override
void initState() {
super.initState();
final msgContent = MessageContent.fromJson(
widget.message.kind, jsonDecode(widget.message.contentJson!));
if (msgContent is TextMessageContent) {
textMessage = msgContent.text;
}
content = msgContent;
}
@override
Widget build(BuildContext context) {
if (content == null) return Container();
bool right = widget.message.messageOtherId == null;
return Align(
alignment: right ? Alignment.centerRight : Alignment.centerLeft,
child: Padding(
padding: widget.lastMessageFromSameUser
? EdgeInsets.only(top: 5, bottom: 0, right: 10, left: 10)
: EdgeInsets.only(top: 5, bottom: 20, right: 10, left: 10),
child: Column(
mainAxisAlignment:
right ? MainAxisAlignment.end : MainAxisAlignment.start,
crossAxisAlignment:
right ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children: [
SlidingResponse(
child: Stack(
alignment: right ? Alignment.centerRight : Alignment.centerLeft,
children: [
(textMessage != null)
? ChatTextEntry(
message: widget.message, text: textMessage!)
: ChatMediaEntry(
message: widget.message,
contact: widget.contact,
content: content!,
),
Positioned(
bottom: 5,
left: 5,
right: 5,
child: ReactionRow(
otherReactions: widget.otherReactions,
message: widget.message,
),
),
],
),
onResponseTriggered: () {
widget.onResponseTriggered(widget.message);
},
),
ChatTextResponseColumns(
textReactions: widget.textReactions,
right: right,
)
],
),
),
);
}
}

View file

@ -0,0 +1,95 @@
import 'package:drift/drift.dart' show Value;
import 'package:flutter/material.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/src/views/chats/chat_messages_components/in_chat_media_viewer.dart';
import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/database/tables/messages_table.dart';
import 'package:twonly/src/model/json/message.dart';
import 'package:twonly/src/providers/api/api.dart';
import 'package:twonly/src/providers/api/media_received.dart' as received;
import 'package:twonly/src/services/notification_service.dart';
import 'package:twonly/src/views/chats/media_viewer_view.dart';
class ChatMediaEntry extends StatelessWidget {
const ChatMediaEntry({
super.key,
required this.message,
required this.contact,
required this.content,
});
final Message message;
final Contact contact;
final MessageContent content;
@override
Widget build(BuildContext context) {
Color color = getMessageColorFromType(
content,
context,
);
return GestureDetector(
onDoubleTap: () async {
if (message.openedAt == null && message.messageOtherId != null ||
message.mediaStored) {
return;
}
if (await received.existsMediaFile(message.messageId, "png")) {
await encryptAndSendMessageAsync(
null,
contact.userId,
MessageJson(
kind: MessageKind.reopenedMedia,
messageId: message.messageId,
content: ReopenedMediaFileContent(
messageId: message.messageOtherId!,
),
timestamp: DateTime.now(),
),
pushKind: PushKind.reopenedMedia,
);
await twonlyDatabase.messagesDao.updateMessageByMessageId(
message.messageId,
MessagesCompanion(openedAt: Value(null)),
);
}
},
onTap: () {
if (message.kind == MessageKind.media) {
if (message.downloadState == DownloadState.downloaded &&
message.openedAt == null) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return MediaViewerView(contact, initialMessage: message);
}),
);
} else if (message.downloadState == DownloadState.pending) {
received.startDownloadMedia(message, true);
}
}
},
child: Container(
width: 150,
decoration: BoxDecoration(
border: Border.all(
color: color,
width: 1.0,
),
borderRadius: BorderRadius.circular(12.0),
),
child: Align(
alignment: Alignment.centerRight,
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: InChatMediaViewer(
message: message,
contact: contact,
),
),
),
),
);
}
}

View file

@ -0,0 +1,82 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:twonly/src/views/components/animate_icon.dart';
import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/model/json/message.dart';
class ReactionRow extends StatefulWidget {
const ReactionRow(
{super.key, required this.otherReactions, required this.message});
final List<Message> otherReactions;
final Message message;
@override
State<ReactionRow> createState() => _ReactionRowState();
}
class _ReactionRowState extends State<ReactionRow> {
@override
Widget build(BuildContext context) {
List<Widget> children = [];
bool hasOneTextReaction = false;
bool hasOneReopened = false;
for (final reaction in widget.otherReactions) {
MessageContent? content = MessageContent.fromJson(
reaction.kind, jsonDecode(reaction.contentJson!));
if (content is ReopenedMediaFileContent) {
if (hasOneReopened) continue;
hasOneReopened = true;
children.add(
Expanded(
child: Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: EdgeInsets.only(right: 3),
child: FaIcon(
FontAwesomeIcons.repeat,
size: 12,
color: Colors.white,
),
),
),
),
);
}
// only show one reaction
if (hasOneTextReaction) continue;
if (content is TextMessageContent) {
hasOneTextReaction = true;
if (!isEmoji(content.text)) continue;
late Widget child;
if (EmojiAnimation.animatedIcons.containsKey(content.text)) {
child = SizedBox(
height: 18,
child: EmojiAnimation(emoji: content.text),
);
} else {
child = Text(content.text, style: TextStyle(fontSize: 14));
}
children.insert(
0,
Padding(
padding: EdgeInsets.only(left: 3),
child: child,
),
);
}
}
if (children.isEmpty) return Container();
return Row(
mainAxisAlignment: widget.message.messageOtherId == null
? MainAxisAlignment.start
: MainAxisAlignment.end,
children: children,
);
}
}

View file

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
import 'package:twonly/src/views/chats/chat_messages_view.dart';
import 'package:twonly/src/views/components/animate_icon.dart';
import 'package:twonly/src/views/components/better_text.dart';
import 'package:twonly/src/database/twonly_database.dart';
class ChatTextEntry extends StatelessWidget {
const ChatTextEntry({super.key, required this.message, required this.text});
final String text;
final Message message;
@override
Widget build(BuildContext context) {
if (EmojiAnimation.supported(text)) {
return Container(
constraints: BoxConstraints(
maxWidth: 100,
),
padding: EdgeInsets.symmetric(
vertical: 4,
horizontal: 10,
),
child: EmojiAnimation(emoji: text),
);
}
return Container(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.8,
),
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 10),
decoration: BoxDecoration(
color: getMessageColor(message),
borderRadius: BorderRadius.circular(12.0),
),
child: BetterText(text: text),
);
}
}

View file

@ -0,0 +1,79 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:twonly/src/views/chats/chat_messages_view.dart';
import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/model/json/message.dart';
class ChatTextResponseColumns extends StatelessWidget {
const ChatTextResponseColumns({
super.key,
required this.textReactions,
required this.right,
});
final List<Message> textReactions;
final bool right;
@override
Widget build(BuildContext context) {
List<Widget> children = [];
for (final reaction in textReactions) {
MessageContent? content = MessageContent.fromJson(
reaction.kind, jsonDecode(reaction.contentJson!));
if (content is TextMessageContent) {
var entries = [
FaIcon(
FontAwesomeIcons.reply,
size: 10,
),
SizedBox(width: 5),
Container(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.5,
),
child: Text(
content.text,
style: TextStyle(fontSize: 14),
textAlign: right ? TextAlign.left : TextAlign.right,
)),
];
if (!right) {
entries = entries.reversed.toList();
}
Color color = getMessageColor(reaction);
children.insert(
0,
Container(
padding: EdgeInsets.only(top: 5, bottom: 0, right: 10, left: 10),
child: Container(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.8,
),
padding: EdgeInsets.symmetric(vertical: 1, horizontal: 10),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(12.0),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: entries,
),
),
),
);
}
}
if (children.isEmpty) return Container();
return Column(
crossAxisAlignment:
right ? CrossAxisAlignment.start : CrossAxisAlignment.end,
children: children,
);
}
}

View file

@ -209,8 +209,6 @@ class _InChatMediaViewerState extends State<InChatMediaViewer> {
} }
Future onTap() async { Future onTap() async {
if (image == null && videoController == null) return;
if (widget.isInFullscreen) return;
bool? removed = await Navigator.push( bool? removed = await Navigator.push(
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
@ -231,8 +229,20 @@ class _InChatMediaViewerState extends State<InChatMediaViewer> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (image == null && video == null) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: MessageSendStateIcon(
[widget.message],
mainAxisAlignment: MainAxisAlignment.center,
),
);
}
return GestureDetector( return GestureDetector(
onTap: onTap, onTap:
((image == null && videoController == null) || widget.isInFullscreen)
? null
: onTap,
child: Stack( child: Stack(
children: [ children: [
if (image != null) Image.file(image!), if (image != null) Image.file(image!),
@ -243,14 +253,6 @@ class _InChatMediaViewerState extends State<InChatMediaViewer> {
child: VideoPlayer(videoController!), child: VideoPlayer(videoController!),
), ),
), ),
if (image == null && video == null)
Padding(
padding: const EdgeInsets.all(10.0),
child: MessageSendStateIcon(
[widget.message],
mainAxisAlignment: MainAxisAlignment.center,
),
),
], ],
), ),
); );

View file

@ -5,7 +5,7 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.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/views/chats/components/chat_list_entry.dart'; import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry.dart';
import 'package:twonly/src/views/components/animate_icon.dart'; import 'package:twonly/src/views/components/animate_icon.dart';
import 'package:twonly/src/views/components/initialsavatar.dart'; import 'package:twonly/src/views/components/initialsavatar.dart';
import 'package:twonly/src/views/components/verified_shield.dart'; import 'package:twonly/src/views/components/verified_shield.dart';
@ -26,16 +26,16 @@ Color getMessageColor(Message message) {
} }
/// Displays detailed information about a SampleItem. /// Displays detailed information about a SampleItem.
class ChatItemDetailsView extends StatefulWidget { class ChatMessagesView extends StatefulWidget {
const ChatItemDetailsView(this.contact, {super.key}); const ChatMessagesView(this.contact, {super.key});
final Contact contact; final Contact contact;
@override @override
State<ChatItemDetailsView> createState() => _ChatItemDetailsViewState(); State<ChatMessagesView> createState() => _ChatMessagesViewState();
} }
class _ChatItemDetailsViewState extends State<ChatItemDetailsView> { class _ChatMessagesViewState extends State<ChatMessagesView> {
TextEditingController newMessageController = TextEditingController(); TextEditingController newMessageController = TextEditingController();
HashSet<int> alreadyReportedOpened = HashSet<int>(); HashSet<int> alreadyReportedOpened = HashSet<int>();
late Contact user; late Contact user;

View file

@ -1,298 +0,0 @@
import 'dart:convert';
import 'package:drift/drift.dart' show Value;
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/src/views/chats/chat_item_details_view.dart';
import 'package:twonly/src/views/chats/components/in_chat_media_viewer.dart';
import 'package:twonly/src/views/components/animate_icon.dart';
import 'package:twonly/src/views/components/better_text.dart';
import 'package:twonly/src/views/chats/components/sliding_response.dart';
import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/database/tables/messages_table.dart';
import 'package:twonly/src/model/json/message.dart';
import 'package:twonly/src/providers/api/api.dart';
import 'package:twonly/src/providers/api/media_received.dart' as received;
import 'package:twonly/src/services/notification_service.dart';
import 'package:twonly/src/views/chats/media_viewer_view.dart';
class ChatListEntry extends StatelessWidget {
const ChatListEntry(
this.message,
this.contact,
this.lastMessageFromSameUser,
this.textReactions,
this.otherReactions, {
super.key,
required this.onResponseTriggered,
});
final Message message;
final Contact contact;
final bool lastMessageFromSameUser;
final List<Message> textReactions;
final List<Message> otherReactions;
final Function(Message) onResponseTriggered;
Widget getReactionRow() {
List<Widget> children = [];
bool hasOneTextReaction = false;
bool hasOneReopened = false;
for (final reaction in otherReactions) {
MessageContent? content = MessageContent.fromJson(
reaction.kind, jsonDecode(reaction.contentJson!));
if (content is ReopenedMediaFileContent) {
if (hasOneReopened) continue;
hasOneReopened = true;
children.add(
Expanded(
child: Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: EdgeInsets.only(right: 3),
child: FaIcon(
FontAwesomeIcons.repeat,
size: 12,
color: Colors.white,
),
),
),
),
);
}
// only show one reaction
if (hasOneTextReaction) continue;
if (content is TextMessageContent) {
hasOneTextReaction = true;
if (!isEmoji(content.text)) continue;
late Widget child;
if (EmojiAnimation.animatedIcons.containsKey(content.text)) {
child = SizedBox(
height: 18,
child: EmojiAnimation(emoji: content.text),
);
} else {
child = Text(content.text, style: TextStyle(fontSize: 14));
}
children.insert(
0,
Padding(
padding: EdgeInsets.only(left: 3),
child: child,
),
);
}
}
if (children.isEmpty) return Container();
return Row(
mainAxisAlignment: message.messageOtherId == null
? MainAxisAlignment.start
: MainAxisAlignment.end,
children: children,
);
}
Widget getTextResponseColumns(BuildContext context, bool right) {
List<Widget> children = [];
for (final reaction in textReactions) {
MessageContent? content = MessageContent.fromJson(
reaction.kind, jsonDecode(reaction.contentJson!));
if (content is TextMessageContent) {
var entries = [
FaIcon(
FontAwesomeIcons.reply,
size: 10,
),
SizedBox(width: 5),
Container(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.5,
),
child: Text(
content.text,
style: TextStyle(fontSize: 14),
textAlign: right ? TextAlign.left : TextAlign.right,
)),
];
if (!right) {
entries = entries.reversed.toList();
}
Color color = getMessageColor(reaction);
children.insert(
0,
Container(
padding: EdgeInsets.only(top: 5, bottom: 0, right: 10, left: 10),
child: Container(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.8,
),
padding: EdgeInsets.symmetric(vertical: 1, horizontal: 10),
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(12.0),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: entries,
),
),
),
);
}
}
if (children.isEmpty) return Container();
return Column(
crossAxisAlignment:
right ? CrossAxisAlignment.start : CrossAxisAlignment.end,
children: children,
);
}
@override
Widget build(BuildContext context) {
bool right = message.messageOtherId == null;
MessageContent? content =
MessageContent.fromJson(message.kind, jsonDecode(message.contentJson!));
Widget child = Container();
if (content is TextMessageContent) {
if (EmojiAnimation.supported(content.text)) {
child = child = Container(
constraints: BoxConstraints(
maxWidth: 100,
),
padding: EdgeInsets.symmetric(
vertical: 4,
horizontal: 10,
),
child: EmojiAnimation(emoji: content.text),
);
} else {
child = Container(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.8,
),
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 10),
decoration: BoxDecoration(
color: getMessageColor(message),
borderRadius: BorderRadius.circular(12.0),
),
child: BetterText(text: content.text),
);
}
} else if (content is MediaMessageContent) {
Color color = getMessageColorFromType(
content,
context,
);
child = GestureDetector(
onDoubleTap: () async {
if (message.openedAt == null && message.messageOtherId != null ||
message.mediaStored) {
return;
}
if (await received.existsMediaFile(message.messageId, "png")) {
await encryptAndSendMessageAsync(
null,
contact.userId,
MessageJson(
kind: MessageKind.reopenedMedia,
messageId: message.messageId,
content: ReopenedMediaFileContent(
messageId: message.messageOtherId!,
),
timestamp: DateTime.now(),
),
pushKind: PushKind.reopenedMedia,
);
await twonlyDatabase.messagesDao.updateMessageByMessageId(
message.messageId,
MessagesCompanion(openedAt: Value(null)),
);
}
},
onTap: () {
if (message.kind == MessageKind.media) {
if (message.downloadState == DownloadState.downloaded &&
message.openedAt == null) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return MediaViewerView(contact, initialMessage: message);
}),
);
} else if (message.downloadState == DownloadState.pending) {
received.startDownloadMedia(message, true);
}
}
},
child: Container(
width: 150,
decoration: BoxDecoration(
border: Border.all(
color: color,
width: 1.0,
),
borderRadius: BorderRadius.circular(12.0),
),
child: Align(
alignment: Alignment.centerRight,
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: InChatMediaViewer(
message: message,
contact: contact,
),
),
),
),
);
}
return Align(
alignment: right ? Alignment.centerRight : Alignment.centerLeft,
child: Padding(
padding: lastMessageFromSameUser
? EdgeInsets.only(top: 5, bottom: 0, right: 10, left: 10)
: EdgeInsets.only(top: 5, bottom: 20, right: 10, left: 10),
child: Column(
mainAxisAlignment:
right ? MainAxisAlignment.end : MainAxisAlignment.start,
crossAxisAlignment:
right ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children: [
SlidingResponse(
child: Stack(
alignment: right ? Alignment.centerRight : Alignment.centerLeft,
children: [
child,
Positioned(
bottom: 5,
left: 5,
right: 5,
child: getReactionRow(),
),
],
),
onResponseTriggered: () {
onResponseTriggered(message);
},
),
getTextResponseColumns(context, !right)
],
),
),
);
}
}

View file

@ -10,7 +10,7 @@ import 'package:twonly/src/views/components/user_context_menu.dart';
import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart';
import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/views/chats/chat_item_details_view.dart'; import 'package:twonly/src/views/chats/chat_messages_view.dart';
import 'package:twonly/src/views/chats/search_username_view.dart'; import 'package:twonly/src/views/chats/search_username_view.dart';
class StartNewChat extends StatefulWidget { class StartNewChat extends StatefulWidget {
@ -182,7 +182,7 @@ class UserList extends StatelessWidget {
Navigator.pushReplacement( Navigator.pushReplacement(
context, context,
MaterialPageRoute(builder: (context) { MaterialPageRoute(builder: (context) {
return ChatItemDetailsView(user); return ChatMessagesView(user);
}), }),
); );
}, },

View file

@ -5,7 +5,7 @@ import 'package:pie_menu/pie_menu.dart';
import 'package:twonly/globals.dart'; import 'package:twonly/globals.dart';
import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/views/chats/chat_item_details_view.dart'; import 'package:twonly/src/views/chats/chat_messages_view.dart';
import 'package:twonly/src/views/contact/contact_verify_view.dart'; import 'package:twonly/src/views/contact/contact_verify_view.dart';
class UserContextMenu extends StatefulWidget { class UserContextMenu extends StatefulWidget {
@ -66,7 +66,7 @@ class _UserContextMenuState extends State<UserContextMenu> {
onSelect: () { onSelect: () {
Navigator.push(context, MaterialPageRoute( Navigator.push(context, MaterialPageRoute(
builder: (context) { builder: (context) {
return ChatItemDetailsView(widget.contact); return ChatMessagesView(widget.contact);
}, },
)); ));
}, },