downloadAllFontsZipFile method

Future<void> downloadAllFontsZipFile(
  1. int fontIndex
)

Downloads a zip file containing all fonts for the specified font index.

This method asynchronously downloads a zip file that contains all the fonts associated with the given fontIndex. The downloaded file will be saved locally for later use.

fontIndex - The index of the font set to be downloaded.

Returns a Future that completes when the download is finished.

Implementation

Future<void> downloadAllFontsZipFile(int fontIndex) async {
  // if (GetStorage().read(StorageConstants().isDownloadedCodeV2Fonts) ??
  //     false || state.isDownloadingFonts.value) {
  //   return Future.value();
  // }

  try {
    state.isDownloadingFonts.value = true;
    update(['fontsDownloadingProgress']);

    // تحميل الملف باستخدام http.Client
    final client = http.Client();
    final response = await client.send(http.Request(
      'GET',
      Uri.parse(
          'https://github.com/alheekmahlib/Islamic_database/raw/refs/heads/main/quran_database/Quran%20Font/quran_fonts.zip'),
    ));

    if (response.statusCode != 200) {
      throw Exception('Failed to download ZIP file: ${response.statusCode}');
    }

    // تحديد المسار الذي سيتم حفظ الملف فيه
    final appDir = await getApplicationDocumentsDirectory();
    final fontsDir = Directory('${appDir.path}/quran_fonts');
    if (!await fontsDir.exists()) {
      await fontsDir.create(recursive: true);
    }

    // حفظ ملف ZIP إلى التطبيق
    final zipFile = File('${appDir.path}/quran_fonts.zip');
    final fileSink = zipFile.openWrite();

    // حجم الملف الإجمالي
    final contentLength = response.contentLength ?? 0;
    int totalBytesDownloaded = 0;

    // متابعة التدفق وكتابة البيانات في الملف مع حساب نسبة التحميل
    response.stream.listen(
      (List<int> chunk) {
        totalBytesDownloaded += chunk.length;
        fileSink.add(chunk);
        state.isDownloadingFonts.value = true;
        // حساب نسبة التحميل
        double progress = totalBytesDownloaded / contentLength * 100;
        state.fontsDownloadProgress.value = progress;
        // log('Download progress: ${progress.toStringAsFixed(2)}%');
        update(['fontsDownloadingProgress']);
      },
      onDone: () async {
        await fileSink.flush();
        await fileSink.close();

        // فك ضغط الـ ZIP بعد إغلاق الملف بنجاح
        try {
          // التحقق من أن الملف تم تنزيله بالكامل
          final zipFileSize = await zipFile.length();
          log('Downloaded ZIP file size: $zipFileSize bytes');

          if (zipFileSize == 0) {
            throw Exception('Downloaded ZIP file is empty');
          }

          // فك ضغط الـ ZIP
          final bytes = zipFile.readAsBytesSync();
          final archive = ZipDecoder().decodeBytes(bytes);

          if (archive.isEmpty) {
            throw FormatException(
                'Failed to extract ZIP file: Archive is empty');
          }

          // استخراج الملفات إلى مجلد الخطوط
          for (final file in archive) {
            final filename = '${fontsDir.path}/${file.name}';
            if (file.isFile) {
              final outFile = File(filename);
              await outFile.create(recursive: true);
              await outFile.writeAsBytes(file.content as List<int>);
              // log('Extracted file: $filename'); // سجل لاستخراج الملف
            } else {
              log('Skipped directory: ${file.name}');
            }
          }

          // تحقق من وجود الملفات في المجلد
          final files = await fontsDir.list().toList();
          if (files.isEmpty) {
            log('No files found in fontsDir after extraction');
          } else {
            log('Files in fontsDir after extraction: ${files.map((file) => file.path).join(', ')}');
          }
          await QuranCtrl.instance.loadFontsQuran();
          // حفظ حالة التحميل في التخزين المحلي
          GetStorage()
              .write(_StorageConstants().isDownloadedCodeV2Fonts, true);
          state.fontsDownloadedList.add(fontIndex);
          GetStorage().write(_StorageConstants().fontsDownloadedList,
              state.fontsDownloadedList);
          state.isDownloadedV2Fonts.value = true;
          state.isDownloadingFonts.value = false;
          Get.forceAppUpdate();
          // update();
          log('Fonts unzipped successfully');
          // Get.back();
        } catch (e) {
          log('Failed to extract ZIP file: $e');
        }
      },
      onError: (error) {
        log('Error during download: $error');
        client.close();
      },
      cancelOnError: true,
    );
  } catch (e) {
    log('Failed to Download Code_v2 fonts: $e');
  }

  state.isDownloadingFonts.value = false;
  update(['fontsDownloadingProgress']);
}