diff --git a/.drone.yml b/.drone.yml
index a3c4a7e..bcf30e5 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -4,7 +4,7 @@ name: default
steps:
- name: build
- image: cirrusci/flutter:3.3.9
+ image: cirrusci/flutter:3.3.10
commands:
- flutter doctor
- flutter pub get
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d93716a..6920a28 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,10 @@
# CHANGELOG
-## 1.5.2+18
+## 1.6.0+18
+* Fixed input colors in login view when using dark theme
+* Added removal of individual files selected for upload
+* Added size for individual files selected for upload
+* Replaced intent sharing library with `flutter_sharing_intent`
* Added proper linting to project
## 1.5.1+17
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 579db4d..2c6fc11 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -21,46 +21,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 1faf8d4..8e2d676 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -60,7 +60,7 @@
- // TODO follow steps 2) on create share extension (https://pub.dev/packages/receive_sharing_intent)
+ // TODO follow steps on create share extension (https://pub.dev/packages/flutter_sharing_intent)
NSPhotoLibraryUsageDescription
Allow to select photos and upload them via the app
LSApplicationQueriesSchemes
diff --git a/lib/app.dart b/lib/app.dart
index 76efa68..10c33bb 100644
--- a/lib/app.dart
+++ b/lib/app.dart
@@ -18,8 +18,10 @@ import 'ui/shared/app_colors.dart';
import 'ui/views/startup_view.dart';
class MyApp extends StatelessWidget {
- static final _defaultLightColorScheme = ColorScheme.fromSwatch(primarySwatch: myColor, brightness: Brightness.light);
- static final _defaultDarkColorScheme = ColorScheme.fromSwatch(primarySwatch: myColor, brightness: Brightness.dark);
+ static final _defaultLightColorScheme = ColorScheme.fromSwatch(
+ primarySwatch: myColor, brightness: Brightness.light);
+ static final _defaultDarkColorScheme = ColorScheme.fromSwatch(
+ primarySwatch: myColor, brightness: Brightness.dark);
MyApp({super.key}) {
initializeDateFormatting('en');
@@ -33,23 +35,30 @@ class MyApp extends StatelessWidget {
state: LocalizationProvider.of(context).state,
child: StreamProvider(
initialData: null,
- create: (context) => locator().refreshEventController.stream,
+ create: (context) =>
+ locator().refreshEventController.stream,
child: StreamProvider(
initialData: Session.initial(),
- create: (context) => locator().sessionController.stream,
- child: LifeCycleManager(child: DynamicColorBuilder(builder: (lightColorScheme, darkColorScheme) {
+ create: (context) =>
+ locator().sessionController.stream,
+ child: LifeCycleManager(child: DynamicColorBuilder(
+ builder: (lightColorScheme, darkColorScheme) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: translate('app.title'),
builder: (context, child) => Navigator(
key: locator().dialogNavigationKey,
- onGenerateRoute: (settings) => MaterialPageRoute(builder: (context) => DialogManager(child: child)),
+ onGenerateRoute: (settings) => MaterialPageRoute(
+ builder: (context) => DialogManager(child: child)),
),
theme: ThemeData(
useMaterial3: true,
brightness: Brightness.light,
- colorScheme: lightColorScheme ?? _defaultLightColorScheme),
- darkTheme: ThemeData(useMaterial3: true, colorScheme: darkColorScheme ?? _defaultDarkColorScheme),
+ colorScheme:
+ lightColorScheme ?? _defaultLightColorScheme),
+ darkTheme: ThemeData(
+ useMaterial3: true,
+ colorScheme: darkColorScheme ?? _defaultDarkColorScheme),
onGenerateRoute: AppRouter.generateRoute,
navigatorKey: locator().navigationKey,
home: const StartUpView(),
diff --git a/lib/core/manager/dialog_manager.dart b/lib/core/manager/dialog_manager.dart
index b1c14bb..5eb75d0 100644
--- a/lib/core/manager/dialog_manager.dart
+++ b/lib/core/manager/dialog_manager.dart
@@ -31,7 +31,8 @@ class _DialogManagerState extends State {
void _showDialog(DialogRequest request) {
List actions = [];
- if (request.buttonTitleDeny != null && request.buttonTitleDeny!.isNotEmpty) {
+ if (request.buttonTitleDeny != null &&
+ request.buttonTitleDeny!.isNotEmpty) {
Widget denyBtn = TextButton(
child: Text(request.buttonTitleDeny!),
onPressed: () {
diff --git a/lib/core/manager/lifecycle_manager.dart b/lib/core/manager/lifecycle_manager.dart
index b2da48a..09840ed 100644
--- a/lib/core/manager/lifecycle_manager.dart
+++ b/lib/core/manager/lifecycle_manager.dart
@@ -17,10 +17,14 @@ class LifeCycleManager extends StatefulWidget {
_LifeCycleManagerState createState() => _LifeCycleManagerState();
}
-class _LifeCycleManagerState extends State with WidgetsBindingObserver {
+class _LifeCycleManagerState extends State
+ with WidgetsBindingObserver {
final Logger logger = getLogger();
- List servicesToManage = [locator(), locator()];
+ List servicesToManage = [
+ locator(),
+ locator()
+ ];
@override
Widget build(BuildContext context) {
diff --git a/lib/core/models/rest/apikey.dart b/lib/core/models/rest/apikey.dart
index 0e3d8bf..2386259 100644
--- a/lib/core/models/rest/apikey.dart
+++ b/lib/core/models/rest/apikey.dart
@@ -15,7 +15,11 @@ class ApiKey {
final String? comment;
- ApiKey({required this.key, required this.created, required this.accessLevel, this.comment});
+ ApiKey(
+ {required this.key,
+ required this.created,
+ required this.accessLevel,
+ this.comment});
// JSON Init
factory ApiKey.fromJson(Map json) => _$ApiKeyFromJson(json);
diff --git a/lib/core/models/rest/apikeys.dart b/lib/core/models/rest/apikeys.dart
index d8e6191..f6b30a5 100644
--- a/lib/core/models/rest/apikeys.dart
+++ b/lib/core/models/rest/apikeys.dart
@@ -12,7 +12,8 @@ class ApiKeys {
ApiKeys({required this.apikeys});
// JSON Init
- factory ApiKeys.fromJson(Map json) => _$ApiKeysFromJson(json);
+ factory ApiKeys.fromJson(Map json) =>
+ _$ApiKeysFromJson(json);
// JSON Export
Map toJson() => _$ApiKeysToJson(this);
diff --git a/lib/core/models/rest/apikeys_response.dart b/lib/core/models/rest/apikeys_response.dart
index 138642a..a2bd8f8 100644
--- a/lib/core/models/rest/apikeys_response.dart
+++ b/lib/core/models/rest/apikeys_response.dart
@@ -15,7 +15,8 @@ class ApiKeysResponse {
ApiKeysResponse({required this.status, required this.data});
// JSON Init
- factory ApiKeysResponse.fromJson(Map json) => _$ApiKeysResponseFromJson(json);
+ factory ApiKeysResponse.fromJson(Map json) =>
+ _$ApiKeysResponseFromJson(json);
// JSON Export
Map toJson() => _$ApiKeysResponseToJson(this);
diff --git a/lib/core/models/rest/config_response.dart b/lib/core/models/rest/config_response.dart
index 7e26ea0..d25ac7d 100644
--- a/lib/core/models/rest/config_response.dart
+++ b/lib/core/models/rest/config_response.dart
@@ -15,7 +15,8 @@ class ConfigResponse {
ConfigResponse({required this.status, required this.data});
// JSON Init
- factory ConfigResponse.fromJson(Map json) => _$ConfigResponseFromJson(json);
+ factory ConfigResponse.fromJson(Map json) =>
+ _$ConfigResponseFromJson(json);
// JSON Export
Map toJson() => _$ConfigResponseToJson(this);
diff --git a/lib/core/models/rest/create_apikey_response.dart b/lib/core/models/rest/create_apikey_response.dart
index 9614676..55efe99 100644
--- a/lib/core/models/rest/create_apikey_response.dart
+++ b/lib/core/models/rest/create_apikey_response.dart
@@ -13,7 +13,8 @@ class CreateApiKeyResponse {
CreateApiKeyResponse({required this.status, required this.data});
// JSON Init
- factory CreateApiKeyResponse.fromJson(Map json) => _$CreateApiKeyResponseFromJson(json);
+ factory CreateApiKeyResponse.fromJson(Map json) =>
+ _$CreateApiKeyResponseFromJson(json);
// JSON Export
Map toJson() => _$CreateApiKeyResponseToJson(this);
diff --git a/lib/core/models/rest/history.dart b/lib/core/models/rest/history.dart
index 602a290..94ec42d 100644
--- a/lib/core/models/rest/history.dart
+++ b/lib/core/models/rest/history.dart
@@ -19,7 +19,8 @@ class History {
History({required this.items, required this.multipasteItems, this.totalSize});
// JSON Init
- factory History.fromJson(Map json) => _$HistoryFromJson(json);
+ factory History.fromJson(Map json) =>
+ _$HistoryFromJson(json);
// JSON Export
Map toJson() => _$HistoryToJson(this);
diff --git a/lib/core/models/rest/history_item.dart b/lib/core/models/rest/history_item.dart
index 17744ba..54364e1 100644
--- a/lib/core/models/rest/history_item.dart
+++ b/lib/core/models/rest/history_item.dart
@@ -23,7 +23,8 @@ class HistoryItem {
this.thumbnail});
// JSON Init
- factory HistoryItem.fromJson(Map json) => _$HistoryItemFromJson(json);
+ factory HistoryItem.fromJson(Map json) =>
+ _$HistoryItemFromJson(json);
// JSON Export
Map toJson() => _$HistoryItemToJson(this);
diff --git a/lib/core/models/rest/history_multipaste_item.dart b/lib/core/models/rest/history_multipaste_item.dart
index cde11dc..1b56dcd 100644
--- a/lib/core/models/rest/history_multipaste_item.dart
+++ b/lib/core/models/rest/history_multipaste_item.dart
@@ -15,7 +15,8 @@ class HistoryMultipasteItem {
HistoryMultipasteItem(this.items, {required this.date, required this.urlId});
// JSON Init
- factory HistoryMultipasteItem.fromJson(Map json) => _$HistoryMultipasteItemFromJson(json);
+ factory HistoryMultipasteItem.fromJson(Map json) =>
+ _$HistoryMultipasteItemFromJson(json);
// JSON Export
Map toJson() => _$HistoryMultipasteItemToJson(this);
diff --git a/lib/core/models/rest/history_multipaste_item_entry.dart b/lib/core/models/rest/history_multipaste_item_entry.dart
index 209fb2e..fb37fb2 100644
--- a/lib/core/models/rest/history_multipaste_item_entry.dart
+++ b/lib/core/models/rest/history_multipaste_item_entry.dart
@@ -9,7 +9,8 @@ class HistoryMultipasteItemEntry {
HistoryMultipasteItemEntry({required this.id});
// JSON Init
- factory HistoryMultipasteItemEntry.fromJson(Map json) => _$HistoryMultipasteItemEntryFromJson(json);
+ factory HistoryMultipasteItemEntry.fromJson(Map json) =>
+ _$HistoryMultipasteItemEntryFromJson(json);
// JSON Export
Map toJson() => _$HistoryMultipasteItemEntryToJson(this);
diff --git a/lib/core/models/rest/history_response.dart b/lib/core/models/rest/history_response.dart
index bfc3548..fa8f904 100644
--- a/lib/core/models/rest/history_response.dart
+++ b/lib/core/models/rest/history_response.dart
@@ -15,7 +15,8 @@ class HistoryResponse {
HistoryResponse({required this.status, required this.data});
// JSON Init
- factory HistoryResponse.fromJson(Map json) => _$HistoryResponseFromJson(json);
+ factory HistoryResponse.fromJson(Map json) =>
+ _$HistoryResponseFromJson(json);
// JSON Export
Map toJson() => _$HistoryResponseToJson(this);
diff --git a/lib/core/models/rest/rest_error.dart b/lib/core/models/rest/rest_error.dart
index 30b3d6f..6db731c 100644
--- a/lib/core/models/rest/rest_error.dart
+++ b/lib/core/models/rest/rest_error.dart
@@ -15,7 +15,8 @@ class RestError {
required this.errorId,
}); // JSON Init
- factory RestError.fromJson(Map json) => _$RestErrorFromJson(json);
+ factory RestError.fromJson(Map json) =>
+ _$RestErrorFromJson(json);
// JSON Export
Map toJson() => _$RestErrorToJson(this);
diff --git a/lib/core/models/rest/uploaded.dart b/lib/core/models/rest/uploaded.dart
index 7405970..28f0a6a 100644
--- a/lib/core/models/rest/uploaded.dart
+++ b/lib/core/models/rest/uploaded.dart
@@ -13,7 +13,8 @@ class Uploaded {
Uploaded({required this.ids, required this.urls});
// JSON Init
- factory Uploaded.fromJson(Map json) => _$UploadedFromJson(json);
+ factory Uploaded.fromJson(Map json) =>
+ _$UploadedFromJson(json);
// JSON Export
Map toJson() => _$UploadedToJson(this);
diff --git a/lib/core/models/rest/uploaded_multi.dart b/lib/core/models/rest/uploaded_multi.dart
index 6339bb8..f404269 100644
--- a/lib/core/models/rest/uploaded_multi.dart
+++ b/lib/core/models/rest/uploaded_multi.dart
@@ -13,7 +13,8 @@ class UploadedMulti {
UploadedMulti({required this.url, required this.urlId});
// JSON Init
- factory UploadedMulti.fromJson(Map json) => _$UploadedMultiFromJson(json);
+ 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
index b6de81f..51a03a2 100644
--- a/lib/core/models/rest/uploaded_multi_response.dart
+++ b/lib/core/models/rest/uploaded_multi_response.dart
@@ -15,7 +15,8 @@ class UploadedMultiResponse {
UploadedMultiResponse({required this.status, required this.data});
// JSON Init
- factory UploadedMultiResponse.fromJson(Map json) => _$UploadedMultiResponseFromJson(json);
+ factory UploadedMultiResponse.fromJson(Map json) =>
+ _$UploadedMultiResponseFromJson(json);
// JSON Export
Map toJson() => _$UploadedMultiResponseToJson(this);
diff --git a/lib/core/models/rest/uploaded_response.dart b/lib/core/models/rest/uploaded_response.dart
index 9ed84b1..707373f 100644
--- a/lib/core/models/rest/uploaded_response.dart
+++ b/lib/core/models/rest/uploaded_response.dart
@@ -15,7 +15,8 @@ class UploadedResponse {
UploadedResponse({required this.status, required this.data});
// JSON Init
- factory UploadedResponse.fromJson(Map json) => _$UploadedResponseFromJson(json);
+ factory UploadedResponse.fromJson(Map json) =>
+ _$UploadedResponseFromJson(json);
// JSON Export
Map toJson() => _$UploadedResponseToJson(this);
diff --git a/lib/core/models/session.dart b/lib/core/models/session.dart
index a2725a8..4d07ac5 100644
--- a/lib/core/models/session.dart
+++ b/lib/core/models/session.dart
@@ -13,7 +13,8 @@ class Session {
: url = '',
apiKey = '';
- factory Session.fromJson(Map json) => _$SessionFromJson(json);
+ factory Session.fromJson(Map json) =>
+ _$SessionFromJson(json);
Map toJson() => _$SessionToJson(this);
}
diff --git a/lib/core/models/uploaded_paste.dart b/lib/core/models/uploaded_paste.dart
index d209696..7db14b6 100644
--- a/lib/core/models/uploaded_paste.dart
+++ b/lib/core/models/uploaded_paste.dart
@@ -26,7 +26,8 @@ class UploadedPaste {
this.items});
// JSON Init
- factory UploadedPaste.fromJson(Map json) => _$UploadedPasteFromJson(json);
+ factory UploadedPaste.fromJson(Map json) =>
+ _$UploadedPasteFromJson(json);
// JSON Export
Map toJson() => _$UploadedPasteToJson(this);
diff --git a/lib/core/repositories/file_repository.dart b/lib/core/repositories/file_repository.dart
index e93ae3a..dd49593 100644
--- a/lib/core/repositories/file_repository.dart
+++ b/lib/core/repositories/file_repository.dart
@@ -33,8 +33,10 @@ class FileRepository {
return response;
}
- Future postUpload(List? files, Map? additionalFiles) async {
- var response = await _api.post('/file/upload', files: files, additionalFiles: additionalFiles);
+ Future postUpload(
+ List? files, Map? additionalFiles) async {
+ var response = await _api.post('/file/upload',
+ files: files, additionalFiles: additionalFiles);
return UploadedResponse.fromJson(json.decode(response.body));
}
@@ -42,10 +44,12 @@ class FileRepository {
Map multiPasteIds = {};
for (var element in ids) {
- multiPasteIds.putIfAbsent("ids[${ids.indexOf(element) + 1}]", () => element);
+ multiPasteIds.putIfAbsent(
+ "ids[${ids.indexOf(element) + 1}]", () => element);
}
- var response = 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/repositories/user_repository.dart b/lib/core/repositories/user_repository.dart
index f8d53e1..41397e5 100644
--- a/lib/core/repositories/user_repository.dart
+++ b/lib/core/repositories/user_repository.dart
@@ -8,8 +8,8 @@ import '../services/api.dart';
class UserRepository {
final Api _api = locator();
- Future postApiKey(
- String url, String username, String password, String accessLevel, String comment) async {
+ Future postApiKey(String url, String username,
+ String password, String accessLevel, String comment) async {
_api.setUrl(url);
var fields = Map.fromEntries([
diff --git a/lib/core/services/api.dart b/lib/core/services/api.dart
index 2cf65b9..fd9168d 100644
--- a/lib/core/services/api.dart
+++ b/lib/core/services/api.dart
@@ -24,25 +24,34 @@ class Api implements ApiErrorConverter {
String _url = "";
String _apiKey = "";
- final Map _headers = {"Content-Type": _applicationJson, "Accept": _applicationJson};
+ final Map _headers = {
+ "Content-Type": _applicationJson,
+ "Accept": _applicationJson
+ };
Duration _timeout = const Duration(seconds: Constants.apiRequestTimeoutLimit);
Future fetch(String route) async {
try {
- _logger
- .d("Requesting GET API endpoint '${_url + route}' with headers '$_headers' and maximum timeout '$_timeout'");
- var response = await http.get(Uri.parse(_url + route), headers: _headers).timeout(_timeout);
+ _logger.d(
+ "Requesting GET API endpoint '${_url + route}' with headers '$_headers' and maximum timeout '$_timeout'");
+ var response = await http
+ .get(Uri.parse(_url + route), headers: _headers)
+ .timeout(_timeout);
handleRestErrors(response);
return response;
} on TimeoutException {
- throw ServiceException(code: ErrorCode.socketTimeout, message: _errorTimeout);
+ throw ServiceException(
+ code: ErrorCode.socketTimeout, message: _errorTimeout);
} on SocketException {
- throw ServiceException(code: ErrorCode.socketError, message: _errorNoConnection);
+ throw ServiceException(
+ code: ErrorCode.socketError, message: _errorNoConnection);
}
}
Future post(String route,
- {Map? fields, List? files, Map? additionalFiles}) async {
+ {Map? fields,
+ List? files,
+ Map? additionalFiles}) async {
try {
var uri = Uri.parse(_url + route);
var request = http.MultipartRequest('POST', uri)
@@ -59,27 +68,34 @@ class Api implements ApiErrorConverter {
if (files != null && files.isNotEmpty) {
for (var element in files) {
- request.files.add(await http.MultipartFile.fromPath('file[${files.indexOf(element) + 1}]', element.path));
+ request.files.add(await http.MultipartFile.fromPath(
+ 'file[${files.indexOf(element) + 1}]', element.path));
}
}
if (additionalFiles != null && additionalFiles.isNotEmpty) {
List keys = additionalFiles.keys.toList();
additionalFiles.forEach((key, value) {
- var index = files != null ? files.length + keys.indexOf(key) + 1 : keys.indexOf(key) + 1;
- request.files.add(http.MultipartFile.fromString('file[$index]', value, filename: key));
+ var index = files != null
+ ? files.length + keys.indexOf(key) + 1
+ : keys.indexOf(key) + 1;
+ request.files.add(http.MultipartFile.fromString('file[$index]', value,
+ filename: key));
});
}
- _logger.d("Requesting POST API endpoint '${uri.toString()}' and ${request.files.length} files");
+ _logger.d(
+ "Requesting POST API endpoint '${uri.toString()}' and ${request.files.length} files");
var multiResponse = await request.send();
var response = await http.Response.fromStream(multiResponse);
handleRestErrors(response);
return response;
} on TimeoutException {
- throw ServiceException(code: ErrorCode.socketTimeout, message: _errorTimeout);
+ throw ServiceException(
+ code: ErrorCode.socketTimeout, message: _errorTimeout);
} on SocketException {
- throw ServiceException(code: ErrorCode.socketError, message: _errorNoConnection);
+ throw ServiceException(
+ code: ErrorCode.socketError, message: _errorNoConnection);
}
}
@@ -107,14 +123,17 @@ class Api implements ApiErrorConverter {
/// have a json decoded object. Replace this with a custom
/// conversion method by overwriting the interface if needed
void handleRestErrors(http.Response response) {
- if (response.statusCode != HttpStatus.ok && response.statusCode != HttpStatus.noContent) {
+ if (response.statusCode != HttpStatus.ok &&
+ response.statusCode != HttpStatus.noContent) {
if (response.headers.containsKey(HttpHeaders.contentTypeHeader)) {
- ContentType responseContentType = ContentType.parse(response.headers[HttpHeaders.contentTypeHeader]!);
+ ContentType responseContentType =
+ ContentType.parse(response.headers[HttpHeaders.contentTypeHeader]!);
if (ContentType.json.primaryType == responseContentType.primaryType &&
ContentType.json.subType == responseContentType.subType) {
var parsedBody = convert(response);
- throw RestServiceException(response.statusCode, responseBody: parsedBody);
+ throw RestServiceException(response.statusCode,
+ responseBody: parsedBody);
}
}
diff --git a/lib/core/services/dialog_service.dart b/lib/core/services/dialog_service.dart
index ccf0d28..9a3e49e 100644
--- a/lib/core/services/dialog_service.dart
+++ b/lib/core/services/dialog_service.dart
@@ -7,7 +7,8 @@ import '../datamodels/dialog_request.dart';
import '../datamodels/dialog_response.dart';
class DialogService {
- final GlobalKey _dialogNavigationKey = GlobalKey();
+ final GlobalKey _dialogNavigationKey =
+ GlobalKey();
late Function(DialogRequest) _showDialogListener;
Completer? _dialogCompleter;
@@ -27,20 +28,28 @@ class DialogService {
title: title,
description: description,
buttonTitleAccept:
- buttonTitleAccept == null || buttonTitleAccept.isEmpty ? translate('dialog.confirm') : buttonTitleAccept));
+ buttonTitleAccept == null || buttonTitleAccept.isEmpty
+ ? translate('dialog.confirm')
+ : buttonTitleAccept));
return _dialogCompleter!.future;
}
Future showConfirmationDialog(
- {String? title, String? description, String? buttonTitleAccept, String? buttonTitleDeny}) {
+ {String? title,
+ String? description,
+ String? buttonTitleAccept,
+ String? buttonTitleDeny}) {
_dialogCompleter = Completer();
_showDialogListener(DialogRequest(
title: title,
description: description,
buttonTitleAccept:
- buttonTitleAccept == null || buttonTitleAccept.isEmpty ? translate('dialog.confirm') : buttonTitleAccept,
- buttonTitleDeny:
- buttonTitleDeny == null || buttonTitleDeny.isEmpty ? translate('dialog.cancel') : buttonTitleDeny));
+ buttonTitleAccept == null || buttonTitleAccept.isEmpty
+ ? translate('dialog.confirm')
+ : buttonTitleAccept,
+ buttonTitleDeny: buttonTitleDeny == null || buttonTitleDeny.isEmpty
+ ? translate('dialog.cancel')
+ : buttonTitleDeny));
return _dialogCompleter!.future;
}
diff --git a/lib/core/services/file_service.dart b/lib/core/services/file_service.dart
index fd4a7e2..8ce822f 100644
--- a/lib/core/services/file_service.dart
+++ b/lib/core/services/file_service.dart
@@ -23,7 +23,8 @@ class FileService {
return await _fileRepository.postDelete(id);
}
- Future uploadPaste(List? files, Map? additionalFiles) async {
+ Future uploadPaste(
+ List? files, Map? additionalFiles) async {
return await _fileRepository.postUpload(files, additionalFiles);
}
diff --git a/lib/core/services/link_service.dart b/lib/core/services/link_service.dart
index 7cfde11..47c4140 100644
--- a/lib/core/services/link_service.dart
+++ b/lib/core/services/link_service.dart
@@ -19,7 +19,8 @@ class LinkService {
_logger.e('Could not launch link $link');
_dialogService.showDialog(
title: translate('link.dialog.title'),
- description: translate('link.dialog.description', args: {'link': link}));
+ description:
+ translate('link.dialog.description', args: {'link': link}));
}
}
}
diff --git a/lib/core/services/navigation_service.dart b/lib/core/services/navigation_service.dart
index cd0b539..e8533bd 100644
--- a/lib/core/services/navigation_service.dart
+++ b/lib/core/services/navigation_service.dart
@@ -17,11 +17,13 @@ class NavigationService {
Future navigateTo(String routeName, {dynamic arguments}) {
logger.d('NavigationService: navigateTo $routeName');
- return _navigationKey.currentState!.pushNamed(routeName, arguments: arguments);
+ return _navigationKey.currentState!
+ .pushNamed(routeName, arguments: arguments);
}
Future navigateAndReplaceTo(String routeName, {dynamic arguments}) {
logger.d('NavigationService: navigateAndReplaceTo $routeName');
- return _navigationKey.currentState!.pushReplacementNamed(routeName, arguments: arguments);
+ return _navigationKey.currentState!
+ .pushReplacementNamed(routeName, arguments: arguments);
}
}
diff --git a/lib/core/services/permission_service.dart b/lib/core/services/permission_service.dart
index 4000c54..4c5dcdc 100644
--- a/lib/core/services/permission_service.dart
+++ b/lib/core/services/permission_service.dart
@@ -57,7 +57,8 @@ class PermissionService extends StoppableService {
return;
}
- var ignoredDialog = await _storageService.hasStoragePermissionDialogIgnored();
+ var ignoredDialog =
+ await _storageService.hasStoragePermissionDialogIgnored();
if (ignoredDialog) {
_logger.d('Permanently ignored permission request, skipping');
@@ -104,8 +105,9 @@ class PermissionService extends StoppableService {
super.start();
await checkEnabledAndPermission();
- _serviceCheckTimer =
- Timer.periodic(const Duration(milliseconds: Constants.mediaPermissionCheckInterval), (serviceTimer) async {
+ _serviceCheckTimer = Timer.periodic(
+ const Duration(milliseconds: Constants.mediaPermissionCheckInterval),
+ (serviceTimer) async {
if (!super.serviceStopped) {
await checkEnabledAndPermission();
} else {
diff --git a/lib/core/services/refresh_service.dart b/lib/core/services/refresh_service.dart
index 0e9e0e3..b92306e 100644
--- a/lib/core/services/refresh_service.dart
+++ b/lib/core/services/refresh_service.dart
@@ -3,7 +3,8 @@ import 'dart:async';
import '../enums/refresh_event.dart';
class RefreshService {
- StreamController refreshEventController = StreamController.broadcast();
+ StreamController refreshEventController =
+ StreamController.broadcast();
void addEvent(RefreshEvent event) {
if (refreshEventController.hasListener) {
diff --git a/lib/core/services/storage_service.dart b/lib/core/services/storage_service.dart
index 322c607..95f08c4 100644
--- a/lib/core/services/storage_service.dart
+++ b/lib/core/services/storage_service.dart
@@ -7,7 +7,8 @@ import '../models/session.dart';
class StorageService {
static const _sessionKey = 'session';
static const _lastUrlKey = 'last_url';
- static const _storagePermissionDialogIgnoredKey = 'storage_permission_ignored';
+ static const _storagePermissionDialogIgnoredKey =
+ 'storage_permission_ignored';
Future storeLastUrl(String url) {
return _store(_lastUrlKey, url);
diff --git a/lib/core/services/user_service.dart b/lib/core/services/user_service.dart
index ef10096..7637a1f 100644
--- a/lib/core/services/user_service.dart
+++ b/lib/core/services/user_service.dart
@@ -12,9 +12,10 @@ class UserService {
final FileService _fileService = locator();
final UserRepository _userRepository = locator();
- Future createApiKey(
- String url, String username, String password, String accessLevel, String comment) async {
- return await _userRepository.postApiKey(url, username, password, accessLevel, comment);
+ Future createApiKey(String url, String username,
+ String password, String accessLevel, String comment) async {
+ return await _userRepository.postApiKey(
+ url, username, password, accessLevel, comment);
}
Future getApiKeys() async {
diff --git a/lib/core/util/formatter_util.dart b/lib/core/util/formatter_util.dart
index ba606f7..1f04f6e 100644
--- a/lib/core/util/formatter_util.dart
+++ b/lib/core/util/formatter_util.dart
@@ -6,7 +6,8 @@ class FormatterUtil {
/// Format epoch timestamp
static String formatEpoch(num millis) {
DateFormat dateFormat = DateFormat().add_yMEd().add_Hm();
- return dateFormat.format(DateTime.fromMillisecondsSinceEpoch(millis as int));
+ return dateFormat
+ .format(DateTime.fromMillisecondsSinceEpoch(millis as int));
}
static String formatBytes(int bytes, int decimals) {
diff --git a/lib/core/viewmodels/base_model.dart b/lib/core/viewmodels/base_model.dart
index 9fc7570..c7c0687 100644
--- a/lib/core/viewmodels/base_model.dart
+++ b/lib/core/viewmodels/base_model.dart
@@ -12,7 +12,10 @@ class BaseModel extends ChangeNotifier {
bool _isDisposed = false;
- final Map _stateMap = {stateViewKey: ViewState.idle, stateMessageKey: null};
+ final Map _stateMap = {
+ stateViewKey: ViewState.idle,
+ stateMessageKey: null
+ };
ViewState? get state => _stateMap[stateViewKey] as ViewState?;
@@ -42,11 +45,14 @@ class BaseModel extends ChangeNotifier {
return null;
}
- void setStateBoolValue(String key, bool stateValue) => _setStateValue(key, stateValue);
+ void setStateBoolValue(String key, bool stateValue) =>
+ _setStateValue(key, stateValue);
- void setStateIntValue(String key, int? stateValue) => _setStateValue(key, stateValue);
+ void setStateIntValue(String key, int? stateValue) =>
+ _setStateValue(key, stateValue);
- void setStateStringValue(String key, String? stateValue) => _setStateValue(key, stateValue);
+ void setStateStringValue(String key, String? stateValue) =>
+ _setStateValue(key, stateValue);
void _setStateValue(String key, Object? stateValue) {
if (_stateMap.containsKey(key)) {
@@ -57,7 +63,8 @@ class BaseModel extends ChangeNotifier {
if (!_isDisposed) {
notifyListeners();
- _logger.d("Notified state value update '($key, ${stateValue.toString()})'");
+ _logger
+ .d("Notified state value update '($key, ${stateValue.toString()})'");
}
}
@@ -80,6 +87,7 @@ class BaseModel extends ChangeNotifier {
@override
void dispose() {
+ _logger.d("Calling dispose");
super.dispose();
_isDisposed = true;
}
diff --git a/lib/core/viewmodels/history_model.dart b/lib/core/viewmodels/history_model.dart
index 4007ced..e506db3 100644
--- a/lib/core/viewmodels/history_model.dart
+++ b/lib/core/viewmodels/history_model.dart
@@ -34,7 +34,8 @@ class HistoryModel extends BaseModel {
String? errorMessage;
void init() {
- _refreshTriggerSubscription = _refreshService.refreshEventController.stream.listen((event) {
+ _refreshTriggerSubscription =
+ _refreshService.refreshEventController.stream.listen((event) {
if (event == RefreshEvent.refreshHistory) {
_logger.d('History needs a refresh');
getHistory();
@@ -54,7 +55,8 @@ class HistoryModel extends BaseModel {
pastes.add(
UploadedPaste(
id: key,
- date: DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch),
+ date:
+ DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch),
filename: value.filename,
filesize: int.parse(value.filesize),
hash: value.hash,
@@ -90,9 +92,11 @@ class HistoryModel extends BaseModel {
e.responseBody is RestError &&
e.responseBody.message != null) {
if (e.statusCode == HttpStatus.badRequest) {
- errorMessage = translate('api.bad_request', args: {'reason': e.responseBody.message});
+ errorMessage = translate('api.bad_request',
+ args: {'reason': e.responseBody.message});
} else {
- errorMessage = translate('api.general_rest_error_payload', args: {'message': e.responseBody.message});
+ errorMessage = translate('api.general_rest_error_payload',
+ args: {'message': e.responseBody.message});
}
} else {
errorMessage = translate('api.general_rest_error');
@@ -115,7 +119,8 @@ class HistoryModel extends BaseModel {
Future deletePaste(String id) async {
DialogResponse res = await _dialogService.showConfirmationDialog(
title: translate('history.delete_dialog.title'),
- description: translate('history.delete_dialog.description', args: {'id': id}),
+ description:
+ translate('history.delete_dialog.description', args: {'id': id}),
buttonTitleAccept: translate('history.delete_dialog.accept'),
buttonTitleDeny: translate('history.delete_dialog.deny'));
@@ -139,7 +144,8 @@ class HistoryModel extends BaseModel {
e.statusCode != HttpStatus.forbidden &&
e.responseBody is RestError &&
e.responseBody.message != null) {
- errorMessage = translate('api.general_rest_error_payload', args: {'message': e.responseBody.message});
+ errorMessage = translate('api.general_rest_error_payload',
+ args: {'message': e.responseBody.message});
} else {
errorMessage = translate('api.general_rest_error');
}
diff --git a/lib/core/viewmodels/login_model.dart b/lib/core/viewmodels/login_model.dart
index afa9182..8d62d08 100644
--- a/lib/core/viewmodels/login_model.dart
+++ b/lib/core/viewmodels/login_model.dart
@@ -117,13 +117,19 @@ class LoginModel extends BaseModel {
try {
if (useCredentialsLogin) {
CreateApiKeyResponse apiKeyResponse = await _userService.createApiKey(
- url, username, password, 'apikey', 'fbmobile-${DateTime.now().millisecondsSinceEpoch}');
+ url,
+ username,
+ password,
+ 'apikey',
+ 'fbmobile-${DateTime.now().millisecondsSinceEpoch}');
var newKey = apiKeyResponse.data['new_key'];
if (newKey != null) {
success = await _sessionService.login(url, newKey);
} else {
- throw ServiceException(code: ErrorCode.invalidApiKey, message: translate('login.errors.invalid_api_key'));
+ throw ServiceException(
+ code: ErrorCode.invalidApiKey,
+ message: translate('login.errors.invalid_api_key'));
}
} else {
_sessionService.setApiConfig(url, apiKey);
@@ -135,13 +141,15 @@ class LoginModel extends BaseModel {
if (e is RestServiceException) {
if (e.statusCode == HttpStatus.unauthorized) {
errorMessage = translate('login.errors.wrong_credentials');
- } else if (e.statusCode != HttpStatus.unauthorized && e.statusCode == HttpStatus.forbidden) {
+ } else if (e.statusCode != HttpStatus.unauthorized &&
+ e.statusCode == HttpStatus.forbidden) {
errorMessage = translate('login.errors.forbidden');
} else if (e.statusCode == HttpStatus.notFound) {
errorMessage = translate('api.incompatible_error_not_found');
}
if (e.statusCode == HttpStatus.badRequest) {
- errorMessage = translate('api.bad_request', args: {'reason': e.responseBody.message});
+ errorMessage = translate('api.bad_request',
+ args: {'reason': e.responseBody.message});
} else {
errorMessage = translate('api.general_rest_error');
}
diff --git a/lib/core/viewmodels/profile_model.dart b/lib/core/viewmodels/profile_model.dart
index edf835d..3d5362c 100644
--- a/lib/core/viewmodels/profile_model.dart
+++ b/lib/core/viewmodels/profile_model.dart
@@ -31,7 +31,8 @@ class ProfileModel extends BaseModel {
Future logout() async {
var dialogResult = await _dialogService.showConfirmationDialog(
- title: translate('logout.title'), description: translate('logout.confirm'));
+ title: translate('logout.title'),
+ description: translate('logout.confirm'));
if (dialogResult.confirmed!) {
await _sessionService.logout();
@@ -41,7 +42,8 @@ class ProfileModel extends BaseModel {
Future revealApiKey(String? apiKey) async {
await _dialogService.showDialog(
title: translate('profile.revealed_api_key.title'),
- description: translate('profile.revealed_api_key.description', args: {'apiKey': apiKey}));
+ description: translate('profile.revealed_api_key.description',
+ args: {'apiKey': apiKey}));
}
Future showConfig(String url) async {
@@ -54,13 +56,15 @@ class ProfileModel extends BaseModel {
if (e is RestServiceException) {
if (e.statusCode == HttpStatus.unauthorized) {
errorMessage = translate('login.errors.wrong_credentials');
- } else if (e.statusCode != HttpStatus.unauthorized && e.statusCode == HttpStatus.forbidden) {
+ } else if (e.statusCode != HttpStatus.unauthorized &&
+ e.statusCode == HttpStatus.forbidden) {
errorMessage = translate('login.errors.forbidden');
} else if (e.statusCode == HttpStatus.notFound) {
errorMessage = translate('api.incompatible_error_not_found');
}
if (e.statusCode == HttpStatus.badRequest) {
- errorMessage = translate('api.bad_request', args: {'reason': e.responseBody.message});
+ errorMessage = translate('api.bad_request',
+ args: {'reason': e.responseBody.message});
} else {
errorMessage = translate('api.general_rest_error');
}
@@ -84,15 +88,18 @@ class ProfileModel extends BaseModel {
await _dialogService.showDialog(
title: translate('profile.shown_config.title'),
description: translate('profile.shown_config.description', args: {
- 'uploadMaxSize': FormatterUtil.formatBytes(config.uploadMaxSize as int, 2),
+ 'uploadMaxSize':
+ FormatterUtil.formatBytes(config.uploadMaxSize as int, 2),
'maxFilesPerRequest': config.maxFilesPerRequest,
'maxInputVars': config.maxInputVars,
- 'requestMaxSize': FormatterUtil.formatBytes(config.requestMaxSize as int, 2)
+ 'requestMaxSize':
+ FormatterUtil.formatBytes(config.requestMaxSize as int, 2)
}));
} else {
await _dialogService.showDialog(
title: translate('profile.shown_config.error.title'),
- description: translate('profile.shown_config.error.description', args: {'message': errorMessage}));
+ description: translate('profile.shown_config.error.description',
+ args: {'message': errorMessage}));
}
}
diff --git a/lib/core/viewmodels/upload_model.dart b/lib/core/viewmodels/upload_model.dart
index 2be59b6..71e43ed 100644
--- a/lib/core/viewmodels/upload_model.dart
+++ b/lib/core/viewmodels/upload_model.dart
@@ -4,10 +4,11 @@ import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
+import 'package:flutter_sharing_intent/flutter_sharing_intent.dart';
+import 'package:flutter_sharing_intent/model/sharing_file.dart';
import 'package:flutter_translate/flutter_translate.dart';
import 'package:logger/logger.dart';
import 'package:path/path.dart';
-import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import '../../locator.dart';
import '../enums/error_code.dart';
@@ -45,6 +46,41 @@ class UploadModel extends BaseModel {
TextEditingController get pasteTextController => _pasteTextController;
+ void _parseIntentFiles(List files) {
+ if (files.isNotEmpty) {
+ setStateView(ViewState.busy);
+
+ paths = files.map((sharedFile) {
+ _logger.d("Shared file name: ${basename(sharedFile.value ?? '')}");
+ _logger.d("Shared file path: ${sharedFile.value}");
+ _logger.d(
+ "Shared file size: ${File(sharedFile.value ?? '').lengthSync()}");
+ _logger.d("Shared file type: ${sharedFile.type}");
+ return PlatformFile.fromMap({
+ 'path': sharedFile.value,
+ 'name': basename(sharedFile.value!),
+ 'size': File(sharedFile.value!).lengthSync(),
+ 'bytes': null
+ });
+ }).toList();
+
+ setStateView(ViewState.idle);
+ }
+ }
+
+ void deleteIntentFile(String path) {
+ setStateView(ViewState.busy);
+ _logger.d("Removing path '$path' from $paths");
+
+ paths?.removeWhere((element) => element.path == path);
+
+ int length = paths!.length;
+ if (length == 0) {
+ paths = null;
+ }
+ setStateView(ViewState.idle);
+ }
+
void init() {
_pasteTextController.addListener(() {
pasteTextTouched = pasteTextController.text.isNotEmpty;
@@ -52,61 +88,21 @@ class UploadModel extends BaseModel {
});
// For sharing images coming from outside the app while the app is in the memory
- _intentDataStreamSubscription = ReceiveSharingIntent.getMediaStream().listen((List value) {
- if (value.isNotEmpty) {
- setStateView(ViewState.busy);
- paths = value.map((sharedFile) {
- return PlatformFile.fromMap({
- 'path': sharedFile.path,
- 'name': basename(sharedFile.path),
- 'size': File(sharedFile.path).lengthSync(),
- 'bytes': null
- });
- }).toList();
- setStateView(ViewState.idle);
- }
+ _intentDataStreamSubscription = FlutterSharingIntent.instance
+ .getMediaStream()
+ .listen((List value) {
+ _logger.d("Retrieved ${value.length} files from intent");
+ _parseIntentFiles(value);
}, onError: (err) {
_errorIntentHandle(err);
});
// For sharing images coming from outside the app while the app is closed
- ReceiveSharingIntent.getInitialMedia().then((List value) {
- if (value.isNotEmpty) {
- setStateView(ViewState.busy);
- paths = value.map((sharedFile) {
- return PlatformFile.fromMap({
- 'path': sharedFile.path,
- 'name': basename(sharedFile.path),
- 'size': File(sharedFile.path).lengthSync(),
- 'bytes': null
- });
- }).toList();
- setStateView(ViewState.idle);
- }
- }, onError: (err) {
- _errorIntentHandle(err);
- });
-
- // For sharing or opening urls/text coming from outside the app while the app is in the memory
- _intentDataStreamSubscription = ReceiveSharingIntent.getTextStream().listen((String value) {
- if (value.isNotEmpty) {
- setStateView(ViewState.busy);
- pasteTextController.text = value;
- setStateView(ViewState.idle);
- }
- }, onError: (err) {
- _errorIntentHandle(err);
- });
-
- // For sharing or opening urls/text coming from outside the app while the app is closed
- ReceiveSharingIntent.getInitialText().then((String? value) {
- if (value != null && value.isNotEmpty) {
- setStateView(ViewState.busy);
- pasteTextController.text = value;
- setStateView(ViewState.idle);
- }
- }, onError: (err) {
- _errorIntentHandle(err);
+ FlutterSharingIntent.instance
+ .getInitialSharing()
+ .then((List value) {
+ _logger.d("Retrieved ${value.length} files from inactive intent");
+ _parseIntentFiles(value);
});
}
@@ -150,7 +146,9 @@ class UploadModel extends BaseModel {
allowMultiple: true,
withData: false,
withReadStream: true,
- allowedExtensions: (_extension?.isNotEmpty ?? false) ? _extension?.replaceAll(' ', '').split(',') : null,
+ allowedExtensions: (_extension?.isNotEmpty ?? false)
+ ? _extension?.replaceAll(' ', '').split(',')
+ : null,
))
?.files;
} on PlatformException catch (e) {
@@ -185,21 +183,25 @@ class UploadModel extends BaseModel {
Map? additionalFiles;
if (pasteTextController.text.isNotEmpty) {
- additionalFiles =
- Map.from({'paste-${(DateTime.now().millisecondsSinceEpoch / 1000).round()}.txt': pasteTextController.text});
+ additionalFiles = Map.from({
+ 'paste-${(DateTime.now().millisecondsSinceEpoch / 1000).round()}.txt':
+ pasteTextController.text
+ });
}
if (paths != null && paths!.isNotEmpty) {
files = paths!.map((e) => File(e.path!)).toList();
}
- UploadedResponse response = await _fileService.uploadPaste(files, additionalFiles);
+ UploadedResponse response =
+ await _fileService.uploadPaste(files, additionalFiles);
for (var element in response.data.ids) {
uploadedPasteIds.putIfAbsent(element, () => false);
}
if (createMulti && response.data.ids.length > 1) {
- UploadedMultiResponse multiResponse = await _fileService.uploadMultiPaste(response.data.ids);
+ UploadedMultiResponse multiResponse =
+ await _fileService.uploadMultiPaste(response.data.ids);
uploadedPasteIds.putIfAbsent(multiResponse.data.urlId, () => true);
}
@@ -219,9 +221,11 @@ class UploadModel extends BaseModel {
e.responseBody is RestError &&
e.responseBody.message != null) {
if (e.statusCode == HttpStatus.badRequest) {
- errorMessage = translate('api.bad_request', args: {'reason': e.responseBody.message});
+ errorMessage = translate('api.bad_request',
+ args: {'reason': e.responseBody.message});
} else {
- errorMessage = translate('api.general_rest_error_payload', args: {'message': e.responseBody.message});
+ errorMessage = translate('api.general_rest_error_payload',
+ args: {'message': e.responseBody.message});
}
} else {
errorMessage = translate('api.general_rest_error');
@@ -252,6 +256,8 @@ class UploadModel extends BaseModel {
void dispose() {
_pasteTextController.dispose();
_intentDataStreamSubscription.cancel();
+ FlutterSharingIntent.instance.reset();
+ paths = null;
super.dispose();
}
}
diff --git a/lib/main.dart b/lib/main.dart
index 1db3d2c..81b84f4 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -11,7 +11,8 @@ void main() async {
setupLogger(Level.info);
setupLocator();
- var delegate = await LocalizationDelegate.create(fallbackLocale: 'en', supportedLocales: ['en', 'en_US']);
+ var delegate = await LocalizationDelegate.create(
+ fallbackLocale: 'en', supportedLocales: ['en', 'en_US']);
WidgetsFlutterBinding.ensureInitialized();
runApp(LocalizedApp(delegate, MyApp()));
diff --git a/lib/ui/app_router.dart b/lib/ui/app_router.dart
index f43647e..5dc8b7c 100644
--- a/lib/ui/app_router.dart
+++ b/lib/ui/app_router.dart
@@ -27,7 +27,8 @@ class AppRouter {
return MaterialPageRoute(
builder: (_) => Scaffold(
body: Center(
- child: Text(translate('dev.no_route', args: {'route': settings.name})),
+ child: Text(translate('dev.no_route',
+ args: {'route': settings.name})),
),
));
}
diff --git a/lib/ui/views/about_view.dart b/lib/ui/views/about_view.dart
index ddd4c45..d9ca5f2 100644
--- a/lib/ui/views/about_view.dart
+++ b/lib/ui/views/about_view.dart
@@ -38,7 +38,8 @@ class AboutView extends StatelessWidget {
padding: const EdgeInsets.all(0),
child: ListView(
shrinkWrap: true,
- padding: const EdgeInsets.only(left: 10.0, right: 10.0, bottom: 10, top: 10),
+ padding: const EdgeInsets.only(
+ left: 10.0, right: 10.0, bottom: 10, top: 10),
children: [
UIHelper.verticalSpaceMedium(),
Center(child: logo),
diff --git a/lib/ui/views/base_view.dart b/lib/ui/views/base_view.dart
index 224a819..ff83c87 100644
--- a/lib/ui/views/base_view.dart
+++ b/lib/ui/views/base_view.dart
@@ -31,7 +31,9 @@ class _BaseViewState extends State> {
@override
Widget build(BuildContext context) {
- return ChangeNotifierProvider(create: (context) => model, child: Consumer(builder: widget.builder!));
+ return ChangeNotifierProvider(
+ create: (context) => model,
+ child: Consumer(builder: widget.builder!));
}
@override
diff --git a/lib/ui/views/history_view.dart b/lib/ui/views/history_view.dart
index 53e659b..ff4847f 100644
--- a/lib/ui/views/history_view.dart
+++ b/lib/ui/views/history_view.dart
@@ -27,8 +27,9 @@ class HistoryView extends StatelessWidget {
model.init();
return model.getHistory();
},
- builder: (context, model, child) =>
- Scaffold(appBar: MyAppBar(title: Text(translate('titles.history'))), body: _render(model, context)),
+ builder: (context, model, child) => Scaffold(
+ appBar: MyAppBar(title: Text(translate('titles.history'))),
+ body: _render(model, context)),
);
}
@@ -41,7 +42,8 @@ class HistoryView extends StatelessWidget {
? Container(
padding: const EdgeInsets.all(0),
child: RefreshIndicator(
- onRefresh: () async => await model.getHistory(), child: _renderItems(model, url, context)))
+ onRefresh: () async => await model.getHistory(),
+ child: _renderItems(model, url, context)))
: Container(
padding: const EdgeInsets.all(25),
child: CenteredErrorRow(
@@ -61,7 +63,8 @@ class HistoryView extends StatelessWidget {
var openInBrowserButton = _renderOpenInBrowser(model, fullPasteUrl);
var dateWidget = ListTile(
- title: Text(FormatterUtil.formatEpoch(paste.date!.millisecondsSinceEpoch)),
+ title: Text(
+ FormatterUtil.formatEpoch(paste.date!.millisecondsSinceEpoch)),
subtitle: Text(translate('history.date')),
);
@@ -73,7 +76,8 @@ class HistoryView extends StatelessWidget {
var copyWidget = ListTile(
title: Text(translate('history.copy_link.description')),
trailing: IconButton(
- icon: const Icon(Icons.copy, color: blueColor, textDirection: TextDirection.ltr),
+ icon: const Icon(Icons.copy,
+ color: blueColor, textDirection: TextDirection.ltr),
onPressed: () {
FlutterClipboard.copy(fullPasteUrl).then((value) {
final snackBar = SnackBar(
@@ -164,12 +168,14 @@ class HistoryView extends StatelessWidget {
trailing: Wrap(children: [
openInBrowserButton,
IconButton(
- icon: const Icon(Icons.share, color: blueColor, textDirection: TextDirection.ltr),
+ icon: const Icon(Icons.share,
+ color: blueColor, textDirection: TextDirection.ltr),
onPressed: () async {
await Share.share(fullPasteUrl);
})
]),
- subtitle: Text(!paste.isMulti! ? paste.filename! : '', style: const TextStyle(fontStyle: FontStyle.italic)),
+ subtitle: Text(!paste.isMulti! ? paste.filename! : '',
+ style: const TextStyle(fontStyle: FontStyle.italic)),
),
));
}
@@ -190,7 +196,8 @@ class HistoryView extends StatelessWidget {
Widget _renderOpenInBrowser(HistoryModel model, String url) {
return IconButton(
- icon: const Icon(Icons.open_in_new, color: blueColor, textDirection: TextDirection.ltr),
+ icon: const Icon(Icons.open_in_new,
+ color: blueColor, textDirection: TextDirection.ltr),
onPressed: () {
return model.openLink(url);
});
diff --git a/lib/ui/views/home_view.dart b/lib/ui/views/home_view.dart
index 3c9f3c3..2812e28 100644
--- a/lib/ui/views/home_view.dart
+++ b/lib/ui/views/home_view.dart
@@ -16,7 +16,9 @@ class HomeView extends StatelessWidget {
return BaseView(
builder: (context, model, child) => Scaffold(
appBar: MyAppBar(title: Text(translate('app.title'))),
- body: model.state == ViewState.busy ? const Center(child: CircularProgressIndicator()) : Container()),
+ body: model.state == ViewState.busy
+ ? const Center(child: CircularProgressIndicator())
+ : Container()),
);
}
}
diff --git a/lib/ui/views/login_view.dart b/lib/ui/views/login_view.dart
index 87125a6..96e1160 100644
--- a/lib/ui/views/login_view.dart
+++ b/lib/ui/views/login_view.dart
@@ -55,13 +55,18 @@ class LoginView extends StatelessWidget {
child: const Icon(Icons.help),
onTap: () {
_dialogService.showDialog(
- title: translate('login.compatibility_dialog.title'),
- description: translate('login.compatibility_dialog.body'));
+ title: translate(
+ 'login.compatibility_dialog.title'),
+ description: translate(
+ 'login.compatibility_dialog.body'));
},
),
InkWell(
- child:
- Icon(model.useCredentialsLogin ? Icons.person_outline : Icons.vpn_key, color: blueColor),
+ child: Icon(
+ model.useCredentialsLogin
+ ? Icons.person_outline
+ : Icons.vpn_key,
+ color: blueColor),
onTap: () {
model.toggleLoginMethod();
},
@@ -86,7 +91,8 @@ class LoginView extends StatelessWidget {
onPressed: () async {
var loginSuccess = await model.login();
if (loginSuccess) {
- _navigationService.navigateAndReplaceTo(HomeView.routeName);
+ _navigationService
+ .navigateAndReplaceTo(HomeView.routeName);
}
},
)
diff --git a/lib/ui/views/navbar_authenticated.dart b/lib/ui/views/navbar_authenticated.dart
index 18b95fa..70a0cc0 100644
--- a/lib/ui/views/navbar_authenticated.dart
+++ b/lib/ui/views/navbar_authenticated.dart
@@ -14,7 +14,8 @@ class AuthenticatedNavBarView extends StatefulWidget {
AuthenticatedNavBarState createState() => AuthenticatedNavBarState();
}
-class AuthenticatedNavBarState extends State with SingleTickerProviderStateMixin {
+class AuthenticatedNavBarState extends State
+ with SingleTickerProviderStateMixin {
final Logger _logger = getLogger();
int _currentTabIndex = 0;
diff --git a/lib/ui/views/profile_view.dart b/lib/ui/views/profile_view.dart
index e9e3e2c..6af69b0 100644
--- a/lib/ui/views/profile_view.dart
+++ b/lib/ui/views/profile_view.dart
@@ -20,8 +20,9 @@ class ProfileView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BaseView(
- builder: (context, model, child) =>
- Scaffold(appBar: MyAppBar(title: Text(translate('titles.profile'))), body: _render(model, context)));
+ builder: (context, model, child) => Scaffold(
+ appBar: MyAppBar(title: Text(translate('titles.profile'))),
+ body: _render(model, context)));
}
Widget _render(ProfileModel model, BuildContext context) {
diff --git a/lib/ui/views/startup_view.dart b/lib/ui/views/startup_view.dart
index e37f642..6808ed0 100644
--- a/lib/ui/views/startup_view.dart
+++ b/lib/ui/views/startup_view.dart
@@ -13,7 +13,7 @@ class StartUpView extends StatelessWidget {
Widget build(BuildContext context) {
return ViewModelBuilder.reactive(
viewModelBuilder: () => StartUpViewModel(),
- onModelReady: (model) => model.handleStartUpLogic(),
+ onViewModelReady: (model) => model.handleStartUpLogic(),
builder: (context, model, child) => Scaffold(
body: model.state == ViewState.busy
? Center(
@@ -22,7 +22,9 @@ class StartUpView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const CircularProgressIndicator(),
- (model.stateMessage!.isNotEmpty ? Text(model.stateMessage!) : Container())
+ (model.stateMessage!.isNotEmpty
+ ? Text(model.stateMessage!)
+ : Container())
]))
: Container()));
}
diff --git a/lib/ui/views/tabbar_container_view.dart b/lib/ui/views/tabbar_container_view.dart
index 1228005..3fa21a5 100644
--- a/lib/ui/views/tabbar_container_view.dart
+++ b/lib/ui/views/tabbar_container_view.dart
@@ -11,7 +11,8 @@ class TabBarContainerView extends StatelessWidget {
@override
Widget build(BuildContext context) {
Session? currentSession = Provider.of(context);
- bool isAuthenticated = currentSession != null ? currentSession.apiKey.isNotEmpty : false;
+ bool isAuthenticated =
+ currentSession != null ? currentSession.apiKey.isNotEmpty : false;
if (isAuthenticated) {
return const AuthenticatedNavBarView();
diff --git a/lib/ui/views/upload_view.dart b/lib/ui/views/upload_view.dart
index 21048b6..b0e4677 100644
--- a/lib/ui/views/upload_view.dart
+++ b/lib/ui/views/upload_view.dart
@@ -1,4 +1,5 @@
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';
@@ -20,12 +21,14 @@ class UploadView extends StatelessWidget {
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)));
+ 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);
+ return model.pasteTextTouched ||
+ (model.paths != null && model.paths!.isNotEmpty);
}
Widget _render(UploadModel model, BuildContext context) {
@@ -38,7 +41,9 @@ class UploadView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const CircularProgressIndicator(),
- (model.stateMessage != null && model.stateMessage!.isNotEmpty ? Text(model.stateMessage!) : Container())
+ (model.stateMessage != null && model.stateMessage!.isNotEmpty
+ ? Text(model.stateMessage!)
+ : Container())
]))
: ListView(children: [
Padding(
@@ -56,12 +61,15 @@ class UploadView extends StatelessWidget {
Icons.text_snippet,
),
suffixIcon: IconButton(
- onPressed: () => model.pasteTextController.clear(),
+ 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)),
+ contentPadding: const EdgeInsets.fromLTRB(
+ 20.0, 10.0, 20.0, 10.0),
+ border: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(32.0)),
),
controller: model.pasteTextController)),
Padding(
@@ -77,14 +85,17 @@ class UploadView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.end,
children: [
ElevatedButton.icon(
- icon: const Icon(Icons.file_copy_sharp, color: blueColor),
+ 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
+ icon: const Icon(Icons.cancel,
+ color: orangeColor),
+ onPressed: model.paths != null &&
+ model.paths!.isNotEmpty
? () => model.clearCachedFiles()
: null,
label: Text(
@@ -114,34 +125,47 @@ class UploadView extends StatelessWidget {
onPressed: !_isUploadButtonEnabled(model)
? null
: () async {
- Map? items = await model.upload();
- String? clipboardContent = model.generatePasteLinks(items, url);
+ Map? items =
+ await model.upload();
+ String? clipboardContent = model
+ .generatePasteLinks(items, url);
- if (clipboardContent != null && clipboardContent.isNotEmpty) {
- FlutterClipboard.copy(clipboardContent).then((value) {
+ if (clipboardContent != null &&
+ clipboardContent.isNotEmpty) {
+ FlutterClipboard.copy(
+ clipboardContent)
+ .then((value) {
final snackBar = SnackBar(
action: SnackBarAction(
- label: translate('upload.dismiss'),
+ label: translate(
+ 'upload.dismiss'),
textColor: blueColor,
onPressed: () {
- ScaffoldMessenger.of(context).hideCurrentSnackBar();
+ ScaffoldMessenger.of(
+ context)
+ .hideCurrentSnackBar();
},
),
- content: Text(translate('upload.uploaded')),
- duration: const Duration(seconds: 10),
+ content: Text(translate(
+ 'upload.uploaded')),
+ duration:
+ const Duration(seconds: 10),
);
- ScaffoldMessenger.of(context).showSnackBar(snackBar);
+ ScaffoldMessenger.of(context)
+ .showSnackBar(snackBar);
});
}
},
- icon: const Icon(Icons.upload_rounded, color: greenColor),
+ 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),
+ padding:
+ const EdgeInsets.only(top: 10.0, bottom: 10.0),
child: CenteredErrorRow(model.errorMessage)))
: Container(),
Builder(
@@ -152,28 +176,54 @@ class UploadView extends StatelessWidget {
)
: model.paths != null
? Container(
- padding: const EdgeInsets.only(bottom: 30.0),
- height: MediaQuery.of(context).size.height * 0.50,
+ 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;
+ 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.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()
+ ? 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,
+ "$name (${FormatterUtil.formatBytes(int.parse(size), 2)})",
),
subtitle: Text(path),
));
},
- separatorBuilder: (BuildContext context, int index) => const Divider(),
+ separatorBuilder:
+ (BuildContext context, int index) =>
+ const Divider(),
),
)
: Container(),
diff --git a/lib/ui/widgets/centered_error_row.dart b/lib/ui/widgets/centered_error_row.dart
index b7fa563..c8d5be3 100644
--- a/lib/ui/widgets/centered_error_row.dart
+++ b/lib/ui/widgets/centered_error_row.dart
@@ -20,7 +20,10 @@ class CenteredErrorRow extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
- Expanded(child: Center(child: Text(message!, style: const TextStyle(color: redColor)))),
+ Expanded(
+ child: Center(
+ child: Text(message!,
+ style: const TextStyle(color: redColor)))),
],
),
(retryCallback != null
diff --git a/lib/ui/widgets/login_header_apikey.dart b/lib/ui/widgets/login_header_apikey.dart
index 90a90fe..56ed54f 100644
--- a/lib/ui/widgets/login_header_apikey.dart
+++ b/lib/ui/widgets/login_header_apikey.dart
@@ -11,13 +11,19 @@ class LoginApiKeyHeaders extends StatelessWidget {
final String? validationMessage;
const LoginApiKeyHeaders(
- {super.key, required this.uriController, required this.apiKeyController, this.validationMessage});
+ {super.key,
+ required this.uriController,
+ required this.apiKeyController,
+ this.validationMessage});
@override
Widget build(BuildContext context) {
return Column(children: [
- validationMessage != null ? Text(validationMessage!, style: const TextStyle(color: redColor)) : Container(),
- LoginTextField(uriController, translate('login.url_placeholder'), const Icon(Icons.link),
+ validationMessage != null
+ ? Text(validationMessage!, style: const TextStyle(color: redColor))
+ : Container(),
+ LoginTextField(uriController, translate('login.url_placeholder'),
+ const Icon(Icons.link),
keyboardType: TextInputType.url),
LoginTextField(
apiKeyController,
diff --git a/lib/ui/widgets/login_header_credentials.dart b/lib/ui/widgets/login_header_credentials.dart
index 9657a66..d676008 100644
--- a/lib/ui/widgets/login_header_credentials.dart
+++ b/lib/ui/widgets/login_header_credentials.dart
@@ -21,12 +21,17 @@ class LoginCredentialsHeaders extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(children: [
- validationMessage != null ? Text(validationMessage!, style: const TextStyle(color: redColor)) : Container(),
- LoginTextField(uriController, translate('login.url_placeholder'), const Icon(Icons.link),
+ validationMessage != null
+ ? Text(validationMessage!, style: const TextStyle(color: redColor))
+ : Container(),
+ LoginTextField(uriController, translate('login.url_placeholder'),
+ const Icon(Icons.link),
keyboardType: TextInputType.url),
- LoginTextField(usernameController, translate('login.username_placeholder'), const Icon(Icons.person),
+ LoginTextField(usernameController,
+ translate('login.username_placeholder'), const Icon(Icons.person),
keyboardType: TextInputType.name),
- LoginTextField(passwordController, translate('login.password_placeholder'), const Icon(Icons.vpn_key),
+ LoginTextField(passwordController,
+ translate('login.password_placeholder'), const Icon(Icons.vpn_key),
obscureText: true),
]);
}
diff --git a/lib/ui/widgets/login_text_field.dart b/lib/ui/widgets/login_text_field.dart
index 56c0e85..1bf7ade 100644
--- a/lib/ui/widgets/login_text_field.dart
+++ b/lib/ui/widgets/login_text_field.dart
@@ -1,7 +1,5 @@
import 'package:flutter/material.dart';
-import '../shared/app_colors.dart';
-
class LoginTextField extends StatelessWidget {
final TextEditingController controller;
final String placeHolder;
@@ -10,7 +8,9 @@ class LoginTextField extends StatelessWidget {
final Widget prefixIcon;
const LoginTextField(this.controller, this.placeHolder, this.prefixIcon,
- {super.key, this.keyboardType = TextInputType.text, this.obscureText = false});
+ {super.key,
+ this.keyboardType = TextInputType.text,
+ this.obscureText = false});
@override
Widget build(BuildContext context) {
@@ -19,7 +19,6 @@ class LoginTextField extends StatelessWidget {
margin: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
height: 50.0,
alignment: Alignment.centerLeft,
- decoration: BoxDecoration(color: whiteColor, borderRadius: BorderRadius.circular(10.0)),
child: TextFormField(
keyboardType: keyboardType,
obscureText: obscureText,
@@ -31,7 +30,8 @@ class LoginTextField extends StatelessWidget {
prefixIcon: prefixIcon,
hintText: placeHolder,
contentPadding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
- border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
+ border:
+ OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
controller: controller),
);
diff --git a/lib/ui/widgets/my_appbar.dart b/lib/ui/widgets/my_appbar.dart
index 9e802e4..67cd92b 100644
--- a/lib/ui/widgets/my_appbar.dart
+++ b/lib/ui/widgets/my_appbar.dart
@@ -6,10 +6,18 @@ class MyAppBar extends AppBar {
static final List aboutEnabledWidgets = [AboutIconButton()];
static final List aboutDisabledWidgets = [];
- MyAppBar({Key? key, required Widget title, List? actionWidgets, bool enableAbout = true})
- : super(key: key, title: Row(children: [title]), actions: _renderIconButtons(actionWidgets, enableAbout));
+ MyAppBar(
+ {Key? key,
+ required Widget title,
+ List? actionWidgets,
+ bool enableAbout = true})
+ : super(
+ key: key,
+ title: Row(children: [title]),
+ actions: _renderIconButtons(actionWidgets, enableAbout));
- static List _renderIconButtons(List? actionWidgets, bool aboutEnabled) {
+ static List _renderIconButtons(
+ List? actionWidgets, bool aboutEnabled) {
actionWidgets ??= [];
List widgets = [...actionWidgets];
diff --git a/pubspec.lock b/pubspec.lock
index 7771c72..3d70bdf 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -98,7 +98,7 @@ packages:
name: built_value_generator
url: "https://pub.dartlang.org"
source: hosted
- version: "8.4.2"
+ version: "8.4.3"
characters:
dependency: transitive
description:
@@ -217,7 +217,7 @@ packages:
name: file_picker
url: "https://pub.dartlang.org"
source: hosted
- version: "5.2.4"
+ version: "5.2.5"
fixnum:
dependency: transitive
description:
@@ -256,6 +256,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.7"
+ flutter_sharing_intent:
+ dependency: "direct main"
+ description:
+ name: flutter_sharing_intent
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.5"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -581,20 +588,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
- quiver:
- dependency: transitive
- description:
- name: quiver
- url: "https://pub.dartlang.org"
- source: hosted
- version: "3.1.0"
- receive_sharing_intent:
- dependency: "direct main"
- description:
- name: receive_sharing_intent
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.4.5"
share_plus:
dependency: "direct main"
description:
@@ -615,7 +608,7 @@ packages:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
- version: "2.0.15"
+ version: "2.0.16"
shared_preferences_android:
dependency: transitive
description:
@@ -623,10 +616,10 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.14"
- shared_preferences_ios:
+ shared_preferences_foundation:
dependency: transitive
description:
- name: shared_preferences_ios
+ name: shared_preferences_foundation
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
@@ -637,13 +630,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
- shared_preferences_macos:
- dependency: transitive
- description:
- name: shared_preferences_macos
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.4"
shared_preferences_platform_interface:
dependency: transitive
description:
@@ -718,7 +704,7 @@ packages:
name: stacked
url: "https://pub.dartlang.org"
source: hosted
- version: "3.0.1"
+ version: "3.1.0+1"
stacked_core:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index fcd276a..892e0a7 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -11,7 +11,7 @@ description: A mobile client for FileBin.
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
-version: 1.5.2+18
+version: 1.6.0+18
environment:
sdk: '>=2.18.5 <3.0.0'
@@ -24,31 +24,31 @@ dependencies:
sdk: flutter
flutter_translate: 4.0.3
provider: 6.0.5
- stacked: 3.0.1
+ stacked: 3.1.0+1
get_it: 7.2.0
logger: 1.1.0
- shared_preferences: 2.0.15
+ shared_preferences: 2.0.16
http: 0.13.5
validators: 3.0.0
flutter_linkify: 5.0.2
url_launcher: 6.1.7
expandable: 5.0.1
share_plus: 6.3.0
- file_picker: 5.2.4
+ file_picker: 5.2.5
clipboard: 0.1.3
- receive_sharing_intent: 1.4.5
permission_handler: 10.2.0
package_info_plus: 3.0.2
json_annotation: 4.7.0
dynamic_color: 1.5.4
intl: 0.17.0
path: 1.8.2
+ flutter_sharing_intent: 1.0.5
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: 2.3.3
- built_value_generator: 8.4.2
+ built_value_generator: 8.4.3
json_serializable: 6.5.4
flutter_lints: 2.0.1