import 'dart:io'; import 'package:flutter/material.dart'; import 'package:open_file/open_file.dart'; import 'package:path_provider/path_provider.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/modules/cx_module/chat/chat_provider.dart'; import 'package:test_sa/modules/cx_module/chat/model/chat_attachment_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/app_style/app_text_style.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/sound/sound_player.dart'; import 'chat_api_client.dart'; class ViewAllAttachmentPage extends StatefulWidget { int moduleId; int requestId; ViewAllAttachmentPage({required this.moduleId, required this.requestId, Key? key}) : super(key: key); @override _ViewAllAttachmentPageState createState() { return _ViewAllAttachmentPageState(); } } class _ViewAllAttachmentPageState extends State { List? attachments; @override void initState() { super.initState(); } @override void dispose() { super.dispose(); } Future> viewAllDocuments(int moduleId, int requestId) async { try { attachments ??= await ChatApiClient().viewAllDocuments(moduleId, requestId); return attachments!; } catch (ex) {} return []; } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColor.neutral100, appBar: const DefaultAppBar(title: "Documents"), body: FutureBuilder>( future: viewAllDocuments(widget.moduleId, widget.requestId), builder: (BuildContext context, AsyncSnapshot> snapshot) { bool isLoading = false; if (snapshot.connectionState == ConnectionState.waiting) { isLoading = true; } if (snapshot.hasData && snapshot.data!.isEmpty) { return NoDataFound(message: context.translation.noDataFound).center; } return ListView.separated( itemCount: isLoading ? 9 : snapshot.data!.length, padding: const EdgeInsets.all(16), separatorBuilder: (cxt, index) => 12.height, itemBuilder: (BuildContext context, int index) { if (isLoading) { return Container(height: 48).toShimmer(context: context, isShow: isLoading); } return AttachmentFileViewer(snapshot.data![index]); }, ); }), ); } } class AttachmentFileViewer extends StatelessWidget { ChatAttachment chatAttachment; AttachmentFileViewer(this.chatAttachment, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { return FutureBuilder( future: checkFileInLocalStorage(), builder: (BuildContext context, AsyncSnapshot snapshot) { bool isImage = chatAttachment.storedFileName!.split(".").last.toLowerCase() == "png" || chatAttachment.storedFileName!.split(".").last.toLowerCase() == "jpg" || chatAttachment.storedFileName!.split(".").last.toLowerCase() == "jpeg"; bool isPdf = chatAttachment.storedFileName!.split(".").last.toLowerCase() == "pdf"; bool isExcel = chatAttachment.storedFileName!.split(".").last.toLowerCase() == "xlsx"; bool isAudio = chatAttachment.storedFileName!.split(".").last.toLowerCase() == "m4a" || chatAttachment.storedFileName!.split(".").last.toLowerCase() == "mp3"; bool isLoading = snapshot.connectionState == ConnectionState.waiting; Widget widget; if (isLoading) { if (isAudio) { return Container( width: double.infinity, height: 48, decoration: ShapeDecoration( color: AppColor.background(context), shape: RoundedRectangleBorder( side: BorderSide(width: 1, color: (context.isDark ? AppColor.neutral20 : AppColor.neutral30)), borderRadius: BorderRadius.circular(32), ), ), child: SizedBox(width: 24, height: 24, child: const CircularProgressIndicator(color: AppColor.primary10, strokeWidth: 2).center), ); } widget = const SizedBox(width: 24, height: 24, child: CircularProgressIndicator(color: AppColor.primary10, strokeWidth: 2)); } else { if (isImage) { widget = Image.file(snapshot.data!, width: 48, height: 48, fit: BoxFit.contain); } else { widget = Image.asset( "assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png", fit: BoxFit.contain, width: 48, height: 48); } } if (isAudio) { if (snapshot.data == null) { return Text("Failed to load", style: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.red50 : AppColor.red60)); } return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), ), padding: const EdgeInsets.all(8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ASoundPlayer(audio: snapshot.data!.path), 4.height, Text( chatAttachment.createdOn!.toServiceRequestDetailsFormat, style: AppTextStyles.textFieldLabelStyle.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), ).paddingOnly(start: 60), ], )); } return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), ), padding: const EdgeInsets.all(8), child: Row( children: [ ClipRRect(borderRadius: BorderRadius.circular(8.0), child: widget), 12.width, Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( chatAttachment.storedFileName!, style: AppTextStyles.textFieldLabelStyle.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), ), 4.height, Text( chatAttachment.createdOn!.toServiceRequestDetailsFormat, style: AppTextStyles.textFieldLabelStyle.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), ), ], ).expanded ], ), ).onPress(() { if (isImage) { Navigator.of(context).push( MaterialPageRoute( builder: (_) => Scaffold( appBar: const DefaultAppBar(), body: SafeArea( child: InteractiveViewer(child: Image.file(snapshot.data!)).center, ), ), ), ); } else { OpenFile.open(snapshot.data!.path); } }); return Container( width: double.infinity, height: 48, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: Colors.white, ), child: snapshot.connectionState == ConnectionState.waiting ? const SizedBox( height: 24, width: 24, child: CircularProgressIndicator(color: AppColor.primary10, strokeWidth: 2), ).center : snapshot.hasData ? Row( children: [ getImage(snapshot.data!), getFile(context, snapshot.data!), ], ) : const Icon(Icons.broken_image_rounded), ); return Container( width: double.infinity, height: 48, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: Colors.white, ), child: snapshot.connectionState == ConnectionState.waiting ? const SizedBox( height: 24, width: 24, child: CircularProgressIndicator(color: AppColor.primary10, strokeWidth: 2), ).center : snapshot.hasData ? Row( children: [ getImage(snapshot.data!), getFile(context, snapshot.data!), ], ) : const Icon(Icons.broken_image_rounded), ); }); } Widget getFile(BuildContext context, File file) { bool isImage = file.path.split(".").last.toLowerCase() == "png" || file.path.split(".").last.toLowerCase() == "jpg" || file.path.split(".").last.toLowerCase() == "jpeg"; bool isPdf = file.path.split(".").last.toLowerCase() == "pdf"; bool isExcel = file.path.split(".").last.toLowerCase() == "xlsx"; return MaterialButton( padding: EdgeInsets.zero, onPressed: () async { if (isImage) { Navigator.of(context).push( MaterialPageRoute( builder: (_) => Scaffold( appBar: const DefaultAppBar(), body: SafeArea( child: InteractiveViewer(child: Image.file(file)).center, ), ), ), ); } else { OpenFile.open(file.path); } // else { // // if (!await launchUrl(Uri.parse(URLs.getFileUrl(file.path)!), mode: LaunchMode.externalApplication)) { // // Fluttertoast.showToast(msg: "UnExpected Error with file."); // // throw Exception('Could not launch'); // // } // } }, ); } Widget getImage(File file) { bool isImage = file.path.split(".").last.toLowerCase() == "png" || file.path.split(".").last.toLowerCase() == "jpg" || file.path.split(".").last.toLowerCase() == "jpeg"; bool isPdf = file.path.split(".").last.toLowerCase() == "pdf"; bool isExcel = file.path.split(".").last.toLowerCase() == "xlsx"; if (isImage) { return Image.file(file); } return Image.asset("assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png"); } Future checkFileInLocalStorage() async { Directory tempDir = await getTemporaryDirectory(); String tempPath = '${tempDir.path}/${chatAttachment.storedFileName}'; File tempFile = File(tempPath); bool exists = await tempFile.exists(); if (exists) { return tempFile; } else { return downloadFile(); } } Future downloadFile() async { try { return await ChatApiClient().downloadFileWithHttp(chatAttachment.downloadUrl!, fileName: chatAttachment.storedFileName!, fileTypeDescription: "", fileSource: 0); } catch (ex) { return null; } } }