import 'dart:async'; import 'dart:io'; import 'dart:ui'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:shared_storage/shared_storage.dart'; import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; import 'package:tangheem/api/tangheem_user_api_client.dart'; import 'package:tangheem/app_state/app_state.dart'; import 'package:tangheem/classes/colors.dart'; import 'package:tangheem/classes/consts.dart'; import 'package:tangheem/classes/utils.dart'; import 'package:tangheem/extensions/int_extensions.dart'; import 'package:tangheem/extensions/string_extensions.dart'; import 'package:tangheem/extensions/widget_extensions.dart'; import 'package:tangheem/models/content_info_model.dart'; import 'package:tangheem/ui/misc/no_data_ui.dart'; import 'package:tangheem/widgets/new/CommonHeader.dart'; class PdfListScreen extends StatefulWidget { static const String routeName = "/tangheem_pdf"; PdfListScreen({Key key}) : super(key: key); @override _PdfListScreenState createState() { return _PdfListScreenState(); } } class _PdfListScreenState extends State { List contentList; List haqooqAlMosasa; @override void initState() { super.initState(); haqooqAlMosasa = AppState().haqooqAlMosasa; getPdfs(); } void getPdfs() async { Utils.showLoading(context); try { List responseList = await Future.wait([TangheemUserApiClient().getContentInfo(8), if (haqooqAlMosasa == null) TangheemUserApiClient().getContentInfo(1)]); contentList = responseList[0].data ?? []; if (haqooqAlMosasa == null) { haqooqAlMosasa = responseList[1].data ?? []; AppState().haqooqAlMosasa = haqooqAlMosasa; } } catch (ex) { contentList = []; haqooqAlMosasa = []; if (mounted) Utils.handleException(ex, null); } finally { Utils.hideLoading(context); } setState(() {}); } @override void dispose() { super.dispose(); } void startFileDownload(String url, String fileName) async { try { Utils.showLoading(context); String path = await Utils.getStoragePath(fileName); Utils.downloadFile(ApiConsts.baseUrl + url, path, onResponse: (isSuccess) { Utils.hideLoading(context); if (isSuccess) { Utils.showToast("تم حفظ الملف بنجاح"); } else { Utils.showToast("فشل حفظ الملف ، حاول مرة أخرى"); } }); } catch (ex) { print(ex); Utils.hideLoading(context); } } Future _requestStoragePermission() async { Map statuses = await [Permission.storage].request(); return statuses[Permission.storage].isGranted; } @override Widget build(BuildContext context) { bool isPortrait = MediaQuery.of(context).orientation == Orientation.portrait; Widget _header = SizedBox(height: isPortrait ? null : double.infinity, width: double.infinity, child: CommonHeader("التصفح والتحميل", "assets/icons/new/pdf_bg.jpg", Color(0xffAE8646))); Widget _dataListView = contentList?.isEmpty ?? true ? NoDataUI() : ListView.separated( physics: isPortrait ? const NeverScrollableScrollPhysics() : const AlwaysScrollableScrollPhysics(), shrinkWrap: isPortrait, padding: EdgeInsets.only(left: isPortrait ? 35 : 0, right: isPortrait ? 35 : 24, top: 35, bottom: 0), itemCount: contentList.length, separatorBuilder: (context, index) { return Divider(color: Color(0xffC7C7C7), height: 1, thickness: 1).paddingOnly(top: 14, bottom: 14); }, itemBuilder: (context, index) { return SizedBox( height: 50, child: Row( children: [ SvgPicture.asset( "assets/icons/new/download_pdf.svg", width: 44, height: 50, ).onPress(() async { if (Platform.isAndroid && (await DeviceInfoPlugin().androidInfo).version.sdkInt > 29) { savePdfToAboveAndroid32(contentList[index].exposeFilePath, contentList[index].fileName); } else { if (await _requestStoragePermission()) { startFileDownload(contentList[index].exposeFilePath, contentList[index].fileName); } else { Utils.showToast("يجب أن تعطي الإذن للتنزيل."); } } }), 7.width, ClipRRect( borderRadius: BorderRadius.circular(7), child: Container( height: 50, alignment: Alignment.centerRight, decoration: BoxDecoration( color: Colors.white, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( width: 44, height: 50, alignment: Alignment.center, decoration: BoxDecoration( color: ColorConsts.darkText, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.zoom_out_map_rounded, color: Colors.white), "تصفع".toText(10), ], ), ), Directionality( textDirection: TextDirection.rtl, child: (contentList[index].fileName?.trim() ?? "").toText(18, color: ColorConsts.darkText).paddingOnly(left: 12, right: 12), ).expanded, ], ), ), ).onPress(() { Navigator.pushNamed(context, PdfViewerScreen.routeName, arguments: contentList[index]); }).expanded, ], ), ); }, ); Widget _aboutView = Column( mainAxisSize: MainAxisSize.min, children: [ "حقوق الموسوعة".toText(isPortrait ? 13 : 16, color: ColorConsts.greyLightColor), for (ContentInfoDataModel text in haqooqAlMosasa) text.content.toText(13, color: ColorConsts.greyLightColor, textAlign: TextAlign.center) ], ); return SizedBox( height: double.infinity, child: isPortrait ? SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), padding: EdgeInsets.only(bottom: 140), child: Column( children: [ _header, contentList == null ? SizedBox() : _dataListView, if ((haqooqAlMosasa?.length ?? 0) > 0) _aboutView.paddingOnly(left: 35, right: 35, top: 35), ], ), ) : Row( children: [ Expanded(child: ((haqooqAlMosasa?.length ?? 0) > 0) ? _aboutView.paddingOnly(left: 35, right: isPortrait ? 35 : 24, top: isPortrait ? 35 : 24) : SizedBox(), flex: 3), Expanded(child: contentList == null ? SizedBox() : _dataListView, flex: 3), Expanded(child: _header, flex: 4), ], ), ); } void savePdfToAboveAndroid32(String pathUrl, String fileName) async { List _persistedPermissionUris = await persistedUriPermissions(); if (_persistedPermissionUris.isNotEmpty) { UriPermission permissionUri = _persistedPermissionUris.first; startFileDownloadAboveAndroid32(pathUrl, fileName, permissionUri.uri); } else { Uri selectedDocumentUris = await openDocumentTree(); if (selectedDocumentUris == null) return; savePdfToAboveAndroid32(pathUrl, fileName); } } void startFileDownloadAboveAndroid32(String url, String fileName, Uri persistentUri) async { try { Utils.showLoading(context); //String path = await Utils.getStoragePath(fileName); Utils.downloadFileAboveAndroid32(ApiConsts.baseUrl + url, "path", onResponse: (bytes) async { Utils.hideLoading(context); if (bytes.isNotEmpty) { final documentFile = await persistentUri.toDocumentFile(); final child = await documentFile?.child(fileName); if (child == null) { documentFile?.createFileAsBytes( mimeType: 'application/pdf ', bytes: bytes, displayName: fileName, ); } else { documentFile?.writeToFileAsBytes( bytes: bytes, mode: FileMode.write, ); } Utils.showToast("تم حفظ الملف بنجاح"); } else { Utils.showToast("فشل حفظ الملف ، حاول مرة أخرى"); } }); } catch (ex) { print(ex); Utils.hideLoading(context); } } } class PdfViewerScreen extends StatelessWidget { static const String routeName = "/tangheem_pdf_view"; final ContentInfoDataModel pdfDetail; PdfViewerScreen(this.pdfDetail, {Key key}) : super(key: key); final GlobalKey _pdfViewerKey = GlobalKey(); @override Widget build(BuildContext context) { return SfPdfViewer.network( ApiConsts.baseUrl + pdfDetail.exposeFilePath, key: _pdfViewerKey, canShowScrollHead: false, enableTextSelection: false, enableDocumentLinkAnnotation: false, canShowPaginationDialog: false, canShowScrollStatus: false, pageSpacing: 0, // pageLayoutMode:PdfPageLayoutMode.single ); } }