Skip to content

Run saveDocument() in an isolate #2078

Closed as not planned
Closed as not planned
@patricknicolosi

Description

@patricknicolosi

Use case

The saveDocument function takes a long time to execute for more complex documents, it would be convenient to find a way to execute this function in an Isolate.

Currently, it is not possible to pass PdfViewerController to an isolate to run saveDocument() separately

Currently code stucks to show loading in showLoadingDialog.

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gym_manager_document_filler/helpers/ftp_helper.dart';
import 'package:gym_manager_document_filler/screens/home/home_screen.dart';
import 'package:gym_manager_document_filler/utils/assets_utils.dart';
import 'package:gym_manager_document_filler/utils/ui_utils.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';
import 'package:path_provider/path_provider.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';

class PdfViewer extends StatelessWidget {
  final String documentAssetPath;
  PdfViewer(this.documentAssetPath, {super.key});

  final PdfViewerController _pdfViewerController = PdfViewerController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton.extended(
          icon: const Icon(LucideIcons.save),
          label: const Text("Salva"),
          onPressed: () async {
            await _exportPdf(
                context: context,
                fileName: AssetsUtils.formatAssetsName(
                    documentAssetPath.split('/')[2]));
          }),
      body: SafeArea(
        child: Stack(
          children: [
            SfPdfViewer.asset(
              documentAssetPath,
              controller: _pdfViewerController,
              canShowPageLoadingIndicator: true,
              initialZoomLevel: 0.6,
            ),
            Padding(
              padding: const EdgeInsets.all(50),
              child: IconButton.filledTonal(
                  icon: const Icon(LucideIcons.chevronLeft),
                  onPressed: () {
                    Navigator.pop(context);
                  }),
            )
          ],
        ),
      ),
    );
  }

  Future _exportPdf(
      {required BuildContext context, required String fileName}) async {
    UiUtils.showLoadingDialog(context: context);
    await Future.delayed(const Duration(seconds: 1));
    try {
      File filledPdf = await _createPdfFile(fileName: fileName);
      await FtpHelper.getIstance()
          .upload(fileName: "$fileName.pdf", file: filledPdf);
      filledPdf.deleteSync();
      _showSuccessUpload(context);
    } catch (e) {
      Navigator.pop(context);
      _showErrorUpload(context, e);
      return;
    }
  }

  Future<File> _createPdfFile({required String fileName}) async {
    try {
      Directory dir = await getApplicationSupportDirectory();
      File filledPdf = File("${dir.path}/$fileName.pdf");
      filledPdf.writeAsBytesSync(await _pdfViewerController.saveDocument());
      return filledPdf;
    } catch (e) {
      throw Exception(e);
    }
  }

  void _showErrorUpload(BuildContext context, Object e) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      backgroundColor: Colors.red,
      content: Text(
        e.toString(),
        style: const TextStyle(color: Colors.white),
      ),
      behavior: SnackBarBehavior.floating,
      margin: const EdgeInsets.all(10),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
    ));
    Navigator.of(context).pushAndRemoveUntil(
        MaterialPageRoute(builder: (context) => const HomeScreen()),
        (Route<dynamic> route) => false);
  }

  void _showSuccessUpload(BuildContext context) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      backgroundColor: Colors.green,
      content: const Text(
        "Modulo salvato con successo",
        style: TextStyle(color: Colors.white),
      ),
      behavior: SnackBarBehavior.floating,
      margin: const EdgeInsets.all(10),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
    ));
    Navigator.of(context).pushAndRemoveUntil(
        MaterialPageRoute(builder: (context) => const HomeScreen()),
        (Route<dynamic> route) => false);
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      close