Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App freezes on cancel download #2020

Closed
abhinavsinghring opened this issue Nov 1, 2023 · 1 comment
Closed

App freezes on cancel download #2020

abhinavsinghring opened this issue Nov 1, 2023 · 1 comment

Comments

@abhinavsinghring
Copy link

I'm trying to download a file and show progress in a dialog and it contains cancel button. But when I try to click on cancel the button app freezes and I get an error and need to hot restart to open app again. Also complete file downloads.

This is the error

#0      CancelToken.cancel (package:dio/src/cancel_token.dart:42:43)
#1      Downloader.build.<anonymous closure>.<anonymous closure> (package:paperbook/Services/Downloader/downloader_dialog.dart:61:50)
#2      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1154:21)
#3      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:275:24)
#4      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:654:11)
#5      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:311:5)
#6      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:244:7)
#7      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:630:9)
#8      PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#9      PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#10     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:625:13)
#11     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#12     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#13     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:488:19)
#14     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:468:22)
#15     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:333:11)
#16     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:413:7)
#17     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:376:5)
#18     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:323:7)
#19     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:292:9)
#20     _invoke1 (dart:ui/hooks.dart:186:13)
#21     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:424:7)
#22     _dispatchPointerDataPacket (dart:ui/hooks.dart:119:31)
)

This is the downloader dialog code

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:paperbook/Constants/size_constant.dart';
import 'package:paperbook/Services/Downloader/Controller/downloader_controller.dart';
import 'package:paperbook/Widgets/SnackBar/snackbar_controller.dart';
import 'package:paperbook/Widgets/Text/custom_text.dart';

import '../../Screens/Downloads/download_screen.dart';

class Downloader extends StatelessWidget {
  const Downloader({
    super.key, 
    required this.docurl, 
    required this.doctitle,
    this.documentBytes
  });

  final String docurl, doctitle;
  final List<int>? documentBytes;

  @override
  Widget build(BuildContext context) {
    final DownloaderController downloaderController = Get.put(DownloaderController());
    final SnackBarController snackBarController = Get.put(SnackBarController());
    downloaderController.startDownloading(
      documentBytes,
      doctitle,
      docurl,
      context,
      snackBarController
    );
    return Obx(
      ()=> downloaderController.downloading.value? AlertDialog(
        clipBehavior: Clip.antiAlias,
        shape:  RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(20),
        ),
        backgroundColor: Theme.of(context).colorScheme.secondary,
        elevation: 0,
        contentPadding: EdgeInsets.all(mainpadding/2),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SizedBox(height: mainpadding),
            CircularProgressIndicator(color: Theme.of(context).colorScheme.primary, strokeWidth: 3,),
            SizedBox(height: mainpadding*1.5),
            TextWidget(
              text: "Downloading: ${downloaderController.progress}%",
              weight: FontWeight.w500,
              size: buttonSize
            ),
            TextButton(
              child: TextWidget(
                text: 'Cancel', 
                color: Theme.of(context).colorScheme.primary, 
                size: paraSize18,
                weight: FontWeight.w500,
              ),
              onPressed: () async {
                downloaderController.cancelToken.cancel('User cancelled download.');
                Get.back();
              },
            ),
          ],
        ),
      ) : 
      AlertDialog(
        clipBehavior: Clip.antiAlias,
        shape:  RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20),
          ),
        backgroundColor: Theme.of(context).colorScheme.secondary,
        elevation: 0,
        title: TextWidget(
          text: 'Awesome! Your file has been downloaded.',
          size: buttonSize,
          weight: FontWeight.w500,
          center: true,
        ),
        actions: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              TextButton(
                child: TextWidget(
                  text: 'Go to Downloads', 
                  color: Theme.of(context).colorScheme.primary, 
                  size: paraSize18,
                  weight: FontWeight.w500,  
                ),
                onPressed: () async {
                  await Get.to(
                    () => const DownloadsPage(),
                    transition: Transition.cupertino,
                    duration: const Duration(milliseconds: 500),
                    popGesture: true,
                    gestureWidth: (context) {
                      double width =
                          MediaQuery.of(context).size.width;
                      return width;
                    },
                  );
                },
              ),
              TextButton(
                child: TextWidget(
                  text: 'Close', 
                  color: Theme.of(context).colorScheme.primary, 
                  size: paraSize18,
                  weight: FontWeight.w500,
                ),
                onPressed: () {
                  Get.back();
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}

And this is controller code

import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:paperbook/Screens/PdfReader/pdf_reader_screen.dart';
import 'package:paperbook/Widgets/SnackBar/content_type.dart';
import 'package:paperbook/Widgets/SnackBar/snackbar_controller.dart';
import 'package:path_provider/path_provider.dart';

class DownloaderController extends GetxController {
  static DownloaderController get instance => Get.find();

  var progress = '0'.obs;
  RxBool downloading = false.obs;
  final CancelToken cancelToken = CancelToken();

  Future<void> startDownloading(List<int>? documentBytes,String doctitle, String docurl, BuildContext context, SnackBarController snackBarController) async {

    downloading.value = true;

    final dir = await getApplicationDocumentsDirectory();                           
    // ignore: unnecessary_null_comparison
    if(dir != null){
      String savename = doctitle;
      String savePath = "${dir.path}/PaperBook/$savename.pdf";
    //   File file = File(savePath);
    //   //Write the PDF data retrieved from the SfPdfViewer.
    //   await file.writeAsBytes(documentBytes!, flush: true).then((value) {
    //       downloading.value = false;
    //       // interstitiaal advertisement
    //     }
    //   ).onError((error, stackTrace) {
    //     Get.back();
    //     snackBarController.showCustomSnackBar(
    //       "Error", 
    //       "Something went wrong!", 
    //       ContentTypeC.failure
    //     );
    // });

      try {
        await Dio().download(
          docurl, 
          savePath,
          onReceiveProgress: (received, total) {
            if (total != -1) {
              progress.value = ((received / total) * 100).toInt().toString();
            }
          },
          deleteOnError: true,
          cancelToken: cancelToken
        ).then((_) {
            downloading.value = false;
            Navigator.push(
              context,
              CupertinoPageRoute(
                builder: (context) => PdfReaderPage(
                  url: savePath, 
                  name: savename,
                  isFile: true,
                ),
              )
            );
            // interstitiaal advertisement
          },
        );       
      // ignore: unused_catch_clause
      } on DioError catch (e) {
        Get.back();
        snackBarController.showCustomSnackBar(
          "Error", 
          "Something went wrong!", 
          ContentTypeC.failure
        );
      }
    }    
  }
}
@github-actions github-actions bot closed this as completed Nov 1, 2023
Copy link
Contributor

github-actions bot commented Nov 1, 2023

@abhinavsinghring Infra and blank issues are only available for moderators. You're apperantly using the wrong issue template.

Infra 和空白 issue 仅供管理人员使用,请选择其他 issue 模板创建 issue。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant