import 'package:cross_file/cross_file.dart' show XFile; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:imagini/bloc/bloc-prov.dart'; import 'package:imagini/screens/upload/upload-bloc.dart'; import 'package:tus_client/tus_client.dart'; import 'package:url_launcher/url_launcher.dart'; class UploadScreen extends StatefulWidget { @override _UploadScreenState createState() => _UploadScreenState(); } class _UploadScreenState extends State { UploadBloc exampleBloc; double _progress = 0; XFile _file; TusClient _client; Uri _fileUrl; @override void initState() { super.initState(); exampleBloc = UploadBloc(); } @override void dispose() { exampleBloc.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return BlocProvider( bloc: exampleBloc, child: PlatformScaffold( appBar: PlatformAppBar( title: Text('Uploads'), cupertino: (_, __) => CupertinoNavigationBarData( // Issue with cupertino where a bar with no transparency // will push the list down. Adding some alpha value fixes it (in a hacky way) backgroundColor: Colors.lightGreen.withAlpha(254), ), ), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ SizedBox(height: 12), Padding( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 2), child: Text( "This demo uses TUS client to upload a file", style: TextStyle(fontSize: 18), ), ), Padding( padding: const EdgeInsets.all(6), child: Card( color: Colors.teal, child: InkWell( onTap: () async { _file = await _getXFile(await FilePicker.platform.pickFiles()); setState(() { _progress = 0; _fileUrl = null; }); }, child: Container( padding: EdgeInsets.all(20), child: Column( children: [ Icon(Icons.cloud_upload, color: Colors.white, size: 60), Text( "Upload a file", style: TextStyle(fontSize: 25, color: Colors.white), ), ], ), ), ), ), ), Padding( padding: const EdgeInsets.all(8), child: Row( children: [ Expanded( child: RaisedButton( onPressed: _file == null ? null : () async { // Create a client print("Create a client"); _client = TusClient( Uri.parse("https://master.tus.io/files/"), _file, store: TusMemoryStore(), ); print("Starting upload"); await _client.upload( onComplete: () async { print("Completed!"); setState(() => _fileUrl = _client.uploadUrl); }, onProgress: (progress) { print("Progress: $progress"); setState(() => _progress = progress); }, ); }, child: Text("Upload"), ), ), SizedBox(width: 8), Expanded( child: RaisedButton( onPressed: _progress == 0 ? null : () async { _client.pause(); }, child: Text("Pause"), ), ), ], ), ), Stack( children: [ Container( margin: const EdgeInsets.all(8), padding: const EdgeInsets.all(1), color: Colors.grey, width: double.infinity, child: Text(" "), ), FractionallySizedBox( widthFactor: _progress / 100, child: Container( margin: const EdgeInsets.all(8), padding: const EdgeInsets.all(1), color: Colors.green, child: Text(" "), ), ), Container( margin: const EdgeInsets.all(8), padding: const EdgeInsets.all(1), width: double.infinity, child: Text("Progress: ${_progress.toStringAsFixed(1)}%"), ), ], ), GestureDetector( onTap: _progress != 100 ? null : () async { await launch(_fileUrl.toString()); }, child: Container( color: _progress == 100 ? Colors.green : Colors.grey, padding: const EdgeInsets.all(8.0), margin: const EdgeInsets.all(8.0), child: Text(_progress == 100 ? "Link to view:\n $_fileUrl" : "-"), ), ), ], ), ), ), ); } Future _getXFile(FilePickerResult result) async { if (result != null) { final chosenFile = result.files.first; if (chosenFile.path != null) { // Android, iOS, Desktop return XFile(chosenFile.path); } else { // Web return XFile.fromData( chosenFile.bytes, name: chosenFile.name, ); } } return null; } }