948 lines
50 KiB
Dart
948 lines
50 KiB
Dart
// ignore_for_file: deprecated_member_use
|
|
|
|
import 'dart:async';
|
|
import 'dart:io';
|
|
|
|
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/bot_assistants_req_model.dart';
|
|
import 'package:didvan/models/ai/bots_model.dart';
|
|
import 'package:didvan/models/ai/file_create_assistants_model.dart';
|
|
import 'package:didvan/models/enums.dart';
|
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
|
import 'package:didvan/models/view/alert_data.dart';
|
|
import 'package:didvan/services/media/media.dart';
|
|
import 'package:didvan/utils/action_sheet.dart';
|
|
import 'package:didvan/utils/extension.dart';
|
|
import 'package:didvan/views/ai/bot_assistants_state.dart';
|
|
import 'package:didvan/views/ai/create_bot_assistants_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/marquee_text.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/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
|
import 'package:image_cropper/image_cropper.dart';
|
|
import 'package:image_picker/image_picker.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
class CreateBotAssistantsPage extends StatefulWidget {
|
|
final int? id;
|
|
const CreateBotAssistantsPage({Key? key, this.id}) : super(key: key);
|
|
|
|
@override
|
|
State<CreateBotAssistantsPage> createState() =>
|
|
_CreateBotAssistantsPageState();
|
|
}
|
|
|
|
class _CreateBotAssistantsPageState extends State<CreateBotAssistantsPage> {
|
|
late InputBorder defaultBorder = OutlineInputBorder(
|
|
borderRadius: DesignConfig.mediumBorderRadius,
|
|
borderSide: BorderSide(
|
|
width: 1, color: Theme.of(context).colorScheme.disabledText));
|
|
|
|
// final _formYouTubeKey = GlobalKey<FormState>();
|
|
final _formNameKey = GlobalKey<FormState>();
|
|
final _formPromptKey = GlobalKey<FormState>();
|
|
final _formDescKey = GlobalKey<FormState>();
|
|
|
|
Timer? _timer;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
}
|
|
|
|
void onConfirm(CreateBotAssistantsState state) async {
|
|
bool isValid = true;
|
|
// if (!_formYouTubeKey.currentState!.validate()) {
|
|
// isValid = false;
|
|
// }
|
|
if (!_formNameKey.currentState!.validate()) {
|
|
isValid = false;
|
|
}
|
|
|
|
if (!_formDescKey.currentState!.validate()) {
|
|
isValid = false;
|
|
}
|
|
|
|
if (!_formPromptKey.currentState!.validate()) {
|
|
isValid = false;
|
|
}
|
|
if (!isValid) {
|
|
return;
|
|
}
|
|
final List<XFile> resultFiles = [];
|
|
for (var file in state.files) {
|
|
if (!file.fromNetwork) {
|
|
resultFiles.add(file.file!);
|
|
}
|
|
}
|
|
|
|
final success = await state.createAssistants(
|
|
id: widget.id,
|
|
data: BotAssistantsReqModel(
|
|
type: state.selectedBotType,
|
|
name: state.name,
|
|
description: state.desc,
|
|
botId: state.initialBot!.id!,
|
|
prompt: state.prompt,
|
|
webLinks:
|
|
state.countOfLink.first.isEmpty ? null : state.countOfLink,
|
|
// youtubeLink: youtubeLink,
|
|
isPrivate: state.isPrivate,
|
|
files: resultFiles,
|
|
deleteImage: state.assistant != null
|
|
? state.assistant!.image == null
|
|
: state.image.value == null,
|
|
image: state.image.value));
|
|
if (success) {
|
|
context.read<BotAssistantsState>().getMyAssissmant();
|
|
context.read<CreateBotAssistantsState>().assistant = null;
|
|
Navigator.pop(context);
|
|
} else {
|
|
ActionSheetUtils(context).showAlert(AlertData(
|
|
message: 'مشکلی در ارتباط با سرور پیش آمده دوباره تلاش کنید',
|
|
aLertType: ALertType.error));
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return WillPopScope(
|
|
onWillPop: () async {
|
|
context.read<CreateBotAssistantsState>().assistant = null;
|
|
|
|
return true;
|
|
},
|
|
child: Scaffold(
|
|
appBar: HoshanAppBar(
|
|
onBack: () {
|
|
context.read<CreateBotAssistantsState>().assistant = null;
|
|
Navigator.pop(context);
|
|
},
|
|
withActions: false,
|
|
),
|
|
body: Consumer<CreateBotAssistantsState>(builder: (BuildContext context,
|
|
CreateBotAssistantsState state, Widget? child) {
|
|
return state.loading
|
|
? Center(
|
|
child: SpinKitThreeBounce(
|
|
size: 46,
|
|
color: Theme.of(context).colorScheme.primary,
|
|
),
|
|
)
|
|
: 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: state.botModels,
|
|
enabled: state.assistant == null,
|
|
initialItem: state.selectedBotType == 'text'
|
|
? state.botModels.first
|
|
: state.botModels.last,
|
|
hideSelectedFieldWhenExpanded: false,
|
|
decoration: CustomDropdownDecoration(
|
|
listItemDecoration: ListItemDecoration(
|
|
selectedColor: Theme.of(context)
|
|
.colorScheme
|
|
.surface
|
|
.withOpacity(0.5),
|
|
),
|
|
closedBorder: Border.all(color: Colors.grey),
|
|
closedFillColor:
|
|
Theme.of(context).colorScheme.surface,
|
|
expandedFillColor:
|
|
Theme.of(context).colorScheme.surface),
|
|
// hintText: "انتخاب کنید",
|
|
onChanged: (value) {
|
|
final index = state.botModels.indexOf(value!);
|
|
state.selectedBotType =
|
|
index == 0 ? 'text' : 'image';
|
|
state.update();
|
|
},
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
ValueListenableBuilder(
|
|
valueListenable: state.image,
|
|
builder: (context, img, _) {
|
|
return Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
DidvanButton(
|
|
width: 120,
|
|
style: ButtonStyleMode.flat,
|
|
color: state.image.value != null ||
|
|
state.assistant?.image != null
|
|
? Theme.of(context).colorScheme.error
|
|
: null,
|
|
title: state.image.value != null ||
|
|
state.assistant?.image != null
|
|
? 'حذف عکس'
|
|
: 'انتخاب عکس',
|
|
onPressed: () async {
|
|
if (state.image.value != null ||
|
|
state.assistant?.image != null) {
|
|
if (state.assistant != null) {
|
|
state.assistant!.image = null;
|
|
}
|
|
state.image.value = null;
|
|
return;
|
|
}
|
|
final pickedFile =
|
|
await MediaService.pickImage(
|
|
source: ImageSource.gallery);
|
|
File? file;
|
|
if (pickedFile != null && !kIsWeb) {
|
|
file = await ImageCropper().cropImage(
|
|
sourcePath: pickedFile.path,
|
|
androidUiSettings:
|
|
const AndroidUiSettings(
|
|
toolbarTitle: 'برش تصویر'),
|
|
iosUiSettings: const IOSUiSettings(
|
|
title: 'برش تصویر',
|
|
doneButtonTitle: 'تایید',
|
|
cancelButtonTitle: 'بازگشت',
|
|
),
|
|
compressQuality: 30,
|
|
);
|
|
if (file != null) {
|
|
state.image.value = XFile(file.path);
|
|
}
|
|
}
|
|
},
|
|
),
|
|
img != null
|
|
? ClipRRect(
|
|
borderRadius:
|
|
DesignConfig.lowBorderRadius,
|
|
child: SizedBox(
|
|
width: 80,
|
|
height: 80,
|
|
child:
|
|
Image.file(File(img.path))),
|
|
)
|
|
: SkeletonImage(
|
|
imageUrl: state.assistant != null &&
|
|
state.assistant!.image != null
|
|
? state.assistant!.image!
|
|
: 'https://via.placeholder.com/70x70',
|
|
width: 80,
|
|
height: 80,
|
|
)
|
|
],
|
|
);
|
|
}),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
title(text: 'انتخاب نام'),
|
|
Form(
|
|
key: _formNameKey,
|
|
child: DidvanTextField(
|
|
initialValue: state.name,
|
|
onChanged: (value) {
|
|
state.name = value;
|
|
|
|
if (value.isEmpty) {
|
|
return;
|
|
}
|
|
if (state.assistant == null) {
|
|
_timer?.cancel();
|
|
_timer =
|
|
Timer(const Duration(seconds: 1), () async {
|
|
await state.getAssistantsName(name: value);
|
|
_formNameKey.currentState!.validate();
|
|
});
|
|
}
|
|
},
|
|
validator: (value) {
|
|
String? result;
|
|
if (value.isEmpty) {
|
|
result = 'نام نباید خالی باشد';
|
|
} else if (value.length < 4) {
|
|
result = 'نام نباید کمتر از 4 حرف باشد';
|
|
} else if (state.assistant == null &&
|
|
!state.successName) {
|
|
result =
|
|
'اسم دیگری انتخاب کنید این اسم موجود است';
|
|
}
|
|
return result;
|
|
},
|
|
hintText: 'ai@2024_B',
|
|
maxLength: 20,
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 8,
|
|
),
|
|
Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
state.loadingName
|
|
? const SizedBox(
|
|
width: 18,
|
|
height: 18,
|
|
child: CircularProgressIndicator())
|
|
: Icon(
|
|
DidvanIcons.info_circle_light,
|
|
color:
|
|
Theme.of(context).colorScheme.caption,
|
|
),
|
|
const SizedBox(width: 4),
|
|
Expanded(
|
|
child: DidvanText(
|
|
state.loadingName
|
|
? '...درحال بررسی اسم'
|
|
: 'نام منحصر به فرد شامل 4 تا 20 کاراکتر (حروف، اعداد، خط تیره، نقطه و زیرخط) ',
|
|
textAlign: TextAlign.right,
|
|
fontSize: 12,
|
|
color: Theme.of(context).colorScheme.caption,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
title(text: 'توضیحات بات'),
|
|
Form(
|
|
key: _formDescKey,
|
|
child: DidvanTextField(
|
|
initialValue: state.desc,
|
|
hintText:
|
|
'توضیح دهید چه کارهایی از این ربات بر میآید.',
|
|
textInputType: TextInputType.multiline,
|
|
minLine: 4,
|
|
maxLine: 4,
|
|
maxLength: 200,
|
|
hasHeight: false,
|
|
showLen: true,
|
|
onChanged: (value) {
|
|
state.desc = value;
|
|
},
|
|
validator: (value) {
|
|
String? result;
|
|
if (value.isEmpty) {
|
|
result = 'توضیحات نباید خالی باشد';
|
|
} else if (value.length < 10) {
|
|
result = 'توضیحات نباید کمتر از 10 حرف باشد';
|
|
}
|
|
return result;
|
|
},
|
|
),
|
|
),
|
|
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: state.selectedBotType == 'text'
|
|
? state.allBots
|
|
: state.imageBots,
|
|
headerBuilder: (context, bot, enabled) =>
|
|
botRow(bot, context),
|
|
listItemBuilder: (context, bot, isSelected,
|
|
onItemSelect) =>
|
|
botRow(bot, context),
|
|
initialItem: state.assistant != null
|
|
? state.initialBot
|
|
: (state.selectedBotType == 'text'
|
|
? state.allBots
|
|
: state.imageBots)
|
|
.first,
|
|
hideSelectedFieldWhenExpanded: false,
|
|
decoration: CustomDropdownDecoration(
|
|
listItemDecoration: ListItemDecoration(
|
|
selectedColor: Theme.of(context)
|
|
.colorScheme
|
|
.surface
|
|
.withOpacity(0.5),
|
|
),
|
|
closedFillColor:
|
|
Theme.of(context).colorScheme.surface,
|
|
closedBorder:
|
|
Border.all(color: Colors.grey),
|
|
expandedFillColor: Theme.of(context)
|
|
.colorScheme
|
|
.surface),
|
|
// hintText: "انتخاب کنید",
|
|
onChanged: (value) {
|
|
state.initialBot = value;
|
|
},
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
title(text: 'دستورالعمل'),
|
|
Form(
|
|
key: _formPromptKey,
|
|
child: DidvanTextField(
|
|
initialValue: state.prompt,
|
|
hintText:
|
|
'به ربات خود بگویید که چگونه رفتار کند و چگونه به پیامهای کاربر پاسخ دهد. سعی کنید تا حد امکان پیام واضح و مشخص باشد.',
|
|
textInputType: TextInputType.multiline,
|
|
minLine: 6,
|
|
maxLine: 6,
|
|
maxLength: 2000,
|
|
hasHeight: false,
|
|
showLen: true,
|
|
onChanged: (value) {
|
|
state.prompt = value;
|
|
},
|
|
validator: (value) {
|
|
String? result;
|
|
if (value.isEmpty) {
|
|
result = 'دستورالعمل نباید خالی باشد';
|
|
} else if (value.length < 10) {
|
|
result = 'نام نباید کمتر از 10 حرف باشد';
|
|
}
|
|
return result;
|
|
},
|
|
),
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
if (state.assistant == null)
|
|
Column(
|
|
children: [
|
|
if (state.selectedBotType == 'text')
|
|
Column(
|
|
children: [
|
|
title(
|
|
text: 'پایگاه دانش', isRequired: false),
|
|
if (state.files.length != 3)
|
|
SizedBox(
|
|
height: 48,
|
|
child: ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor:
|
|
Theme.of(context)
|
|
.colorScheme
|
|
.disabledBackground,
|
|
shape:
|
|
const RoundedRectangleBorder(
|
|
borderRadius: DesignConfig
|
|
.lowBorderRadius)),
|
|
onPressed: () async {
|
|
final picks = await MediaService
|
|
.pickMultiFile();
|
|
if (picks != null) {
|
|
for (var file in picks.xFiles) {
|
|
if (file.path.isDocument() ||
|
|
file.path.isAudio()) {
|
|
state.files.add(
|
|
FileCreateAssistantsModel(
|
|
fromNetwork: false,
|
|
file: file,
|
|
url: null));
|
|
} else {
|
|
ActionSheetUtils(context)
|
|
.showAlert(AlertData(
|
|
message:
|
|
'باید فایل انتخاب شده صوتی یا Pdf باشد',
|
|
aLertType: ALertType
|
|
.error));
|
|
}
|
|
}
|
|
}
|
|
state.update();
|
|
},
|
|
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,
|
|
)
|
|
],
|
|
)),
|
|
),
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
...List.generate(
|
|
state.files.length,
|
|
(index) {
|
|
return SizedBox(
|
|
child: Stack(
|
|
children: [
|
|
Container(
|
|
width: MediaQuery
|
|
.sizeOf(
|
|
context)
|
|
.width /
|
|
5,
|
|
height: MediaQuery.sizeOf(
|
|
context)
|
|
.width /
|
|
5,
|
|
margin: const EdgeInsets
|
|
.symmetric(
|
|
horizontal: 8,
|
|
vertical: 12),
|
|
padding:
|
|
const EdgeInsets.all(
|
|
8),
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context)
|
|
.colorScheme
|
|
.disabledBackground,
|
|
borderRadius: DesignConfig
|
|
.lowBorderRadius),
|
|
child: Column(
|
|
children: [
|
|
Expanded(
|
|
child: state
|
|
.files[
|
|
index]
|
|
.fromNetwork
|
|
? state
|
|
.files[
|
|
index]
|
|
.url!
|
|
.isImage()
|
|
? CachedNetworkImage(
|
|
imageUrl: state
|
|
.files[
|
|
index]
|
|
.url!)
|
|
: const Icon(
|
|
CupertinoIcons
|
|
.doc)
|
|
: state
|
|
.files[
|
|
index]
|
|
.file!
|
|
.path
|
|
.isImage()
|
|
? Image.file(File(state
|
|
.files[
|
|
index]
|
|
.file!
|
|
.path))
|
|
: const Icon(
|
|
CupertinoIcons
|
|
.doc),
|
|
),
|
|
MarqueeText(
|
|
text: state
|
|
.files[
|
|
index]
|
|
.fromNetwork
|
|
? state
|
|
.files[
|
|
index]
|
|
.url!
|
|
.split(
|
|
'/')
|
|
.last
|
|
: state
|
|
.files[
|
|
index]
|
|
.file!
|
|
.name,
|
|
textDirection:
|
|
TextDirection
|
|
.rtl,
|
|
style: Theme.of(
|
|
context)
|
|
.textTheme
|
|
.labelSmall!)
|
|
],
|
|
)),
|
|
Positioned(
|
|
top: 8,
|
|
left: 4,
|
|
child: InkWell(
|
|
onTap: () {
|
|
state.files
|
|
.removeAt(index);
|
|
state.update();
|
|
},
|
|
child: Container(
|
|
padding:
|
|
const EdgeInsets
|
|
.all(6),
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape
|
|
.circle,
|
|
color: Theme.of(
|
|
context)
|
|
.colorScheme
|
|
.error),
|
|
child: const Icon(
|
|
DidvanIcons
|
|
.trash_solid,
|
|
color: Colors.white,
|
|
size: 18,
|
|
),
|
|
),
|
|
))
|
|
],
|
|
),
|
|
);
|
|
},
|
|
)
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
title(
|
|
text: 'لینک وب سایت',
|
|
isRequired: false),
|
|
Row(
|
|
children: [
|
|
if (state.countOfLink.length > 1)
|
|
DidvanIconButton(
|
|
icon: CupertinoIcons
|
|
.minus_circle_fill,
|
|
onPressed: () {
|
|
state.countOfLink
|
|
.removeLast();
|
|
state.update();
|
|
},
|
|
),
|
|
if (state.countOfLink.length != 3)
|
|
DidvanIconButton(
|
|
icon: CupertinoIcons
|
|
.plus_circle_fill,
|
|
onPressed: () {
|
|
if (state.countOfLink.last
|
|
.isNotEmpty) {
|
|
state.countOfLink.add('');
|
|
state.update();
|
|
}
|
|
},
|
|
),
|
|
],
|
|
)
|
|
],
|
|
),
|
|
ListView.builder(
|
|
shrinkWrap: true,
|
|
itemCount: state.countOfLink.length,
|
|
physics:
|
|
const NeverScrollableScrollPhysics(),
|
|
itemBuilder: (context, index) => Column(
|
|
children: [
|
|
DidvanTextField(
|
|
textAlign: TextAlign.left,
|
|
onChanged: (value) {
|
|
state.countOfLink[index] = value;
|
|
if (state.countOfLink[index]
|
|
.isEmpty &&
|
|
state.countOfLink.length !=
|
|
1) {
|
|
state.countOfLink
|
|
.removeAt(index);
|
|
}
|
|
state.update();
|
|
},
|
|
// validator: (value) {},
|
|
hintText: 'https://www.weforum.org',
|
|
),
|
|
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,
|
|
),
|
|
],
|
|
),
|
|
// title(text: 'لینک یوتیوب', isRequired: false),
|
|
// Form(
|
|
// key: _formYouTubeKey,
|
|
// child: DidvanTextField(
|
|
// onChanged: (value) {
|
|
// youtubeLink = value;
|
|
// },
|
|
// validator: (value) =>
|
|
// value.startsWith('https://www.youtube.com') ||
|
|
// value.isEmpty
|
|
// ? null
|
|
// : 'باید لینک یوتیوب باشد',
|
|
// hintText: 'https://www.youtube.com/watch?v',
|
|
// ),
|
|
// ),
|
|
// 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: !state.isPrivate,
|
|
title: '',
|
|
onChanged: (value) {
|
|
state.isPrivate = !value;
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
widget.id != null
|
|
? Flex(
|
|
direction: Axis.horizontal,
|
|
children: [
|
|
Flexible(
|
|
flex: 2,
|
|
child: Stack(
|
|
children: [
|
|
DidvanButton(
|
|
title: state.loadingCreate
|
|
? ' '
|
|
: 'ذخیره تغییرات',
|
|
onPressed: () async =>
|
|
onConfirm(state),
|
|
),
|
|
if (state.loadingCreate)
|
|
const Positioned.fill(
|
|
child: Center(
|
|
child: SpinKitThreeBounce(
|
|
size: 32,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
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,
|
|
)
|
|
],
|
|
),
|
|
onConfirmed: () async {
|
|
final success =
|
|
await state.deleteAssistants(
|
|
id: widget.id!);
|
|
if (success) {
|
|
context
|
|
.read<BotAssistantsState>()
|
|
.getMyAssissmant();
|
|
|
|
context
|
|
.read<
|
|
CreateBotAssistantsState>()
|
|
.assistant = null;
|
|
Navigator.pop(context);
|
|
}
|
|
},
|
|
));
|
|
},
|
|
),
|
|
),
|
|
],
|
|
)
|
|
: Stack(
|
|
children: [
|
|
DidvanButton(
|
|
title:
|
|
state.loadingCreate ? ' ' : 'ذخیره',
|
|
onPressed: () async => onConfirm(state)),
|
|
if (state.loadingCreate)
|
|
const Positioned.fill(
|
|
child: Center(
|
|
child: SpinKitThreeBounce(
|
|
size: 32,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
const SizedBox(
|
|
height: 24,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
|
|
Container botRow(BotsModel bot, BuildContext context) {
|
|
return Container(
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
color: Theme.of(context).colorScheme.surface,
|
|
borderRadius: DesignConfig.highBorderRadius),
|
|
child: Row(
|
|
children: [
|
|
SkeletonImage(
|
|
imageUrl: bot.image.toString(),
|
|
width: 42,
|
|
height: 42,
|
|
borderRadius: BorderRadius.circular(360),
|
|
),
|
|
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)),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|