"Refactored AI chat page and message bar widgets: added file name handling, updated text direction logic, and rearranged UI components."
This commit is contained in:
parent
306b85f163
commit
7bec995377
|
|
@ -714,6 +714,7 @@ class _AiChatPageState extends State<AiChatPage> {
|
|||
|
||||
Container messageFile(
|
||||
BuildContext context, Prompts message, AiChatState state) {
|
||||
final String fileName = message.fileName ?? message.fileLocal?.name ?? '';
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: DesignConfig.mediumBorderRadius,
|
||||
|
|
@ -734,9 +735,12 @@ class _AiChatPageState extends State<AiChatPage> {
|
|||
SizedBox(
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
child: MarqueeText(
|
||||
text: message.fileName.toString(),
|
||||
text: fileName,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
stop: const Duration(seconds: 3),
|
||||
textDirection: fileName.startsWithEnglish()
|
||||
? TextDirection.ltr
|
||||
: TextDirection.rtl,
|
||||
),
|
||||
),
|
||||
// if (state.file != null && !kIsWeb)
|
||||
|
|
|
|||
|
|
@ -379,53 +379,17 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
Expanded(
|
||||
child: state.file != null && state.file!.isRecorded
|
||||
? audioContainer()
|
||||
: Directionality(
|
||||
textDirection: state.message.text
|
||||
.toString()
|
||||
.startsWithEnglish()
|
||||
? TextDirection.ltr
|
||||
: TextDirection.rtl,
|
||||
child: TextFormField(
|
||||
textInputAction: TextInputAction.newline,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
minLines: 1,
|
||||
maxLines: 6, // Set this
|
||||
keyboardType: TextInputType.multiline,
|
||||
controller: state.message,
|
||||
|
||||
enabled: !(state.file != null &&
|
||||
widget.bot.attachment == 1),
|
||||
decoration: InputDecoration(
|
||||
contentPadding:
|
||||
const EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||
border: InputBorder.none,
|
||||
hintText: 'بنویسید...',
|
||||
hintStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.disabledText),
|
||||
suffixIcon: state.isEdite
|
||||
? InkWell(
|
||||
onTap: () {
|
||||
state.isEdite = false;
|
||||
state.update();
|
||||
},
|
||||
child: const Icon(
|
||||
DidvanIcons.close_circle_solid),
|
||||
)
|
||||
: const SizedBox(),
|
||||
),
|
||||
|
||||
onChanged: (value) {
|
||||
if (value.isEmpty || value.length == 1) {
|
||||
state.update();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
: ValueListenableBuilder(
|
||||
valueListenable: state.message,
|
||||
builder: (context, message, child) {
|
||||
return Directionality(
|
||||
textDirection:
|
||||
message.text.toString().startsWithEnglish()
|
||||
? TextDirection.ltr
|
||||
: TextDirection.rtl,
|
||||
child: edittext(context, state),
|
||||
);
|
||||
}),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8.0),
|
||||
|
|
@ -458,79 +422,112 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
);
|
||||
}
|
||||
|
||||
Padding recorderAndSendButton(
|
||||
AiChatState state, HistoryAiChatState historyState) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 12, 8),
|
||||
child: state.message.text.isEmpty &&
|
||||
historyState.bot!.attachmentType!.contains('audio') &&
|
||||
state.file == null &&
|
||||
widget.bot.attachment != 0
|
||||
? MessageBarBtn(
|
||||
enable: true,
|
||||
icon: _mRecorder!.isRecording || _mRecorder!.isPaused
|
||||
? Icons.stop_rounded
|
||||
: DidvanIcons.mic_regular,
|
||||
click: getRecorderFn(),
|
||||
)
|
||||
: MessageBarBtn(
|
||||
enable: (state.file != null && state.file!.isRecorded) ||
|
||||
(widget.bot.attachment == 1) ||
|
||||
state.message.text.isNotEmpty,
|
||||
icon: DidvanIcons.send_light,
|
||||
click: () async {
|
||||
if ((state.file == null || !state.file!.isRecorded) &&
|
||||
(widget.bot.attachment != 1) &&
|
||||
state.message.text.isEmpty) {
|
||||
return;
|
||||
}
|
||||
TextFormField edittext(BuildContext context, AiChatState state) {
|
||||
return TextFormField(
|
||||
textInputAction: TextInputAction.newline,
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
minLines: 1,
|
||||
maxLines: 6, // Set this
|
||||
keyboardType: TextInputType.multiline,
|
||||
controller: state.message,
|
||||
|
||||
if (state.messages.isNotEmpty &&
|
||||
DateTime.parse(state.messages.last.dateTime)
|
||||
.toPersianDateStr()
|
||||
.contains(DateTime.parse(DateTime.now()
|
||||
.subtract(const Duration(minutes: 210))
|
||||
.toIso8601String())
|
||||
.toPersianDateStr())) {
|
||||
state.messages.last.prompts.add(Prompts(
|
||||
error: false,
|
||||
text: state.message.text,
|
||||
// file: state.file?.path,
|
||||
// fileName: state.file?.basename,
|
||||
fileLocal: state.file,
|
||||
finished: true,
|
||||
role: 'user',
|
||||
createdAt: DateTime.now()
|
||||
.subtract(const Duration(minutes: 210))
|
||||
.toIso8601String(),
|
||||
));
|
||||
} else {
|
||||
state.messages.add(MessageModel(
|
||||
dateTime: DateTime.now()
|
||||
enabled: !(state.file != null && widget.bot.attachment == 1),
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.fromLTRB(12, 12, 12, 12),
|
||||
border: InputBorder.none,
|
||||
hintText: 'بنویسید...',
|
||||
hintStyle: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(color: Theme.of(context).colorScheme.disabledText),
|
||||
suffixIcon: state.isEdite
|
||||
? InkWell(
|
||||
onTap: () {
|
||||
state.isEdite = false;
|
||||
state.update();
|
||||
},
|
||||
child: const Icon(DidvanIcons.close_circle_solid),
|
||||
)
|
||||
: const SizedBox(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
recorderAndSendButton(AiChatState state, HistoryAiChatState historyState) {
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: state.message,
|
||||
builder: (context, message, child) => Padding(
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 12, 8),
|
||||
child: message.text.isEmpty &&
|
||||
historyState.bot!.attachmentType!.contains('audio') &&
|
||||
state.file == null &&
|
||||
widget.bot.attachment != 0
|
||||
? MessageBarBtn(
|
||||
enable: true,
|
||||
icon: _mRecorder!.isRecording || _mRecorder!.isPaused
|
||||
? Icons.stop_rounded
|
||||
: DidvanIcons.mic_regular,
|
||||
click: getRecorderFn(),
|
||||
)
|
||||
: MessageBarBtn(
|
||||
enable: (state.file != null && state.file!.isRecorded) ||
|
||||
(widget.bot.attachment == 1) ||
|
||||
message.text.isNotEmpty,
|
||||
icon: DidvanIcons.send_light,
|
||||
click: () async {
|
||||
if ((state.file == null || !state.file!.isRecorded) &&
|
||||
(widget.bot.attachment != 1) &&
|
||||
message.text.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.messages.isNotEmpty &&
|
||||
DateTime.parse(state.messages.last.dateTime)
|
||||
.toPersianDateStr()
|
||||
.contains(DateTime.parse(DateTime.now()
|
||||
.subtract(const Duration(minutes: 210))
|
||||
.toIso8601String())
|
||||
.toPersianDateStr())) {
|
||||
state.messages.last.prompts.add(Prompts(
|
||||
error: false,
|
||||
text: message.text,
|
||||
// file: state.file?.path,
|
||||
// fileName: state.file?.basename,
|
||||
fileLocal: state.file,
|
||||
finished: true,
|
||||
role: 'user',
|
||||
createdAt: DateTime.now()
|
||||
.subtract(const Duration(minutes: 210))
|
||||
.toIso8601String(),
|
||||
prompts: [
|
||||
Prompts(
|
||||
error: false,
|
||||
text: state.message.text,
|
||||
finished: true,
|
||||
// file: state.file?.path,
|
||||
// fileName: state.file?.basename,
|
||||
fileLocal: state.file,
|
||||
role: 'user',
|
||||
createdAt: DateTime.now()
|
||||
.subtract(const Duration(minutes: 210))
|
||||
.toIso8601String(),
|
||||
)
|
||||
]));
|
||||
}
|
||||
state.message.clear();
|
||||
openAttach = false;
|
||||
state.update();
|
||||
await state.postMessage(
|
||||
widget.bot, widget.assistantsName != null);
|
||||
},
|
||||
),
|
||||
));
|
||||
} else {
|
||||
state.messages.add(MessageModel(
|
||||
dateTime: DateTime.now()
|
||||
.subtract(const Duration(minutes: 210))
|
||||
.toIso8601String(),
|
||||
prompts: [
|
||||
Prompts(
|
||||
error: false,
|
||||
text: message.text,
|
||||
finished: true,
|
||||
// file: state.file?.path,
|
||||
// fileName: state.file?.basename,
|
||||
fileLocal: state.file,
|
||||
role: 'user',
|
||||
createdAt: DateTime.now()
|
||||
.subtract(const Duration(minutes: 210))
|
||||
.toIso8601String(),
|
||||
)
|
||||
]));
|
||||
}
|
||||
state.message.clear();
|
||||
openAttach = false;
|
||||
state.update();
|
||||
await state.postMessage(
|
||||
widget.bot, widget.assistantsName != null);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -694,7 +691,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
MediaService.onLoadingPickFile(context);
|
||||
FilePickerResult? result = await MediaService.pickPdfFile();
|
||||
if (result != null) {
|
||||
String? name = result.files.first.name;
|
||||
String? name = result.files.single.name;
|
||||
|
||||
if (kIsWeb) {
|
||||
Uint8List? bytes =
|
||||
|
|
@ -910,7 +907,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
|
|||
SizedBox(
|
||||
height: 24,
|
||||
child: MarqueeText(
|
||||
text: state.file != null ? state.file!.name! : '',
|
||||
text: state.file != null ? state.file!.name ?? '' : '',
|
||||
style: const TextStyle(fontSize: 14),
|
||||
stop: const Duration(seconds: 3),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in New Issue