"Added file download functionality, modified media service, and updated AI chat page and state with file download feature."

This commit is contained in:
OkaykOrhmn 2024-10-03 09:35:26 +03:30
parent 0512e22727
commit f42171401e
4 changed files with 151 additions and 61 deletions

View File

@ -1,4 +1,7 @@
import 'dart:io';
import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/ai/files_model.dart';
import 'package:didvan/models/requests/studio.dart';
import 'package:didvan/models/studio_details_data.dart';
import 'package:didvan/models/view/action_sheet_data.dart';
@ -11,7 +14,12 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:just_audio/just_audio.dart';
import 'package:mime/mime.dart';
import 'package:path/path.dart' as p;
import 'package:file_picker/file_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
import 'package:universal_html/html.dart' as html;
class MediaService {
static final audioPlayer = AudioPlayer();
@ -141,6 +149,42 @@ class MediaService {
}
}
static Future<String?> downloadFile(String url) async {
final basename = p.basename(url).split('?accessToken=').first;
Directory? dir;
try {
if (Platform.isIOS) {
dir = await getApplicationDocumentsDirectory(); // for iOS
} else {
dir = Directory('/storage/emulated/0/Download/'); // for android
if (!await dir.exists()) dir = (await getExternalStorageDirectory())!;
}
} catch (err) {
print("Cannot get download folder path $err");
}
String path = "${dir?.path}$basename";
File file = File(path);
try {
final http.Response audioResponse = await http.get(Uri.parse(url));
final bytes = audioResponse.bodyBytes;
file.writeAsBytes(bytes);
} catch (e) {
print("Exception$e");
return null;
}
return path;
}
static String downloadFileFromWeb(String url) {
html.AnchorElement anchorElement = html.AnchorElement(href: url);
anchorElement.download = url;
anchorElement.click();
return anchorElement.pathname!;
}
static onLoadingPickFile(BuildContext context) {
ActionSheetUtils(context).openDialog(
barrierDismissible: false,

View File

@ -16,6 +16,9 @@ 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/routes/routes.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/utils/date_time.dart';
import 'package:didvan/views/ai/ai_chat_state.dart';
@ -27,6 +30,7 @@ import 'package:didvan/views/widgets/didvan/icon_button.dart';
import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/marquee_text.dart';
import 'package:didvan/views/widgets/skeleton_image.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
@ -313,11 +317,12 @@ class _AiChatPageState extends State<AiChatPage> {
bottomSheet: Column(
mainAxisSize: MainAxisSize.min,
children: [
Platform.isIOS
? AiMessageBarIOS(
bot: widget.args.bot,
)
: AiMessageBar(
// Platform.isIOS
// ? AiMessageBarIOS(
// bot: widget.args.bot,
// )
// :
AiMessageBar(
bot: widget.args.bot,
),
],
@ -590,6 +595,39 @@ class _AiChatPageState extends State<AiChatPage> {
),
),
),
if (message.file != null)
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () async {
final url =
'${RequestHelper.baseUrl + message.file.toString()}?accessToken=${RequestService.token}';
final download = kIsWeb
? MediaService
.downloadFileFromWeb(url)
: await MediaService.downloadFile(
url);
AlertData alertData = AlertData(
message: 'دانلود موفقیت آمیز بود',
aLertType: ALertType.success);
if (download == null) {
alertData = AlertData(
message:
'دانلود موفقیت آمیز نبود',
aLertType: ALertType.error);
}
ActionSheetUtils(context)
.showAlert(alertData);
},
child: Icon(
DidvanIcons.download_solid,
size: 18,
color: Theme.of(context)
.colorScheme
.focusedBorder,
),
),
),
if (message.error != null && message.error!)
Padding(
padding: const EdgeInsets.all(8.0),
@ -613,6 +651,14 @@ class _AiChatPageState extends State<AiChatPage> {
),
),
),
if (state.messages[mIndex].prompts[index]
.text !=
null ||
(state.messages[mIndex].prompts[index]
.text !=
null &&
state.messages[mIndex].prompts[index]
.text!.isNotEmpty))
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(

View File

@ -143,7 +143,7 @@ class AiChatState extends CoreProvier {
messages.last.prompts.add(Prompts(
finished: false,
error: false,
text: '...',
text: '',
role: 'bot',
createdAt: DateTime.now()
.subtract(const Duration(minutes: 210))

View File

@ -281,12 +281,6 @@ class _AiMessageBarState extends State<AiMessageBar> {
.colorScheme
.focused
.withOpacity(0.5)),
child: Center(
child: SpinKitThreeBounce(
color: Theme.of(context).colorScheme.primary,
size: 32,
),
),
),
)
],
@ -310,6 +304,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
Row recorderAndTextMessageHandler(BuildContext context, AiChatState state) {
return Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: _mRecorder!.isPaused
? [
Expanded(
@ -412,6 +407,9 @@ class _AiMessageBarState extends State<AiMessageBar> {
},
)),
),
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Row(children: [
attachmentLayout(state, context),
if (widget.bot.attachmentType!.isNotEmpty)
Padding(
@ -434,6 +432,8 @@ class _AiMessageBarState extends State<AiMessageBar> {
},
),
)
]),
)
],
);
}