mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-13 12:22:01 +10:00
hide message tracing
This commit is contained in:
@@ -17,6 +17,7 @@ import '../helpers/utf8_length_limiter.dart';
|
||||
import '../l10n/l10n.dart';
|
||||
import '../models/channel.dart';
|
||||
import '../models/channel_message.dart';
|
||||
import '../services/app_settings_service.dart';
|
||||
import '../utils/emoji_utils.dart';
|
||||
import '../widgets/emoji_picker.dart';
|
||||
import '../widgets/gif_message.dart';
|
||||
@@ -263,6 +264,8 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> {
|
||||
}
|
||||
|
||||
Widget _buildMessageBubble(ChannelMessage message) {
|
||||
final settingsService = context.watch<AppSettingsService>();
|
||||
final enableTracing = settingsService.settings.enableMessageTracing;
|
||||
final isOutgoing = message.isOutgoing;
|
||||
final gifId = _parseGifId(message.text);
|
||||
final poi = _parsePoiMessage(message.text);
|
||||
@@ -336,108 +339,166 @@ class _ChannelChatScreenState extends State<ChannelChatScreen> {
|
||||
if (poi != null)
|
||||
_buildPoiMessage(context, poi, isOutgoing)
|
||||
else if (gifId != null)
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: GifMessage(
|
||||
url:
|
||||
'https://media.giphy.com/media/$gifId/giphy.gif',
|
||||
backgroundColor: Colors.transparent,
|
||||
fallbackTextColor: isOutgoing
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.onPrimaryContainer
|
||||
.withValues(alpha: 0.7)
|
||||
: Theme.of(context).colorScheme.onSurface
|
||||
.withValues(alpha: 0.6),
|
||||
),
|
||||
Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: GifMessage(
|
||||
url:
|
||||
'https://media.giphy.com/media/$gifId/giphy.gif',
|
||||
backgroundColor: Colors.transparent,
|
||||
fallbackTextColor: isOutgoing
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.onPrimaryContainer
|
||||
.withValues(alpha: 0.7)
|
||||
: Theme.of(context).colorScheme.onSurface
|
||||
.withValues(alpha: 0.6),
|
||||
),
|
||||
),
|
||||
if (!enableTracing && isOutgoing)
|
||||
Positioned(
|
||||
top: 4,
|
||||
right: 4,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(2),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black.withValues(alpha: 0.3),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
(message.status == ChannelMessageStatus.sent && displayPath.isNotEmpty)
|
||||
? Icons.check_circle
|
||||
: message.status == ChannelMessageStatus.failed
|
||||
? Icons.cancel
|
||||
: Icons.cloud,
|
||||
size: 14,
|
||||
color: (message.status == ChannelMessageStatus.sent && displayPath.isNotEmpty)
|
||||
? Colors.green
|
||||
: message.status == ChannelMessageStatus.failed
|
||||
? Colors.red
|
||||
: Colors.white70,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
else
|
||||
Linkify(
|
||||
text: message.text,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
linkStyle: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.green,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
options: const LinkifyOptions(
|
||||
humanize: false,
|
||||
defaultToHttps: false,
|
||||
),
|
||||
linkifiers: const [UrlLinkifier()],
|
||||
onOpen: (link) =>
|
||||
LinkHandler.handleLinkTap(context, link.url),
|
||||
),
|
||||
if (displayPath.isNotEmpty) ...[
|
||||
const SizedBox(height: 4),
|
||||
Padding(
|
||||
padding: gifId != null
|
||||
? const EdgeInsets.symmetric(horizontal: 8)
|
||||
: EdgeInsets.zero,
|
||||
child: Text(
|
||||
'via ${_formatPathPrefixes(displayPath)}',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 4),
|
||||
Padding(
|
||||
padding: gifId != null
|
||||
? const EdgeInsets.only(
|
||||
left: 8,
|
||||
right: 8,
|
||||
bottom: 4,
|
||||
)
|
||||
: EdgeInsets.zero,
|
||||
child: Row(
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
_formatTime(message.timestamp),
|
||||
Flexible(
|
||||
child: Linkify(
|
||||
text: message.text,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
linkStyle: const TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.green,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
options: const LinkifyOptions(
|
||||
humanize: false,
|
||||
defaultToHttps: false,
|
||||
),
|
||||
linkifiers: const [UrlLinkifier()],
|
||||
onOpen: (link) =>
|
||||
LinkHandler.handleLinkTap(context, link.url),
|
||||
),
|
||||
),
|
||||
if (!enableTracing && isOutgoing) ...[
|
||||
const SizedBox(width: 4),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 2),
|
||||
child: Icon(
|
||||
(message.status == ChannelMessageStatus.sent && displayPath.isNotEmpty)
|
||||
? Icons.check_circle
|
||||
: message.status == ChannelMessageStatus.failed
|
||||
? Icons.cancel
|
||||
: Icons.cloud,
|
||||
size: 14,
|
||||
color: (message.status == ChannelMessageStatus.sent && displayPath.isNotEmpty)
|
||||
? Colors.green
|
||||
: message.status == ChannelMessageStatus.failed
|
||||
? Colors.red
|
||||
: Colors.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
if (enableTracing) ...[
|
||||
if (displayPath.isNotEmpty) ...[
|
||||
const SizedBox(height: 4),
|
||||
Padding(
|
||||
padding: gifId != null
|
||||
? const EdgeInsets.symmetric(horizontal: 8)
|
||||
: EdgeInsets.zero,
|
||||
child: Text(
|
||||
'via ${_formatPathPrefixes(displayPath)}',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
if (message.repeatCount > 0) ...[
|
||||
const SizedBox(width: 6),
|
||||
Icon(
|
||||
Icons.repeat,
|
||||
size: 12,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 4),
|
||||
Padding(
|
||||
padding: gifId != null
|
||||
? const EdgeInsets.only(
|
||||
left: 8,
|
||||
right: 8,
|
||||
bottom: 4,
|
||||
)
|
||||
: EdgeInsets.zero,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'${message.repeatCount}',
|
||||
_formatTime(message.timestamp),
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
if (message.repeatCount > 0) ...[
|
||||
const SizedBox(width: 6),
|
||||
Icon(
|
||||
Icons.repeat,
|
||||
size: 12,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
Text(
|
||||
'${message.repeatCount}',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
],
|
||||
if (isOutgoing) ...[
|
||||
const SizedBox(width: 4),
|
||||
Icon(
|
||||
message.status == ChannelMessageStatus.sent
|
||||
? Icons.check
|
||||
: message.status ==
|
||||
ChannelMessageStatus.pending
|
||||
? Icons.schedule
|
||||
: Icons.error_outline,
|
||||
size: 14,
|
||||
color:
|
||||
message.status ==
|
||||
ChannelMessageStatus.failed
|
||||
? Colors.red
|
||||
: Colors.grey[600],
|
||||
),
|
||||
],
|
||||
],
|
||||
if (isOutgoing) ...[
|
||||
const SizedBox(width: 4),
|
||||
Icon(
|
||||
message.status == ChannelMessageStatus.sent
|
||||
? Icons.check
|
||||
: message.status ==
|
||||
ChannelMessageStatus.pending
|
||||
? Icons.schedule
|
||||
: Icons.error_outline,
|
||||
size: 14,
|
||||
color:
|
||||
message.status ==
|
||||
ChannelMessageStatus.failed
|
||||
? Colors.red
|
||||
: Colors.grey[600],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user