You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tangheem/lib/ui/screens/pdf_viewer_screen.dart

273 lines
10 KiB
Dart

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<PdfListScreen> {
List<ContentInfoDataModel> contentList;
List<ContentInfoDataModel> haqooqAlMosasa;
@override
void initState() {
super.initState();
haqooqAlMosasa = AppState().haqooqAlMosasa;
getPdfs();
}
void getPdfs() async {
Utils.showLoading(context);
try {
List<ContentInfoModel> 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<bool> _requestStoragePermission() async {
Map<Permission, PermissionStatus> 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<UriPermission> _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<SfPdfViewerState> _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
);
}
}