0

The user transmits images that are subsequently uploaded to the server. At the same time, while some images are being uploaded, the user should be able to add other images.

I assume that this needs to be done using STREAM, but I don't understand how.

At the moment I have a UI, a Block, and a request to the server

I also need to get the loading process and display it in the UI, after 100% refresh the screen enter image description here

Bloc

Future<void> _onSetScan(
  SetScanEvent event,
  Emitter<SigningDocumentsState> emit,
) async {
  final picker = ImagePicker();
  try {
    final pickerFile = await picker.pickMultiImage();

    final files = pickerFile.map<UploadFile>(
      (xFile) {
        return UploadFile(
          file: File(xFile.path),
          value: '0',
          type: event.type,
        );
      },
    ).toList();

    final receivedFiles = <UploadFile>[];

    if (files.isNotEmpty) {
      files.forEach((element) {
        final size = element.file.lengthSync() / pow(1024, 2);
        if (size > 5) {
          final msg =
              'Размер файла ${element.file.path.split('/').last} превышает 5 МБ';
          emit(
            SigningDocumentsState(
              status: SigningDocumentsStatus.largeSize,
              scans: state.scans,
              filesUploadQueue: state.filesUploadQueue,
              failureMessage: msg,
            ),
          );
        } else {
          receivedFiles.add(element);
        }
      });

    }
  } on Exception {
    emit(
      SigningDocumentsState(
        status: SigningDocumentsStatus.failure,
        scans: state.scans,
        filesUploadQueue: state.filesUploadQueue,
      ),
    );
  }
}

UI

class Contracts extends StatelessWidget {
  const Contracts({
    required this.title,
    required this.type,
    super.key,
  });

  final String title;
  final String type;

  @override
  Widget build(BuildContext context) {

    final theme = Theme.of(context);
    return BlocBuilder<SigningDocumentsBloc, SigningDocumentsState>(
      builder: (context, state) {
        final contracts =
        state.scans.where((item) => item.type == type).toList();
        print(state.filesUploadQueue);
        return Row(
          children: [
            SizedBox(
              height: theme.spacings.x20,
              width: theme.spacings.x10,
              child: OutlinedButton(
                style: OutlinedButton.styleFrom(
                  backgroundColor: theme.palette.bgQuaternary,
                  padding: EdgeInsets.symmetric(vertical: theme.spacings.x8),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(theme.spacings.x1),
                  ),
                  side: BorderSide.none,
                ),
                onPressed: () {
                  context
                      .read<SigningDocumentsBloc>()
                      .add(SetScanEvent(type: type));
                },
                child: SvgPicture.asset(
                  AssetNames.paperClip,
                ),
              ),
            ),
            SizedBox(
              width: theme.spacings.x3,
            ),
            Expanded(
              child: SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Row(
                  children: [
//here
                    Row(
                      children: state.filesUploadQueue.where((item) => item.type == type).toList().map((contract) {
                        return UploadContainer(
                          value: double.parse(contract.value),
                        );
                      }).toList(),
                    ),
                    Row(
                      children: contracts.map((contract) {
                        return Contract(
                          files: contract,
                          title: title,
                          length: contracts.length,
                          index: contracts.indexOf(contract),
                        );
                      }).toList(),
                    ),
                  ],
                ),
              ),
            ),
          ],
        );
      },
    );
  }
}

UploadContainer

class UploadContainer extends StatelessWidget {
  const UploadContainer({
    required this.value,
    super.key,
  });

  final double value;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Padding(
      padding: EdgeInsets.only(right: theme.spacings.x2),
      child: Container(
        width: theme.spacings.x20,
        height: theme.spacings.x20,
        decoration: BoxDecoration(
          border: Border.all(
            color: theme.palette.buttonDisabled,
          ),
          borderRadius: BorderRadius.circular(
            theme.spacings.x2,
          ),
        ),
        child: Center(
          child: Stack(
            children: [
              Center(
                child: CircularProgressIndicator(
                  backgroundColor: theme.palette.bgPrimary,
                  valueColor: value < 0.51
                      ? AlwaysStoppedAnimation(theme.palette.iconAccentThird)
                      : AlwaysStoppedAnimation(theme.palette.iconAccentSecond),
                  value: value,
                  strokeWidth: theme.spacings.x1,
                ),
              ),
              Center(child: Text('${(value * 100).toInt()} %', style: theme.textTheme.bodySmall,)),
            ],
          ),
        ),
      ),
    );
  }
}

Repository

@override
Future<void> setScan({
  required File file,
  required String type,
}) async {
  final name = file.path.split('/').last;
  final scan = await MultipartFile.fromFile(
    file.path,
    filename: name,
  );
  final formData = FormData.fromMap({
    'files[]': scan,
    'name': name,
    'service': 'test',
    'type': type,
  });
  await _dio.post(
    'https://test-url',
    data: formData,
    onSendProgress: (int sent, int total) {
      final percentage = ((sent/total)*100).toStringAsFixed(2); // 
    },
  );

I tried updating the state without a Stream, but when I add images in addition to those that are being loaded, they disappear from the download queue

Maxim
  • 21
  • 4

0 Answers0