From d549f01a23b9f40d1ec80cba4ce0f70da0c11ae9 Mon Sep 17 00:00:00 2001 From: maxxkim Date: Mon, 22 Apr 2024 12:46:36 +0300 Subject: [PATCH] feat(chat): Layouts for chat select finished --- assets/images/img_glass.svg | 4 + lib/core/utils/image_constant.dart | 1 + .../bloc/chat_select_bloc.dart | 30 +++- .../chat_select_screen/chat_search_view.dart | 164 ++++++++++++++++++ .../chat_select_screen.dart | 91 ++++++---- .../chat_select_screen/models/chat_entry.dart | 4 +- .../models/chat_select_model.dart | 4 +- .../widgets/chat_entry_widget.dart | 2 +- 8 files changed, 257 insertions(+), 43 deletions(-) create mode 100644 assets/images/img_glass.svg create mode 100644 lib/presentation/chat/chat_select_screen/chat_search_view.dart diff --git a/assets/images/img_glass.svg b/assets/images/img_glass.svg new file mode 100644 index 00000000..063af954 --- /dev/null +++ b/assets/images/img_glass.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/core/utils/image_constant.dart b/lib/core/utils/image_constant.dart index e7dd2b2a..8534fec2 100644 --- a/lib/core/utils/image_constant.dart +++ b/lib/core/utils/image_constant.dart @@ -14,6 +14,7 @@ class ImageConstant { static String imageNotFound = 'assets/images/image_not_found.png'; + static String imaGlass = 'assets/images/image_glass.svg'; // Настройки images static String imgClose = '$imagePath/img_close.svg'; diff --git a/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart b/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart index 1fbde95f..04059200 100644 --- a/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart +++ b/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart @@ -2,6 +2,7 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import '/core/app_export.dart'; import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_select_model.dart'; +import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_entry.dart'; // ignore: must_be_immutable part 'chat_select_event.dart'; part 'chat_select_state.dart'; @@ -11,11 +12,38 @@ class ChatSelectBloc extends Bloc { on(_onInitialize); } + List fillChatEntryList() { + return [ + ChatItemModel( + userImage: ImageConstant.imgLogo, + username: "Ксения Обрамова", + dateText: "9/29", + greetingText: "Привет, хорошая статья"), + ChatItemModel( + userImage: ImageConstant.imgLogo, + username: "Ксения Обрамова", + dateText: "9/29", + greetingText: "Привет, хорошая статья"), + ChatItemModel( + userImage: ImageConstant.imgLogo, + username: "Данил Иванов", + dateText: "9/29", + greetingText: "Посоветуй пожалуйста рецепт..."), + ChatItemModel( + userImage: ImageConstant.imgLogo, + username: "Данил Иванов", + dateText: "9/29", + greetingText: "Посоветуй пожалуйста рецепт...") + ]; + } + _onInitialize( ChatSelectInitialEvent event, Emitter emit, ) async { emit(state.copyWith( - chatSelectModelObj: state.chatSelectModelObj?.copyWith())); + chatSelectModelObj: state.chatSelectModelObj?.copyWith( + userprofileItemList: fillChatEntryList(), + ))); } } diff --git a/lib/presentation/chat/chat_select_screen/chat_search_view.dart b/lib/presentation/chat/chat_select_screen/chat_search_view.dart new file mode 100644 index 00000000..b9447660 --- /dev/null +++ b/lib/presentation/chat/chat_select_screen/chat_search_view.dart @@ -0,0 +1,164 @@ +import 'package:flutter/material.dart'; +import 'package:eatvio_app/core/app_export.dart'; + +class CustomSearchView extends StatelessWidget { + CustomSearchView( + {Key? key, + this.alignment, + this.width, + this.scrollPadding, + this.controller, + this.focusNode, + this.autofocus = false, + this.textStyle, + this.textInputType = TextInputType.text, + this.maxLines, + this.hintText, + this.hintStyle, + this.prefix, + this.prefixConstraints, + this.suffix, + this.suffixConstraints, + this.contentPadding, + this.borderDecoration, + this.fillColor, + this.filled = true, + this.validator, + this.onChanged}) + : super( + key: key, + ); + + final Alignment? alignment; + + final double? width; + + final TextEditingController? scrollPadding; + + final TextEditingController? controller; + + final FocusNode? focusNode; + + final bool? autofocus; + + final TextStyle? textStyle; + + final TextInputType? textInputType; + + final int? maxLines; + + final String? hintText; + + final TextStyle? hintStyle; + + final Widget? prefix; + + final BoxConstraints? prefixConstraints; + + final Widget? suffix; + + final BoxConstraints? suffixConstraints; + + final EdgeInsets? contentPadding; + + final InputBorder? borderDecoration; + + final Color? fillColor; + + final bool? filled; + + final FormFieldValidator? validator; + + final Function(String)? onChanged; + + @override + Widget build(BuildContext context) { + return alignment != null + ? Align( + alignment: alignment ?? Alignment.center, + child: searchViewWidget(context)) + : searchViewWidget(context); + } + + searchViewWidget(BuildContext context) => SizedBox( + width: width ?? double.maxFinite, + child: TextFormField( + scrollPadding: + EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + controller: controller, + focusNode: focusNode, + onTapOutside: (event) => onTapOutside(), + autofocus: autofocus!, + style: textStyle ?? CustomTextStyles.bodySmallMulishBluegray800, + keyboardType: textInputType, + maxLines: maxLines ?? 1, + decoration: decoration, + validator: validator, + onChanged: (String value) => onChanged?.call(value), + ), + ); + + void onTapOutside() { + if (focusNode != null) { + focusNode?.unfocus(); + } else { + FocusManager.instance.primaryFocus?.unfocus(); + } + } + + InputDecoration get decoration => InputDecoration( + hintText: hintText ?? "", + hintStyle: hintStyle ?? CustomTextStyles.bodySmallMulishBluegray800, + prefixIcon: prefix ?? + SizedBox( + child: Padding( + padding: EdgeInsets.only(left: 10), + child: Icon(Icons.search)), + ), + prefixIconConstraints: prefixConstraints ?? + BoxConstraints( + maxHeight: 40.v, + ), + suffixIcon: suffix ?? + Padding( + padding: EdgeInsets.only( + right: 15.h, + ), + child: IconButton( + onPressed: () => controller!.clear(), + icon: Icon( + Icons.clear, + color: Colors.grey.shade600, + ), + ), + ), + suffixIconConstraints: suffixConstraints ?? + BoxConstraints( + maxHeight: 40.v, + ), + isDense: true, + contentPadding: contentPadding ?? + EdgeInsets.only( + top: 11.v, + right: 11.h, + bottom: 11.v, + ), + fillColor: fillColor ?? appTheme.gray100, + filled: filled, + border: borderDecoration ?? + OutlineInputBorder( + borderRadius: BorderRadius.circular(8.h), + borderSide: BorderSide.none, + ), + enabledBorder: borderDecoration ?? + OutlineInputBorder( + borderRadius: BorderRadius.circular(8.h), + borderSide: BorderSide.none, + ), + focusedBorder: borderDecoration ?? + OutlineInputBorder( + borderRadius: BorderRadius.circular(8.h), + borderSide: BorderSide.none, + ), + ); +} diff --git a/lib/presentation/chat/chat_select_screen/chat_select_screen.dart b/lib/presentation/chat/chat_select_screen/chat_select_screen.dart index 7b9b2f65..563c487e 100644 --- a/lib/presentation/chat/chat_select_screen/chat_select_screen.dart +++ b/lib/presentation/chat/chat_select_screen/chat_select_screen.dart @@ -1,6 +1,8 @@ import 'bloc/chat_select_bloc.dart'; import 'models/chat_select_model.dart'; import 'package:eatvio_app/core/app_export.dart'; +import '../chat_select_screen/chat_search_view.dart'; +import 'package:eatvio_app/widgets/custom_bottom_bar.dart'; import 'package:flutter/material.dart'; import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_entry.dart'; // ignore: must_be_immutable import 'package:eatvio_app/presentation/chat/chat_select_screen/widgets/chat_entry_widget.dart'; // ignore: must_be_immutable @@ -20,41 +22,53 @@ class ChatSelectScreen extends StatelessWidget { mediaQueryData = MediaQuery.of(context); return SafeArea( child: Scaffold( - resizeToAvoidBottomInset: false, - body: Container( - width: double.maxFinite, - decoration: AppDecoration.fillGray, - child: Column( - children: [ - SizedBox(height: 30.v), - Container( - margin: EdgeInsets.only( - left: 16.h, - right: 20.h, - ), - padding: EdgeInsets.all(12.h), - decoration: AppDecoration.outlinePrimary.copyWith( - borderRadius: BorderRadiusStyle.circleBorder8, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - BlocSelector( - selector: (state) => TextEditingController(), - builder: (context, searchController) { - return Container(); - }, - ), - SizedBox(height: 20.v), - _buildUserprofile(context) - ], - ), - ) - ], + resizeToAvoidBottomInset: false, + body: Container( + width: double.maxFinite, + decoration: AppDecoration.fillGray, + child: Column( + children: [ + SizedBox(height: 30.v), + Container( + margin: EdgeInsets.only( + left: 16.h, + right: 20.h, + ), + padding: EdgeInsets.all(12.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.all(Radius.circular(12)), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 2, + blurRadius: 5, + offset: Offset(0, 3), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + BlocSelector( + selector: (state) => TextEditingController(), + builder: (context, searchController) { + return CustomSearchView( + controller: searchController, + hintText: "Поиск", + ); + }, + ), + SizedBox(height: 20.v), + _buildUserprofile(context) + ], + ), + ) + ], + ), ), - ), - ), + bottomNavigationBar: _buildBottomBar(context)), ); } @@ -63,7 +77,6 @@ class ChatSelectScreen extends StatelessWidget { selector: (state) => state.chatSelectModelObj, builder: (context, chatSelectModelObj) { return ListView.separated( - physics: NeverScrollableScrollPhysics(), shrinkWrap: true, separatorBuilder: (context, index) { return SizedBox( @@ -72,9 +85,9 @@ class ChatSelectScreen extends StatelessWidget { }, itemCount: chatSelectModelObj?.userprofileItemList.length ?? 0, itemBuilder: (context, index) { - UserprofileItemModel model = + ChatItemModel model = chatSelectModelObj?.userprofileItemList[index] ?? - UserprofileItemModel(); + ChatItemModel(); return UserprofileItemWidget( model, ); @@ -83,4 +96,8 @@ class ChatSelectScreen extends StatelessWidget { }, ); } + + _buildBottomBar(BuildContext context) { + return CustomBottomBar(onChanged: (BottomBarEnum type) {}); + } } diff --git a/lib/presentation/chat/chat_select_screen/models/chat_entry.dart b/lib/presentation/chat/chat_select_screen/models/chat_entry.dart index 2cd363fe..40fb78ef 100644 --- a/lib/presentation/chat/chat_select_screen/models/chat_entry.dart +++ b/lib/presentation/chat/chat_select_screen/models/chat_entry.dart @@ -3,8 +3,8 @@ import 'package:eatvio_app/core/app_export.dart'; /// This class is used in the [userprofile_item_widget] screen. // ignore_for_file: must_be_immutable -class UserprofileItemModel { - UserprofileItemModel( +class ChatItemModel { + ChatItemModel( {this.userImage, this.username, this.dateText, diff --git a/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart b/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart index a7014788..4a3b9669 100644 --- a/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart +++ b/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart @@ -8,8 +8,8 @@ import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_entr class ChatSelectModel extends Equatable { ChatSelectModel({this.userprofileItemList = const []}); - List userprofileItemList; - ChatSelectModel copyWith({List? userprofileItemList}) { + List userprofileItemList; + ChatSelectModel copyWith({List? userprofileItemList}) { return ChatSelectModel( userprofileItemList: userprofileItemList ?? this.userprofileItemList, ); diff --git a/lib/presentation/chat/chat_select_screen/widgets/chat_entry_widget.dart b/lib/presentation/chat/chat_select_screen/widgets/chat_entry_widget.dart index 13fb8371..97f0ec28 100644 --- a/lib/presentation/chat/chat_select_screen/widgets/chat_entry_widget.dart +++ b/lib/presentation/chat/chat_select_screen/widgets/chat_entry_widget.dart @@ -10,7 +10,7 @@ class UserprofileItemWidget extends StatelessWidget { key: key, ); - UserprofileItemModel userprofileItemModelObj; + ChatItemModel userprofileItemModelObj; @override Widget build(BuildContext context) {