import 'package:clipboard/clipboard.dart'; import 'package:fbmobile/core/util/formatter_util.dart'; import 'package:flutter/material.dart'; import 'package:flutter_translate/flutter_translate.dart'; import 'package:provider/provider.dart'; import '../../core/enums/viewstate.dart'; import '../../core/models/session.dart'; import '../../core/viewmodels/upload_model.dart'; import '../shared/app_colors.dart'; import '../widgets/centered_error_row.dart'; import '../widgets/my_appbar.dart'; import 'base_view.dart'; class UploadView extends StatelessWidget { static const routeName = '/upload'; const UploadView({super.key}); @override Widget build(BuildContext context) { return BaseView( onModelReady: (model) => model.init(), builder: (context, model, child) => Scaffold( appBar: MyAppBar(title: Text(translate('titles.upload'))), body: _render(model, context))); } bool _isUploadButtonEnabled(UploadModel model) { return model.pasteTextTouched || (model.paths != null && model.paths!.isNotEmpty); } Widget _render(UploadModel model, BuildContext context) { var url = Provider.of(context).url; return model.state == ViewState.busy ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ const CircularProgressIndicator(), (model.stateMessage != null && model.stateMessage!.isNotEmpty ? Text(model.stateMessage!) : Container()) ])) : ListView(children: [ Padding( padding: const EdgeInsets.only(left: 25.0, right: 25.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.only(top: 10.0, bottom: 10.0), child: TextFormField( minLines: 1, maxLines: 7, decoration: InputDecoration( prefixIcon: const Icon( Icons.text_snippet, ), suffixIcon: IconButton( onPressed: () => model.pasteTextController.clear(), icon: const Icon(Icons.clear), ), hintText: translate('upload.text_to_be_pasted'), contentPadding: const EdgeInsets.fromLTRB( 20.0, 10.0, 20.0, 10.0), border: OutlineInputBorder( borderRadius: BorderRadius.circular(32.0)), ), controller: model.pasteTextController)), Padding( padding: const EdgeInsets.only(top: 10.0, bottom: 10.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.end, children: [Text(translate('upload.and_or'))])), Padding( padding: const EdgeInsets.only(top: 10.0, bottom: 10.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.end, children: [ ElevatedButton.icon( icon: const Icon(Icons.file_copy_sharp, color: blueColor), onPressed: () => model.openFileExplorer(), label: Text( translate('upload.open_file_explorer'), )), ElevatedButton.icon( icon: const Icon(Icons.cancel, color: orangeColor), onPressed: model.paths != null && model.paths!.isNotEmpty ? () => model.clearCachedFiles() : null, label: Text( translate('upload.clear_temporary_files'), )), ], )), Padding( padding: const EdgeInsets.only(top: 10.0, bottom: 10.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: [ Checkbox( value: model.createMulti, onChanged: (v) => model.toggleCreateMulti(), ), Text(translate('upload.multipaste')), ])), Padding( padding: const EdgeInsets.only(top: 10.0, bottom: 10.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.end, children: [ ElevatedButton.icon( onPressed: !_isUploadButtonEnabled(model) ? null : () async { Map? items = await model.upload(); String? clipboardContent = model .generatePasteLinks(items, url); if (clipboardContent != null && clipboardContent.isNotEmpty) { FlutterClipboard.copy( clipboardContent) .then((value) { final snackBar = SnackBar( action: SnackBarAction( label: translate( 'upload.dismiss'), textColor: blueColor, onPressed: () { ScaffoldMessenger.of( context) .hideCurrentSnackBar(); }, ), content: Text(translate( 'upload.uploaded')), duration: const Duration(seconds: 10), ); if (context.mounted) { ScaffoldMessenger.of(context) .showSnackBar(snackBar); } }); } }, icon: const Icon(Icons.upload_rounded, color: greenColor), label: Text( translate('upload.upload'), )), ])), model.errorMessage != null && model.errorMessage!.isNotEmpty ? (Padding( padding: const EdgeInsets.only(top: 10.0, bottom: 10.0), child: CenteredErrorRow(model.errorMessage))) : Container(), Builder( builder: (BuildContext context) => model.loadingPath ? const Padding( padding: EdgeInsets.only(bottom: 10.0), child: CircularProgressIndicator(), ) : model.paths != null ? Container( padding: const EdgeInsets.only(bottom: 20.0), height: MediaQuery.of(context).size.height * 0.50, child: ListView.separated( itemCount: model.paths != null && model.paths!.isNotEmpty ? model.paths!.length : 1, itemBuilder: (BuildContext context, int index) { final bool isMultiPath = model.paths != null && model.paths!.isNotEmpty; final String name = (isMultiPath ? model.paths! .map((e) => e.name) .toList()[index] : model.fileName ?? '...'); final size = model.paths!.isNotEmpty ? model.paths! .map((e) => e.size) .toList()[index] .toString() : ''; final path = model.paths!.isNotEmpty ? model.paths! .map((e) => e.path) .toList()[index] .toString() : ''; return Card( child: ListTile( trailing: IconButton( icon: const Icon(Icons.clear, color: orangeColor), onPressed: () { model.deleteIntentFile(path); }), title: Text( "$name (${FormatterUtil.formatBytes(int.parse(size), 2)})", ), subtitle: Text(path), )); }, separatorBuilder: (BuildContext context, int index) => const Divider(), ), ) : Container(), ), ], )) ]); } }