"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:
OkaykOrhmn 2024-11-18 16:44:36 +03:30
parent 306b85f163
commit 7bec995377
2 changed files with 121 additions and 120 deletions

View File

@ -714,6 +714,7 @@ class _AiChatPageState extends State<AiChatPage> {
Container messageFile( Container messageFile(
BuildContext context, Prompts message, AiChatState state) { BuildContext context, Prompts message, AiChatState state) {
final String fileName = message.fileName ?? message.fileLocal?.name ?? '';
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: DesignConfig.mediumBorderRadius, borderRadius: DesignConfig.mediumBorderRadius,
@ -734,9 +735,12 @@ class _AiChatPageState extends State<AiChatPage> {
SizedBox( SizedBox(
width: MediaQuery.sizeOf(context).width, width: MediaQuery.sizeOf(context).width,
child: MarqueeText( child: MarqueeText(
text: message.fileName.toString(), text: fileName,
style: const TextStyle(fontSize: 14), style: const TextStyle(fontSize: 14),
stop: const Duration(seconds: 3), stop: const Duration(seconds: 3),
textDirection: fileName.startsWithEnglish()
? TextDirection.ltr
: TextDirection.rtl,
), ),
), ),
// if (state.file != null && !kIsWeb) // if (state.file != null && !kIsWeb)

View File

@ -379,53 +379,17 @@ class _AiMessageBarState extends State<AiMessageBar> {
Expanded( Expanded(
child: state.file != null && state.file!.isRecorded child: state.file != null && state.file!.isRecorded
? audioContainer() ? audioContainer()
: Directionality( : ValueListenableBuilder(
textDirection: state.message.text valueListenable: state.message,
.toString() builder: (context, message, child) {
.startsWithEnglish() return Directionality(
textDirection:
message.text.toString().startsWithEnglish()
? TextDirection.ltr ? TextDirection.ltr
: TextDirection.rtl, : TextDirection.rtl,
child: TextFormField( child: edittext(context, state),
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();
}
},
),
),
), ),
Padding( Padding(
padding: const EdgeInsets.only(bottom: 8.0), padding: const EdgeInsets.only(bottom: 8.0),
@ -458,11 +422,43 @@ class _AiMessageBarState extends State<AiMessageBar> {
); );
} }
Padding recorderAndSendButton( TextFormField edittext(BuildContext context, AiChatState state) {
AiChatState state, HistoryAiChatState historyState) { return TextFormField(
return Padding( 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(),
),
);
}
recorderAndSendButton(AiChatState state, HistoryAiChatState historyState) {
return ValueListenableBuilder(
valueListenable: state.message,
builder: (context, message, child) => Padding(
padding: const EdgeInsets.fromLTRB(12, 0, 12, 8), padding: const EdgeInsets.fromLTRB(12, 0, 12, 8),
child: state.message.text.isEmpty && child: message.text.isEmpty &&
historyState.bot!.attachmentType!.contains('audio') && historyState.bot!.attachmentType!.contains('audio') &&
state.file == null && state.file == null &&
widget.bot.attachment != 0 widget.bot.attachment != 0
@ -476,12 +472,12 @@ class _AiMessageBarState extends State<AiMessageBar> {
: MessageBarBtn( : MessageBarBtn(
enable: (state.file != null && state.file!.isRecorded) || enable: (state.file != null && state.file!.isRecorded) ||
(widget.bot.attachment == 1) || (widget.bot.attachment == 1) ||
state.message.text.isNotEmpty, message.text.isNotEmpty,
icon: DidvanIcons.send_light, icon: DidvanIcons.send_light,
click: () async { click: () async {
if ((state.file == null || !state.file!.isRecorded) && if ((state.file == null || !state.file!.isRecorded) &&
(widget.bot.attachment != 1) && (widget.bot.attachment != 1) &&
state.message.text.isEmpty) { message.text.isEmpty) {
return; return;
} }
@ -494,7 +490,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
.toPersianDateStr())) { .toPersianDateStr())) {
state.messages.last.prompts.add(Prompts( state.messages.last.prompts.add(Prompts(
error: false, error: false,
text: state.message.text, text: message.text,
// file: state.file?.path, // file: state.file?.path,
// fileName: state.file?.basename, // fileName: state.file?.basename,
fileLocal: state.file, fileLocal: state.file,
@ -512,7 +508,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
prompts: [ prompts: [
Prompts( Prompts(
error: false, error: false,
text: state.message.text, text: message.text,
finished: true, finished: true,
// file: state.file?.path, // file: state.file?.path,
// fileName: state.file?.basename, // fileName: state.file?.basename,
@ -531,6 +527,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
widget.bot, widget.assistantsName != null); widget.bot, widget.assistantsName != null);
}, },
), ),
),
); );
} }
@ -694,7 +691,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
MediaService.onLoadingPickFile(context); MediaService.onLoadingPickFile(context);
FilePickerResult? result = await MediaService.pickPdfFile(); FilePickerResult? result = await MediaService.pickPdfFile();
if (result != null) { if (result != null) {
String? name = result.files.first.name; String? name = result.files.single.name;
if (kIsWeb) { if (kIsWeb) {
Uint8List? bytes = Uint8List? bytes =
@ -910,7 +907,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
SizedBox( SizedBox(
height: 24, height: 24,
child: MarqueeText( child: MarqueeText(
text: state.file != null ? state.file!.name! : '', text: state.file != null ? state.file!.name ?? '' : '',
style: const TextStyle(fontSize: 14), style: const TextStyle(fontSize: 14),
stop: const Duration(seconds: 3), stop: const Duration(seconds: 3),
), ),