forked from eatvio/eatvio_app
112 lines
4.3 KiB
Dart
112 lines
4.3 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: RefreshIndicator(
|
|
child: switch (state.state) {
|
|
BaseState.error => DataErrorWidget(onReload: () => context.read<ChatsCubit>().getChatRooms()),
|
|
BaseState.success => _buildChatList(context, state),
|
|
_ => const Loader(),
|
|
},
|
|
onRefresh: () async {
|
|
await context.read<ChatsCubit>().getChatRooms();
|
|
},
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
NotificationListener<ScrollNotification> _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]);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|