From 0c5384441a7a5c8fe46668bed56bcfb8226a7e9e Mon Sep 17 00:00:00 2001 From: Varakh Date: Tue, 2 Feb 2021 18:17:48 +0100 Subject: [PATCH] Copy uploaded paste links to clipboard --- CHANGELOG.md | 4 +++ android/app/src/main/AndroidManifest.xml | 1 + android/fastlane/buildAndroidDebug.sh | 8 +++++ assets/i18n/en.json | 2 ++ lib/core/models/rest/uploaded_multi.dart | 20 ++++++++++++ .../models/rest/uploaded_multi_response.dart | 22 +++++++++++++ lib/core/repositories/file_repository.dart | 4 ++- lib/core/viewmodels/upload_model.dart | 10 ++++-- lib/ui/views/upload_view.dart | 31 ++++++++++++++++++- pubspec.yaml | 3 +- 10 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 CHANGELOG.md create mode 100755 android/fastlane/buildAndroidDebug.sh create mode 100644 lib/core/models/rest/uploaded_multi.dart create mode 100644 lib/core/models/rest/uploaded_multi_response.dart diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c595851 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +# CHANGELOG + +## 1.0.0+1 +* Initial release \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1a53060..af25218 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -27,4 +27,5 @@ android:name="flutterEmbedding" android:value="2" /> + diff --git a/android/fastlane/buildAndroidDebug.sh b/android/fastlane/buildAndroidDebug.sh new file mode 100755 index 0000000..cfd4587 --- /dev/null +++ b/android/fastlane/buildAndroidDebug.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +cd ../../; +flutter clean && \ +flutter pub get && +flutter packages pub run build_runner build --delete-conflicting-outputs; + +flutter build apk --debug; \ No newline at end of file diff --git a/assets/i18n/en.json b/assets/i18n/en.json index 0af637b..db65a25 100644 --- a/assets/i18n/en.json +++ b/assets/i18n/en.json @@ -31,6 +31,8 @@ "upload": "Upload", "uploading_now": "Uploading...", "file_explorer_open": "Selecting files...", + "uploaded": "Uploaded! Copied links to clipboard.", + "dismiss": "Dismiss", "multipaste": "multipaste", "errors": { "not_found": "Not found" diff --git a/lib/core/models/rest/uploaded_multi.dart b/lib/core/models/rest/uploaded_multi.dart new file mode 100644 index 0000000..26c52bc --- /dev/null +++ b/lib/core/models/rest/uploaded_multi.dart @@ -0,0 +1,20 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'uploaded_multi.g.dart'; + +@JsonSerializable() +class UploadedMulti { + @JsonKey(required: true) + final String url; + + @JsonKey(required: true, name: "url_id") + final String urlId; + + UploadedMulti({this.url, this.urlId}); + + // JSON Init + factory UploadedMulti.fromJson(Map json) => _$UploadedMultiFromJson(json); + + // JSON Export + Map toJson() => _$UploadedMultiToJson(this); +} diff --git a/lib/core/models/rest/uploaded_multi_response.dart b/lib/core/models/rest/uploaded_multi_response.dart new file mode 100644 index 0000000..0ba806d --- /dev/null +++ b/lib/core/models/rest/uploaded_multi_response.dart @@ -0,0 +1,22 @@ +import 'package:json_annotation/json_annotation.dart'; + +import 'uploaded_multi.dart'; + +part 'uploaded_multi_response.g.dart'; + +@JsonSerializable() +class UploadedMultiResponse { + @JsonKey(required: true) + final String status; + + @JsonKey(required: true) + final UploadedMulti data; + + UploadedMultiResponse({this.status, this.data}); + + // JSON Init + factory UploadedMultiResponse.fromJson(Map json) => _$UploadedMultiResponseFromJson(json); + + // JSON Export + Map toJson() => _$UploadedMultiResponseToJson(this); +} diff --git a/lib/core/repositories/file_repository.dart b/lib/core/repositories/file_repository.dart index 5363852..6a233b8 100644 --- a/lib/core/repositories/file_repository.dart +++ b/lib/core/repositories/file_repository.dart @@ -6,6 +6,7 @@ import '../models/rest/config.dart'; import '../models/rest/config_response.dart'; import '../models/rest/history.dart'; import '../models/rest/history_response.dart'; +import '../models/rest/uploaded_multi_response.dart'; import '../models/rest/uploaded_response.dart'; import '../services/api.dart'; @@ -42,6 +43,7 @@ class FileRepository { multiPasteIds.putIfAbsent("ids[${ids.indexOf(element) + 1}]", () => element); }); - await _api.post('/file/create_multipaste', fields: multiPasteIds); + var response = await _api.post('/file/create_multipaste', fields: multiPasteIds); + return UploadedMultiResponse.fromJson(json.decode(response.body)); } } diff --git a/lib/core/viewmodels/upload_model.dart b/lib/core/viewmodels/upload_model.dart index 3b80fd1..4bfbf73 100644 --- a/lib/core/viewmodels/upload_model.dart +++ b/lib/core/viewmodels/upload_model.dart @@ -12,6 +12,7 @@ import '../enums/viewstate.dart'; import '../error/rest_service_exception.dart'; import '../error/service_exception.dart'; import '../models/rest/rest_error.dart'; +import '../models/rest/uploaded_multi_response.dart'; import '../models/rest/uploaded_response.dart'; import '../services/file_service.dart'; import '../util/logger.dart'; @@ -73,10 +74,11 @@ class UploadModel extends BaseModel { setState(ViewState.Idle); } - void upload() async { + Future> upload() async { setState(ViewState.Busy); setStateMessage(translate('upload.uploading_now')); + List uploadedPasteIds = []; try { List files; Map additionalFiles; @@ -91,14 +93,17 @@ class UploadModel extends BaseModel { } UploadedResponse response = await _fileService.upload(files, additionalFiles); + uploadedPasteIds.addAll(response.data.ids); if (createMulti && response.data.ids.length > 1) { - await _fileService.createMulti(response.data.ids); + UploadedMultiResponse multiResponse = await _fileService.createMulti(response.data.ids); + uploadedPasteIds.add(multiResponse.data.urlId); } clearCachedFiles(); _pasteTextController.clear(); errorMessage = null; + return uploadedPasteIds; } catch (e) { if (e is RestServiceException) { if (e.statusCode == HttpStatus.notFound) { @@ -132,6 +137,7 @@ class UploadModel extends BaseModel { setStateMessage(null); setState(ViewState.Idle); + return null; } @override diff --git a/lib/ui/views/upload_view.dart b/lib/ui/views/upload_view.dart index 4c558e4..5751cef 100644 --- a/lib/ui/views/upload_view.dart +++ b/lib/ui/views/upload_view.dart @@ -1,7 +1,10 @@ +import 'package:clipboard/clipboard.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'; @@ -13,6 +16,8 @@ class UploadView extends StatelessWidget { @override Widget build(BuildContext context) { + var url = Provider.of(context).url; + return BaseView( builder: (context, model, child) => Scaffold( appBar: MyAppBar(title: Text(translate('titles.upload'))), @@ -96,7 +101,31 @@ class UploadView extends StatelessWidget { borderRadius: BorderRadius.circular(24), ), color: primaryAccentColor, - onPressed: () => model.upload(), + onPressed: () async { + List items = await model.upload(); + + if (items != null) { + var clipboardContent = ''; + items.forEach((element) { + clipboardContent += '$url/$element\n'; + }); + + FlutterClipboard.copy(clipboardContent).then((value) { + final snackBar = SnackBar( + action: SnackBarAction( + label: translate('upload.dismiss'), + textColor: Colors.blue, + onPressed: () { + Scaffold.of(context).hideCurrentSnackBar(); + }, + ), + content: Text(translate('upload.uploaded')), + duration: Duration(seconds: 10), + ); + Scaffold.of(context).showSnackBar(snackBar); + }); + } + }, icon: Icon(Icons.upload_rounded, color: Colors.green), label: Text( translate('upload.upload'), diff --git a/pubspec.yaml b/pubspec.yaml index 6170b6a..2cdd7bc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,7 +25,7 @@ dependencies: flutter_translate: 1.6.0 provider: 4.3.3 provider_architecture: 1.1.1+1 - get_it: 3.1.0 # major changes in 4.x + get_it: 3.1.0 # major changes > 3 logger: 0.9.4 shared_preferences: 0.5.12+4 http: 0.12.2 @@ -36,6 +36,7 @@ dependencies: expandable: 4.1.4 share: 0.6.5+4 file_picker: 2.1.6 + clipboard: 0.1.2+8 dev_dependencies: flutter_test: