mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-10-09 19:55:05 +00:00
chore: Initial commit
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPovRHpejR4zRxuhjY4Qs3
This commit is contained in:
108
lib/widgets/messages/messages_content.dart
Normal file
108
lib/widgets/messages/messages_content.dart
Normal file
@@ -0,0 +1,108 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../l10n/app_localizations.dart';
|
||||
import '../../models/message.dart';
|
||||
import '../../providers/messages_provider.dart';
|
||||
import '../common/bidirectional_refresh.dart';
|
||||
import '../../widgets/messages/message_bubble.dart';
|
||||
|
||||
class MessagesContent extends StatelessWidget {
|
||||
static const double defaultPadding = 8;
|
||||
|
||||
final List<DisplayMessageEntry> messages;
|
||||
final ScrollController scrollController;
|
||||
final String? highlightedMessageId;
|
||||
final double bottomContentPadding;
|
||||
final Future<void> Function() onRefresh;
|
||||
final VoidCallback? onNavigateToMap;
|
||||
final ValueChanged<Message>? onMessageTap;
|
||||
final ValueChanged<Message>? onReplyToMessage;
|
||||
|
||||
const MessagesContent({
|
||||
super.key,
|
||||
required this.messages,
|
||||
required this.scrollController,
|
||||
required this.highlightedMessageId,
|
||||
this.bottomContentPadding = 0,
|
||||
required this.onRefresh,
|
||||
this.onNavigateToMap,
|
||||
this.onMessageTap,
|
||||
this.onReplyToMessage,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const scrollPhysics = BouncingScrollPhysics(
|
||||
parent: AlwaysScrollableScrollPhysics(),
|
||||
);
|
||||
|
||||
return BidirectionalRefresh(
|
||||
onRefresh: onRefresh,
|
||||
child: messages.isEmpty
|
||||
? LayoutBuilder(
|
||||
builder: (context, constraints) => SingleChildScrollView(
|
||||
keyboardDismissBehavior:
|
||||
ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
physics: scrollPhysics,
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(minHeight: constraints.maxHeight),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.message_outlined,
|
||||
size: 64,
|
||||
color: Theme.of(context).disabledColor,
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
AppLocalizations.of(context)!.noMessagesYet,
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
AppLocalizations.of(context)!.pullDownToSync,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: ListView.builder(
|
||||
controller: scrollController,
|
||||
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
|
||||
physics: scrollPhysics,
|
||||
reverse: true,
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
defaultPadding,
|
||||
defaultPadding,
|
||||
defaultPadding,
|
||||
defaultPadding + bottomContentPadding,
|
||||
),
|
||||
itemCount: messages.length,
|
||||
itemBuilder: (context, index) {
|
||||
final entry = messages[index];
|
||||
final message = entry.message;
|
||||
|
||||
return MessageBubble(
|
||||
key: ValueKey(message.id),
|
||||
message: message,
|
||||
receivedCopies: entry.occurrenceCount,
|
||||
isHighlighted: message.id == highlightedMessageId,
|
||||
onNavigateToMap: onNavigateToMap,
|
||||
onTap: onMessageTap == null
|
||||
? null
|
||||
: () => onMessageTap!(message),
|
||||
onReply: onReplyToMessage == null
|
||||
? null
|
||||
: () => onReplyToMessage!(message),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user