// ignore_for_file: deprecated_member_use import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/views/comments/comments_state.dart'; import 'package:didvan/views/comments/widgets/comment.dart'; import 'package:didvan/views/widgets/didvan/scaffold.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/shimmer_placeholder.dart'; import 'package:didvan/views/widgets/state_handlers/empty_state.dart'; import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; class Comments extends StatefulWidget { final Map pageData; const Comments({ Key? key, required this.pageData, }) : super(key: key); @override State createState() => _CommentsState(); } class _CommentsState extends State { final _focusNode = FocusNode(); double _bottomPadding = 0; @override void initState() { super.initState(); if (_isPage) { final state = context.read(); state.itemId = widget.pageData['id']; state.type = widget.pageData['type']; state.onCommentsChanged = widget.pageData['onCommentsChanged']; Future.delayed( Duration.zero, () => state.getComments(), ); } } bool get _isPage => widget.pageData['isPage'] != false; @override Widget build(BuildContext context) { final bottomViewInset = MediaQuery.of(context).viewInsets.bottom; if (bottomViewInset == 10) { if (_bottomPadding != 10) { FocusScope.of(context).unfocus(); _bottomPadding = 10; } } _bottomPadding = bottomViewInset; final scaffold = DidvanScaffold( hidePlayer: true, // physics: const BouncingScrollPhysics(), backgroundColor: Theme.of(context).colorScheme.surface, appBarData: _isPage ? AppBarData( hasBack: true, title: 'نظرات', subtitle: widget.pageData['title'], ) : null, padding: _isPage ? const EdgeInsets.only(bottom: 100) : EdgeInsets.zero, slivers: [ Consumer( builder: (context, state, child) => SliverStateHandler( onRetry: state.getComments, state: state, itemPadding: const EdgeInsets.only( bottom: 20), childCount: state.comments.length, placeholder: const _CommentPlaceholder(), centerEmptyState: false, enableEmptyState: state.comments.isEmpty, paddingEmptyState: 0, emptyState: EmptyState( asset: Assets.emptyChat, title: 'لیست خالی است', titleColor: const Color.fromARGB(255, 0, 126, 167), subtitle: 'در حال حاضر آیتمی در این بخش ثبت نشده است. هر زمان مورد جدیدی اضافه شود، در اینجا نمایش داده می‌شود.', ), builder: (context, state, index) => Comment( key: ValueKey( state.comments[index].id.toString() + state.comments[index].text, ), focusNode: _focusNode, comment: state.comments[index], ), ), ), ], ); if (_isPage) { return Scaffold( resizeToAvoidBottomInset: true, body: Stack( children: [ Positioned.fill(child: scaffold), Positioned( left: 20, right: 20, bottom: 20, child: CommentMessageBox(focusNode: _focusNode), ), ], ), ); } return Material( child: scaffold, ); } } class CommentMessageBox extends StatefulWidget { final FocusNode focusNode; const CommentMessageBox({Key? key, required this.focusNode}) : super(key: key); @override State createState() => _CommentMessageBoxState(); } class _CommentMessageBoxState extends State { final _controller = TextEditingController(); @override Widget build(BuildContext context) { final state = context.watch(); return Column( children: [ AnimatedSwitcher( duration: const Duration(milliseconds: 250), child: state.showReplyBox ? Container( key: const ValueKey('reply_box'), margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary, borderRadius: BorderRadius.circular(8), border: Border.all( color: Theme.of(context).colorScheme.primary, width: 1, ), ), child: Row( children: [ const Icon( Icons.reply, size: 16, color: Color.fromARGB(255, 194, 194, 194), ), const SizedBox(width: 8), Expanded( child: DidvanText( 'پاسخ به ${state.replyingTo?.fullName ?? ""}', style: const TextStyle( fontSize: 13, color: Color.fromARGB(255, 194, 194, 194), fontWeight: FontWeight.w600, ), ), ), GestureDetector( onTap: () { state.commentId = null; state.replyingTo = null; state.showReplyBox = false; state.update(); }, child: const Icon( Icons.close, size: 16, color: Colors.grey, ), ), ], ), ) : const SizedBox.shrink(key: ValueKey('empty')), ), Container( padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.focused, border: Border.all(color: Theme.of(context).colorScheme.border), borderRadius: BorderRadius.circular(32), ), child: Row( children: [ Expanded( child: TextField( focusNode: widget.focusNode, controller: _controller, keyboardType: TextInputType.multiline, textInputAction: TextInputAction.send, style: Theme.of(context).textTheme.bodyMedium, onEditingComplete: () {}, onSubmitted: (value) => _onSend(state), decoration: InputDecoration( border: InputBorder.none, hintText: 'دیدگاه‌های خود را بنویسید...', hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( color: DesignConfig.isDark ? Colors.white : Colors.black), ), onChanged: (value) => state.text = value, ), ), ElevatedButton( onPressed: () => _onSend(state), style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(32), ), padding: EdgeInsets.zero, minimumSize: const Size(10, 20), tapTargetSize: MaterialTapTargetSize.shrinkWrap, backgroundColor: Theme.of(context).primaryColor, elevation: 0, ), child: Padding( padding: const EdgeInsets.fromLTRB(20, 10, 20, 10), child: Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( 'ارسال', style: Theme.of(context).textTheme.bodyMedium!.copyWith( color: Colors.white, fontWeight: FontWeight.normal, ), ), const SizedBox(width: 8), SvgPicture.asset( 'lib/assets/icons/send2.svg', color: Colors.white, ), ], ), ), ), ), ], ), ), ], ); } void _onSend(CommentsState state) { if (state.text.trim().isNotEmpty) { state.addComment(); _controller.clear(); FocusScope.of(context).unfocus(); } } } class _CommentPlaceholder extends StatelessWidget { const _CommentPlaceholder({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ ShimmerPlaceholder( height: 24, width: 24, borderRadius: DesignConfig.highBorderRadius, ), SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ShimmerPlaceholder( height: 20, width: 100, ), ShimmerPlaceholder( height: 14, width: 100, ), ], ), SizedBox(height: 12), ShimmerPlaceholder( height: 16, width: double.infinity, ), SizedBox(height: 8), ShimmerPlaceholder( height: 16, width: 200, ), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ ShimmerPlaceholder( height: 24, width: 48, ), SizedBox(width: 8), ShimmerPlaceholder( height: 24, width: 48, ), ], ), ], ), ), ], ); } }