Files
eatvio_app/lib/features/chat/presentation/pages/chats_screen.dart
2025-04-04 20:21:31 +07:00

107 lines
4.1 KiB
Dart

import 'package:easy_debounce/easy_debounce.dart';
import 'package:eatvio_app/core/enums/base_state.dart';
import 'package:eatvio_app/core/utils/pagination_utils.dart';
import 'package:eatvio_app/core/widgets/data_error_widget.dart';
import 'package:eatvio_app/core/widgets/loader.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_state.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/chat_entry_widget.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/chat_search_bar_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class ChatsScreen extends StatefulWidget {
const ChatsScreen({super.key});
@override
State<ChatsScreen> createState() => _ChatsScreenState();
}
class _ChatsScreenState extends State<ChatsScreen> {
final searchController = TextEditingController();
@override
Widget build(BuildContext context) {
return BlocBuilder<ChatsCubit, ChatsState>(
builder: (context, state) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
toolbarHeight: 0,
),
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverPadding(
padding: const EdgeInsets.only(top: 8),
sliver: SliverAppBar(
automaticallyImplyLeading: false,
stretchTriggerOffset: 1,
scrolledUnderElevation: 0,
floating: true,
snap: true,
title: Padding(
padding: const EdgeInsets.only(top: 8),
child: ChatSearchBarWidget(
onSuffixIconTap: () => context.read<ChatsCubit>().getChatRooms(),
onChanged: (query) {
if (query.length > 2) {
EasyDebounce.debounce(
'searchChatRoom',
const Duration(milliseconds: 300),
() => context.read<ChatsCubit>().getChatRooms(query: query),
);
} else {
context.read<ChatsCubit>().getChatRooms();
}
},
controller: searchController,
fillColor: const Color(0xFFF0F2F5),
hintText: "Поиск",
hintStyle: const TextStyle(
color: Color(0xFF7B8794),
),
),
),
),
),
];
},
body: switch (state.state) {
BaseState.error => DataErrorWidget(onReload: () => context.read<ChatsCubit>().getChatRooms()),
BaseState.success => _buildChatList(context, state),
_ => const Loader(),
},
),
);
},
);
}
_buildChatList(BuildContext context, ChatsState state) {
return NotificationListener<ScrollNotification>(
onNotification: (notification) {
loadNewContent(notification, context.read<ChatsCubit>().loadMoreChatRooms);
return false;
},
child: ListView.separated(
padding: const EdgeInsets.all(16),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
separatorBuilder: (context, index) {
return const SizedBox(
height: 8,
);
},
itemCount: state.isLoadingMoreChats ? state.chatRooms.length + 1 : state.chatRooms.length,
itemBuilder: (context, index) {
if (index == state.chatRooms.length) {
return const Center(child: Loader());
}
return ChatEntryWidget(chatRoom: state.chatRooms[index]);
},
),
);
}
}