import 'package:flutter/material.dart'; import 'dart:ui'; import '../widgets/chat_box.dart'; import '../screens/full_screen.dart'; import 'package:provider/provider.dart'; import '../services/message_service.dart'; import '../widgets/gradient_background.dart'; class PartScreen extends StatefulWidget { final VoidCallback? onHide; const PartScreen({super.key, this.onHide}); @override State createState() => _PartScreenState(); } class _PartScreenState extends State { final ScrollController _scrollController = ScrollController(); bool _isInitialized = false; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { final messageService = Provider.of(context, listen: false); messageService.removeNonListeningMessages(); setState(() { _isInitialized = true; }); }); } @override void dispose() { _scrollController.dispose(); super.dispose(); } void _scrollToBottom() { if (_scrollController.hasClients) { _scrollController.animateTo( 0.0, duration: const Duration(milliseconds: 200), curve: Curves.easeOut, ); } } void _openFullScreen() async { widget.onHide?.call(); await Navigator.of(context).push( MaterialPageRoute( builder: (context) => const FullScreen(), ), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.transparent, body: LayoutBuilder( builder: (context, constraints) { if (!_isInitialized) { return const SizedBox.shrink(); } final double minHeight = constraints.maxHeight * 0.18; final double maxHeight = constraints.maxHeight * 0.4; final double chatWidth = constraints.maxWidth * 0.94; final int messageCount = context.watch().messages.length; double chatHeight; if (messageCount <= 1) { chatHeight = minHeight; } else { final height = minHeight + (messageCount * 78); chatHeight = height < maxHeight ? height : maxHeight; } return Stack( children: [ Positioned.fill( child: IgnorePointer( ignoring: false, child: GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { final messageService = context.read(); if (widget.onHide != null) widget.onHide!(); setState(() { _isInitialized = true; }); messageService.abortReply(); messageService.initializeEmpty(); }, child: Container( color: Colors.transparent, ), ), ), ), Padding( padding: EdgeInsets.only(bottom: constraints.maxHeight * 0.22), child: Align( alignment: Alignment.bottomCenter, child: Selector( selector: (_, service) => service.messages.length, builder: (context, messageCount, child) { WidgetsBinding.instance.addPostFrameCallback((_) { _scrollToBottom(); }); return Consumer( builder: (context, handler, child) { final messages = handler.messages; return AnimatedContainer( duration: const Duration(milliseconds: 180), curve: Curves.easeInOut, width: chatWidth, height: chatHeight, child: ClipRRect( borderRadius: BorderRadius.circular(24), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 12, sigmaY: 12), child: GradientBackground( colors: const [ Color(0XBF3B0A3F), Color(0xBF0E0E24), Color(0xBF0C0B33), ], borderRadius: BorderRadius.circular(6), child: Stack( children: [ Padding( padding: const EdgeInsets.only( top: 42, left: 6, right: 6, bottom: 6), child: Column( children: [ Expanded( child: Padding( padding: EdgeInsets.only( top: 12, bottom: 12), child: ChatBox( scrollController: _scrollController, messages: messages, ), ), ), ], ), ), Positioned( top: 6, right: 6, child: IconButton( icon: Image.asset( 'assets/images/open_in_full.png', width: 24, height: 24 ), onPressed: _openFullScreen, padding: EdgeInsets.zero, ), ), ], ), ), ), ), ); }, ); }, ), ), ), ], ); }, ), ); } }