mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-04-20 22:13:48 +00:00
moved roomserver chat into chat_screen
This commit is contained in:
parent
f3aef42331
commit
ab7cc84db5
3 changed files with 65 additions and 1252 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
|
@ -162,13 +163,12 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||
body: Consumer<MeshCoreConnector>(
|
||||
builder: (context, connector, child) {
|
||||
final messages = connector.getMessages(widget.contact);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: messages.isEmpty
|
||||
? _buildEmptyState()
|
||||
: _buildMessageList(messages),
|
||||
: _buildMessageList(messages, connector),
|
||||
),
|
||||
_buildInputBar(connector),
|
||||
],
|
||||
|
|
@ -199,18 +199,29 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
Widget _buildMessageList(List<Message> messages) {
|
||||
Widget _buildMessageList(List<Message> messages, MeshCoreConnector connector) {
|
||||
return ListView.builder(
|
||||
controller: _scrollController,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16),
|
||||
itemCount: messages.length,
|
||||
itemBuilder: (context, index) {
|
||||
Contact contact = widget.contact;
|
||||
final message = messages[index];
|
||||
String fourByteHex = '';
|
||||
if(widget.contact.type == advTypeRoom) {
|
||||
contact = _resolveContactFrom4Bytes(
|
||||
connector,
|
||||
message.fourByteRoomContactKey.isEmpty ? Uint8List.fromList([0, 0, 0, 0]) : message.fourByteRoomContactKey,
|
||||
);
|
||||
fourByteHex = message.fourByteRoomContactKey.map((b) => b.toRadixString(16).padLeft(2, '0')).join().toUpperCase();
|
||||
}
|
||||
|
||||
return _MessageBubble(
|
||||
message: message,
|
||||
senderName: widget.contact.name,
|
||||
onTap: () => _openMessagePath(message),
|
||||
onLongPress: () => _showMessageActions(message),
|
||||
senderName: widget.contact.type == advTypeRoom ? "${contact.name} [$fourByteHex]" : contact.name,
|
||||
isRoomServer: widget.contact.type == advTypeRoom,
|
||||
onTap: () => _openMessagePath(message, contact),
|
||||
onLongPress: () => _showMessageActions(message, contact),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
@ -579,6 +590,13 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
Contact _resolveContactFrom4Bytes(MeshCoreConnector connector, Uint8List key4Bytes) {
|
||||
return connector.contacts.firstWhere(
|
||||
(c) => listEquals(c.publicKey.sublist(0, 4), key4Bytes.sublist(0, 4)),
|
||||
orElse: () => widget.contact,
|
||||
);
|
||||
}
|
||||
|
||||
String _currentPathLabel(Contact contact) {
|
||||
// Check if user has set a path override
|
||||
if (contact.pathOverride != null) {
|
||||
|
|
@ -684,6 +702,15 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
void _openChat(BuildContext context, Contact contact) {
|
||||
// Check if this is a repeater
|
||||
context.read<MeshCoreConnector>().markContactRead(contact.publicKeyHex);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => ChatScreen(contact: contact)),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showCustomPathDialog(BuildContext context) async {
|
||||
final connector = Provider.of<MeshCoreConnector>(context, listen: false);
|
||||
|
||||
|
|
@ -734,10 +761,11 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||
}
|
||||
|
||||
|
||||
void _openMessagePath(Message message) {
|
||||
void _openMessagePath(Message message, Contact contact) {
|
||||
final connector = context.read<MeshCoreConnector>();
|
||||
final fourByteHex = message.fourByteRoomContactKey.map((b) => b.toRadixString(16).padLeft(2, '0')).join().toUpperCase();
|
||||
final senderName =
|
||||
message.isOutgoing ? (connector.selfName ?? 'Me') : widget.contact.name;
|
||||
message.isOutgoing ? (connector.selfName ?? 'Me') : widget.contact.type == advTypeRoom ? "${contact.name} [$fourByteHex]" : widget.contact.name;
|
||||
final pathMessage = ChannelMessage(
|
||||
senderKey: null,
|
||||
senderName: senderName,
|
||||
|
|
@ -757,7 +785,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||
);
|
||||
}
|
||||
|
||||
void _showMessageActions(Message message) {
|
||||
void _showMessageActions(Message message, Contact contact) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (sheetContext) => SafeArea(
|
||||
|
|
@ -798,6 +826,14 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||
_retryMessage(message);
|
||||
},
|
||||
),
|
||||
if(widget.contact.type == advTypeRoom)
|
||||
ListTile(
|
||||
leading: const Icon(Icons.chat),
|
||||
title: const Text('Open Chat'),
|
||||
onTap: () {
|
||||
_openChat(context, contact);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.close),
|
||||
title: const Text('Cancel'),
|
||||
|
|
@ -862,12 +898,14 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||
class _MessageBubble extends StatelessWidget {
|
||||
final Message message;
|
||||
final String senderName;
|
||||
final bool isRoomServer;
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onLongPress;
|
||||
|
||||
const _MessageBubble({
|
||||
required this.message,
|
||||
required this.senderName,
|
||||
required this.isRoomServer,
|
||||
this.onTap,
|
||||
this.onLongPress,
|
||||
});
|
||||
|
|
@ -886,7 +924,10 @@ class _MessageBubble extends StatelessWidget {
|
|||
? colorScheme.onErrorContainer
|
||||
: (isOutgoing ? colorScheme.onPrimary : colorScheme.onSurface);
|
||||
final metaColor = textColor.withValues(alpha: 0.7);
|
||||
|
||||
String messageText = message.text;
|
||||
if (isRoomServer && !isOutgoing) {
|
||||
messageText = message.text.substring(4.clamp(0, message.text.length));
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||
child: Column(
|
||||
|
|
@ -936,12 +977,20 @@ class _MessageBubble extends StatelessWidget {
|
|||
fallbackTextColor: textColor.withValues(alpha: 0.7),
|
||||
)
|
||||
else
|
||||
Text(
|
||||
message.text,
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
if(!isOutgoing)
|
||||
Text(
|
||||
messageText,
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
if(isOutgoing)
|
||||
Text(
|
||||
message.text,
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isOutgoing && message.retryCount > 0) ...[
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import '../widgets/room_login_dialog.dart';
|
|||
import '../widgets/unread_badge.dart';
|
||||
import 'channels_screen.dart';
|
||||
import 'chat_screen.dart';
|
||||
import 'room_chat_screen.dart';
|
||||
import 'map_screen.dart';
|
||||
import 'repeater_hub_screen.dart';
|
||||
import 'settings_screen.dart';
|
||||
|
|
@ -451,7 +450,7 @@ class _ContactsScreenState extends State<ContactsScreen>
|
|||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => RoomChatScreen(contact: room),
|
||||
builder: (context) => ChatScreen(contact: room),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue