503 lines
20 KiB
Dart
503 lines
20 KiB
Dart
import 'package:animated_custom_dropdown/custom_dropdown.dart';
|
|
import 'package:cached_network_image/cached_network_image.dart';
|
|
import 'package:didvan/config/design_config.dart';
|
|
import 'package:didvan/config/theme_data.dart';
|
|
import 'package:didvan/constants/app_icons.dart';
|
|
import 'package:didvan/models/ai/bots_model.dart';
|
|
import 'package:didvan/models/enums.dart';
|
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
|
import 'package:didvan/utils/action_sheet.dart';
|
|
import 'package:didvan/views/ai/create_bot_assistants_state.dart';
|
|
import 'package:didvan/views/ai/history_ai_chat_state.dart';
|
|
import 'package:didvan/views/widgets/didvan/button.dart';
|
|
import 'package:didvan/views/widgets/didvan/icon_button.dart';
|
|
import 'package:didvan/views/widgets/didvan/switch.dart';
|
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
|
import 'package:didvan/views/widgets/didvan/text_field.dart';
|
|
import 'package:didvan/views/widgets/hoshan_app_bar.dart';
|
|
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
|
|
import 'package:didvan/views/widgets/skeleton_image.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
class CreateBotAssistantsPage extends StatefulWidget {
|
|
const CreateBotAssistantsPage({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<CreateBotAssistantsPage> createState() =>
|
|
_CreateBotAssistantsPageState();
|
|
}
|
|
|
|
class _CreateBotAssistantsPageState extends State<CreateBotAssistantsPage> {
|
|
final List<String> botModels = ['مدل زبانی', 'مدل تصویری'];
|
|
late List<BotsModel> allBots = context.read<HistoryAiChatState>().bots;
|
|
final _formYouTubeKey = GlobalKey<FormState>();
|
|
final _formNameKey = GlobalKey<FormState>();
|
|
final _formDescKey = GlobalKey<FormState>();
|
|
|
|
List<String> countOfLink = [''];
|
|
int selectedItem = 0;
|
|
bool inEdite = true;
|
|
|
|
late InputBorder defaultBorder = OutlineInputBorder(
|
|
borderRadius: DesignConfig.mediumBorderRadius,
|
|
borderSide: BorderSide(
|
|
width: 1, color: Theme.of(context).colorScheme.disabledText));
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
context.read<CreateBotAssistantsState>().getImageToolsBots();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: HoshanAppBar(
|
|
onBack: () => Navigator.pop(context),
|
|
withActions: false,
|
|
),
|
|
body: Consumer<CreateBotAssistantsState>(
|
|
builder: (BuildContext context, CreateBotAssistantsState state,
|
|
Widget? child) =>
|
|
SingleChildScrollView(
|
|
physics: const BouncingScrollPhysics(),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 32),
|
|
child: Column(
|
|
children: [
|
|
title(text: 'نوع دستیار'),
|
|
SizedBox(
|
|
width: MediaQuery.sizeOf(context).width,
|
|
child: CustomDropdown<String>(
|
|
closedHeaderPadding: const EdgeInsets.all(12),
|
|
items: botModels,
|
|
initialItem: botModels[selectedItem],
|
|
hideSelectedFieldWhenExpanded: false,
|
|
decoration: CustomDropdownDecoration(
|
|
listItemDecoration: ListItemDecoration(
|
|
selectedColor: Theme.of(context)
|
|
.colorScheme
|
|
.surface
|
|
.withOpacity(0.5),
|
|
),
|
|
closedBorder: Border.all(color: Colors.grey),
|
|
closedFillColor: Colors.grey.shade100.withOpacity(0.1),
|
|
expandedFillColor:
|
|
Theme.of(context).colorScheme.surface),
|
|
// hintText: "انتخاب کنید",
|
|
onChanged: (value) {
|
|
setState(() {
|
|
selectedItem = botModels.indexOf(value!);
|
|
});
|
|
},
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
const Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
DidvanButton(
|
|
width: 120,
|
|
style: ButtonStyleMode.flat,
|
|
title: 'انتخاب عکس',
|
|
),
|
|
SkeletonImage(
|
|
imageUrl: 'https://via.placeholder.com/70x70',
|
|
width: 80,
|
|
height: 80,
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
title(text: 'انتخاب نام'),
|
|
Form(
|
|
key: _formNameKey,
|
|
child: DidvanTextField(
|
|
onChanged: (value) {},
|
|
validator: (value) {
|
|
String? result;
|
|
if (value.isEmpty) {
|
|
result = 'نام نباید خالی باشد';
|
|
} else if (value.length < 4) {
|
|
result = 'نام نباید کمتر از 4 حرف باشد';
|
|
}
|
|
return result;
|
|
},
|
|
hintText: 'ai@2024_B',
|
|
maxLength: 20,
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 8,
|
|
),
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Icon(
|
|
DidvanIcons.info_circle_light,
|
|
color: Theme.of(context).colorScheme.caption,
|
|
),
|
|
const SizedBox(width: 4),
|
|
Expanded(
|
|
child: DidvanText(
|
|
'نام منحصر به فرد شامل 4 تا 20 کاراکتر (حروف، اعداد، خط تیره، نقطه و زیرخط) ',
|
|
textAlign: TextAlign.right,
|
|
fontSize: 12,
|
|
color: Theme.of(context).colorScheme.caption,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
title(text: 'نوع دستیار'),
|
|
state.loadingImageBots
|
|
? ShimmerPlaceholder(
|
|
width: MediaQuery.sizeOf(context).width,
|
|
height: 48,
|
|
borderRadius: DesignConfig.lowBorderRadius,
|
|
)
|
|
: SizedBox(
|
|
width: MediaQuery.sizeOf(context).width,
|
|
child: CustomDropdown<BotsModel>(
|
|
closedHeaderPadding: const EdgeInsets.all(12),
|
|
items: selectedItem == 0 ? allBots : state.imageBots,
|
|
headerBuilder: (context, bot, enabled) =>
|
|
botRow(bot, context),
|
|
listItemBuilder:
|
|
(context, bot, isSelected, onItemSelect) =>
|
|
botRow(bot, context),
|
|
initialItem:
|
|
(selectedItem == 0 ? allBots : state.imageBots)
|
|
.first,
|
|
hideSelectedFieldWhenExpanded: false,
|
|
decoration: CustomDropdownDecoration(
|
|
listItemDecoration: ListItemDecoration(
|
|
selectedColor: Theme.of(context)
|
|
.colorScheme
|
|
.surface
|
|
.withOpacity(0.5),
|
|
),
|
|
closedBorder: Border.all(color: Colors.grey),
|
|
closedFillColor:
|
|
Colors.grey.shade100.withOpacity(0.1),
|
|
expandedFillColor:
|
|
Theme.of(context).colorScheme.surface),
|
|
// hintText: "انتخاب کنید",
|
|
onChanged: (value) {
|
|
// setState(() {
|
|
// selectedItem = value;
|
|
// });
|
|
},
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
title(text: 'دستورالعمل'),
|
|
Form(
|
|
key: _formDescKey,
|
|
child: DidvanTextField(
|
|
hintText:
|
|
'به ربات خود بگویید که چگونه رفتار کند و چگونه به پیامهای کاربر پاسخ دهد. سعی کنید تا حد امکان واضح و مشخص باشید.',
|
|
textInputType: TextInputType.multiline,
|
|
minLine: 6,
|
|
maxLine: 6,
|
|
maxLength: 400,
|
|
hasHeight: false,
|
|
showLen: true,
|
|
validator: (value) {
|
|
String? result;
|
|
if (value.isEmpty) {
|
|
result = 'دستورالعمل نباید خالی باشد';
|
|
} else if (value.length < 10) {
|
|
result = 'نام نباید کمتر از 10 حرف باشد';
|
|
}
|
|
return result;
|
|
},
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
if (selectedItem == 0)
|
|
Column(
|
|
children: [
|
|
title(text: 'پایگاه دانش', isRequired: false),
|
|
SizedBox(
|
|
height: 48,
|
|
child: ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: Theme.of(context)
|
|
.colorScheme
|
|
.disabledBackground,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius:
|
|
DesignConfig.lowBorderRadius)),
|
|
onPressed: () {},
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Icon(
|
|
CupertinoIcons.add,
|
|
color: Theme.of(context).colorScheme.caption,
|
|
),
|
|
const SizedBox(
|
|
width: 4,
|
|
),
|
|
DidvanText(
|
|
'آپلود فایل (فایل صوتی، پی دی اف)',
|
|
color: Theme.of(context).colorScheme.caption,
|
|
fontSize: 16,
|
|
)
|
|
],
|
|
)),
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
],
|
|
),
|
|
title(text: 'لینک یوتیوب', isRequired: false),
|
|
Form(
|
|
key: _formYouTubeKey,
|
|
child: DidvanTextField(
|
|
onChanged: (value) {},
|
|
validator: (value) =>
|
|
value.startsWith('https://www.youtube.com')
|
|
? null
|
|
: 'باید لینک یوتیوب باشد',
|
|
hintText: 'https://www.youtube.com/watch?v',
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
title(text: 'لینک وب سایت', isRequired: false),
|
|
Row(
|
|
children: [
|
|
if (countOfLink.length > 1)
|
|
DidvanIconButton(
|
|
icon: CupertinoIcons.minus_circle_fill,
|
|
onPressed: () {
|
|
setState(() {
|
|
countOfLink.removeLast();
|
|
});
|
|
},
|
|
),
|
|
DidvanIconButton(
|
|
icon: CupertinoIcons.plus_circle_fill,
|
|
onPressed: () {
|
|
setState(() {
|
|
countOfLink.add('');
|
|
});
|
|
},
|
|
),
|
|
],
|
|
)
|
|
],
|
|
),
|
|
ListView.builder(
|
|
shrinkWrap: true,
|
|
itemCount: countOfLink.length,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
itemBuilder: (context, index) => Column(
|
|
children: [
|
|
DidvanTextField(
|
|
onChanged: (value) {
|
|
countOfLink.insert(index, value);
|
|
},
|
|
// validator: (value) {},
|
|
hintText: 'https://www.weforum.org/agenda/2024/08',
|
|
),
|
|
const SizedBox(
|
|
height: 8,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Icon(
|
|
DidvanIcons.info_circle_light,
|
|
color: Theme.of(context).colorScheme.caption,
|
|
),
|
|
const SizedBox(width: 4),
|
|
Expanded(
|
|
child: DidvanText(
|
|
'دستیار شما با استناد بر اطلاعات ارائه شده در پایگاه دانش، پیام کاربران را ارزیابی میکند.',
|
|
textAlign: TextAlign.right,
|
|
fontSize: 12,
|
|
color: Theme.of(context).colorScheme.caption,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const DidvanText(
|
|
'نمایش عمومی',
|
|
fontSize: 14,
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: DidvanText(
|
|
'در صورت فعال بودن، دستیار شما توسط سایرین قابل مشاهده بوده و مورد استفاده قرار میگیرد.',
|
|
fontSize: 14,
|
|
color: Theme.of(context).colorScheme.caption,
|
|
),
|
|
),
|
|
],
|
|
)
|
|
],
|
|
),
|
|
),
|
|
SizedBox(
|
|
width: 64,
|
|
height: 48,
|
|
child: DidvanSwitch(
|
|
value: false,
|
|
title: '',
|
|
onChanged: (value) {},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
inEdite
|
|
? Flex(
|
|
direction: Axis.horizontal,
|
|
children: [
|
|
Flexible(
|
|
flex: 2,
|
|
child: DidvanButton(
|
|
title: 'ذخیره تغییرات',
|
|
onPressed: () {
|
|
final List<bool> valid = [];
|
|
valid.add(
|
|
!_formYouTubeKey.currentState!.validate());
|
|
valid.add(
|
|
!_formNameKey.currentState!.validate());
|
|
valid.add(
|
|
!_formDescKey.currentState!.validate());
|
|
if (valid.firstWhere(
|
|
(element) => !element,
|
|
)) return;
|
|
},
|
|
),
|
|
),
|
|
const SizedBox(
|
|
width: 20,
|
|
),
|
|
Flexible(
|
|
flex: 1,
|
|
child: DidvanButton(
|
|
title: 'حذف دستیار',
|
|
style: ButtonStyleMode.flat,
|
|
color: Theme.of(context).colorScheme.error,
|
|
onPressed: () {
|
|
ActionSheetUtils(context).openDialog(
|
|
data: ActionSheetData(
|
|
title: 'حذف دستیار',
|
|
titleIcon: DidvanIcons.trash_solid,
|
|
titleColor:
|
|
Theme.of(context).colorScheme.error,
|
|
content: const Column(
|
|
children: [
|
|
DidvanText(
|
|
'با حذف این دستیار، استفاده از آن برای شما و سایر کاربران، امکانپذیر نیست.\nآیا مطمئن هستید؟!',
|
|
fontSize: 14,
|
|
)
|
|
],
|
|
)));
|
|
},
|
|
),
|
|
),
|
|
],
|
|
)
|
|
: const DidvanButton(
|
|
title: 'ذخیره',
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Container botRow(BotsModel bot, BuildContext context) {
|
|
return Container(
|
|
alignment: Alignment.center,
|
|
child: Row(
|
|
children: [
|
|
ClipOval(
|
|
child: CachedNetworkImage(
|
|
imageUrl: bot.image.toString(),
|
|
width: 42,
|
|
height: 42,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: DidvanText(
|
|
bot.name.toString(),
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
))
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget title({required final String text, final bool isRequired = true}) {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
children: [
|
|
Text.rich(
|
|
TextSpan(
|
|
children: [
|
|
TextSpan(
|
|
text: text,
|
|
style: Theme.of(context).textTheme.bodyMedium,
|
|
),
|
|
if (isRequired)
|
|
TextSpan(
|
|
text: '*',
|
|
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
|
color: Theme.of(context).colorScheme.error)),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|