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: