didvan-app/lib/views/ai/history_ai_chat_page.dart

368 lines
15 KiB
Dart

// ignore_for_file: library_private_types_in_public_api
import 'dart:async';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/constants/assets.dart';
import 'package:didvan/main.dart';
import 'package:didvan/models/ai/ai_chat_args.dart';
import 'package:didvan/models/view/action_sheet_data.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/utils/date_time.dart';
import 'package:didvan/views/ai/history_ai_chat_state.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:provider/provider.dart';
class HistoryAiChatPage extends StatefulWidget {
const HistoryAiChatPage({Key? key}) : super(key: key);
@override
_HistoryAiChatPageState createState() => _HistoryAiChatPageState();
}
class _HistoryAiChatPageState extends State<HistoryAiChatPage> {
ScrollController scrollController = ScrollController();
@override
void initState() {
final state = context.read<HistoryAiChatState>();
Future.delayed(
Duration.zero,
() => state.getChats(),
);
super.initState();
}
@override
Widget build(BuildContext context) {
return DidvanScaffold(
hidePlayer: true,
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 92),
floatingActionButton: openAiListBtn(context),
scrollController: scrollController,
slivers: [
Consumer<HistoryAiChatState>(
builder: (context, state, child) {
return SliverStateHandler(
state: state,
emptyState: EmptyState(
asset: Assets.emptyResult,
title: 'لیست خالی است',
),
enableEmptyState: state.chats.isEmpty,
placeholder: const _HistoryPlaceholder(),
placeholderCount: 8,
// builder: (context, state, index) => _HistoryPlaceholder(),
builder: (context, state, index) {
final chat = state.chats[index];
return InkWell(
onTap: () {
if (state.chatsToDelete.isEmpty) {
navigatorKey.currentState!.pushNamed(Routes.aiChat,
arguments:
AiChatArgs(bot: chat.bot!, chatId: chat.id!));
} else {
if (state.chatsToDelete.contains(chat.id)) {
state.chatsToDelete.remove(chat.id!);
} else {
state.chatsToDelete.add(chat.id!);
}
}
state.update();
},
onLongPress: () {
if (state.chatsToDelete.isEmpty) {
state.chatsToDelete.add(chat.id!);
}
state.update();
},
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color:
Theme.of(context).colorScheme.border))),
child: Stack(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(
width: 46,
height: 46,
),
const SizedBox(
width: 18,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
DidvanText(
chat.bot!.name.toString(),
fontWeight: FontWeight.bold,
),
DidvanText(
DateTimeUtils.momentGenerator(
chat.updatedAt.toString()),
style:
const TextStyle(fontSize: 12)),
],
),
SizedBox(
child: DidvanText(
chat.prompts![0].text.toString(),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
],
),
Positioned(
bottom: 0,
right: 0,
top: 0,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: ClipOval(
child: CachedNetworkImage(
imageUrl: chat.bot!.image.toString(),
),
),
),
),
if (state.chatsToDelete.contains(chat.id))
Positioned(
right: 32,
bottom: 0,
child: Container(
// ignore: prefer_const_constructors
decoration: BoxDecoration(
color: Theme.of(context)
.scaffoldBackgroundColor,
shape: BoxShape.circle),
child: Icon(DidvanIcons.check_circle_solid,
size: 20,
color:
Theme.of(context).colorScheme.success),
),
)
],
),
),
);
},
childCount: state.chats.length,
onRetry: state.getChats);
},
)
],
appBarData: null,
);
}
Widget openAiListBtn(BuildContext context) {
final watch = context.watch<HistoryAiChatState>();
final state = context.read<HistoryAiChatState>();
return FloatingActionButton(
backgroundColor: watch.chatsToDelete.isEmpty
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.error,
shape: const OvalBorder(),
mini: true,
onPressed: () {
if (watch.chatsToDelete.isEmpty) {
state.getBots();
state.search = '';
_botsDialogSelect(context);
} else {
state.addChatToDelete();
}
},
child: watch.chatsToDelete.isEmpty
? const Icon(DidvanIcons.add_regular)
: const Icon(DidvanIcons.trash_regular),
);
}
void _botsDialogSelect(BuildContext context) {
final state = context.read<HistoryAiChatState>();
ActionSheetUtils.context = context;
ActionSheetUtils.openDialog(
data: ActionSheetData(
hasConfirmButton: false,
hasDismissButton: false,
content: Column(
children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// Padding(
// padding: const EdgeInsets.symmetric(vertical: 8.0),
// child: InkWell(
// onTap: () {
// ActionSheetUtils.pop();
// },
// child: const Icon(DidvanIcons.close_solid)),
// )
// ],
// ),
// SearchField(
// title: 'هوش مصنوعی',
// value: state.search,
// onChanged: (value) {
// state.search = value;
// if (value.isEmpty) {
// state.getBots();
// return;
// }
// state.timer?.cancel();
// state.timer = Timer(const Duration(seconds: 1), () {
// state.getSearchBots(value);
// });
// },
// focusNode: FocusNode()),
// const SizedBox(
// height: 12,
// ),
SizedBox(
width: double.infinity,
height: MediaQuery.sizeOf(context).height / 3,
child: ValueListenableBuilder<bool>(
valueListenable: state.loadingBots,
builder: (context, value, child) => value
? Center(
child: Image.asset(
Assets.loadingAnimation,
width: 60,
height: 60,
),
)
: state.bots.isEmpty
? Padding(
padding: const EdgeInsets.symmetric(
horizontal: 12.0),
child: EmptyState(
asset: Assets.emptyResult,
title: 'نتیجه‌ای پیدا نشد',
height: 120,
),
)
: ListView.builder(
padding:
const EdgeInsets.symmetric(vertical: 12),
itemCount: state.bots.length,
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
final bot = state.bots[index];
return InkWell(
onTap: () {
ActionSheetUtils.pop();
navigatorKey.currentState!.pushNamed(
Routes.aiChat,
arguments: AiChatArgs(bot: bot));
},
child: Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(
vertical: 8),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Theme.of(context)
.colorScheme
.border,
width: 1))),
child: Row(
children: [
ClipOval(
child: CachedNetworkImage(
imageUrl: bot.image.toString(),
width: 42,
height: 42,
),
),
const SizedBox(width: 12),
Text(bot.name.toString())
],
),
),
);
}),
),
)
],
)));
}
}
class _HistoryPlaceholder extends StatelessWidget {
const _HistoryPlaceholder({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Padding(
padding: EdgeInsets.symmetric(vertical: 12.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipOval(
child: ShimmerPlaceholder(
height: 42,
width: 42,
),
),
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),
],
),
),
],
),
);
}
}