// SPDX-License-Identifier: Apache-2.0 import 'package:flutter/material.dart'; import '../design/breakpoints.dart'; import '../services/snapshot_state_mapper.dart'; import '../services/ts3_server_link.dart'; import '../src/rust/api.dart' as rust; import 'chat_views.dart'; /// Fixed-width inline chat panel for expanded desktop layouts. class ChatPanel extends StatelessWidget { /// Construct an inline chat panel. const ChatPanel({ super.key, required this.messages, required this.snapshot, required this.target, required this.clientName, required this.onClose, this.restoredDraft, this.onDraftChanged, this.onTs3ServerLink, }); /// Backing chat messages shared with the chat route. final List messages; /// Latest TeamSpeak snapshot. final rust.BridgeSnapshot snapshot; /// Chat target shown in the panel. final rust.BridgeMessageTarget target; /// Client display name for direct-message and poke targets. final String clientName; /// Handle TeamSpeak server links embedded in chat messages. final Ts3ServerLinkHandler? onTs3ServerLink; /// Called when the user closes the inline panel. final VoidCallback onClose; /// External draft text to restore in the chat detail view. final String? restoredDraft; /// Called when the draft text changes. final ValueChanged? onDraftChanged; @override Widget build(BuildContext context) { final currentChannelId = ownClientSnapshotState(snapshot)?.channelId; final channelName = snapshotChannelName(snapshot, currentChannelId); return SizedBox( width: ChanoraBreakpoints.chatPanelWidth, child: DecoratedBox( decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, border: Border( left: BorderSide( color: Theme.of(context).colorScheme.outlineVariant, ), ), ), child: ChatDetailView( messages: messages, snapshot: snapshot, target: target, clientName: clientName, currentChannelId: currentChannelId, channelName: channelName, onTs3ServerLink: onTs3ServerLink, restoredDraft: restoredDraft, onDraftChanged: onDraftChanged, messageMaxWidth: 500, headerTrailing: IconButton( tooltip: 'Close chat', icon: const Icon(Icons.close), onPressed: onClose, ), ), ), ); } }