TF-56 Add object upload request & response and widget builder
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 10C4.9 10 4 10.9 4 12C4 13.1 4.9 14 6 14C7.1 14 8 13.1 8 12C8 10.9 7.1 10 6 10ZM18 10C16.9 10 16 10.9 16 12C16 13.1 16.9 14 18 14C19.1 14 20 13.1 20 12C20 10.9 19.1 10 18 10ZM12 10C10.9 10 10 10.9 10 12C10 13.1 10.9 14 12 14C13.1 14 14 13.1 14 12C14 10.9 13.1 10 12 10Z" fill="#ACACAC"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 403 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2 6H0V11H0.01L0 20C0 21.1 0.9 22 2 22H20V20H2V6ZM22 4H14L12 2H6C4.9 2 4.01 2.9 4.01 4L4 16C4 17.1 4.9 18 6 18H22C23.1 18 24 17.1 24 16V6C24 4.9 23.1 4 22 4ZM7 15L11.5 9L15 13.51L17.5 10.5L21 15H7Z" fill="#ACACAC"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 328 B |
+3
-1
@@ -33,7 +33,9 @@ export 'presentation/views/text/text_form_field_builder.dart';
|
||||
export 'presentation/views/image/icon_builder.dart';
|
||||
export 'presentation/views/context_menu/context_menu_action_builder.dart';
|
||||
export 'presentation/views/context_menu/context_menu_builder.dart';
|
||||
export 'presentation/views/dialog/downloading_file_dialog_builder.dart';
|
||||
export 'presentation/views/context_menu/context_menu_header_builder.dart';
|
||||
export 'presentation/views/context_menu/simple_context_menu_action_builder.dart';
|
||||
export 'presentation/views/dialog/loading_dialog_builder.dart';
|
||||
|
||||
// Resources
|
||||
export 'presentation/resources/assets_paths.dart';
|
||||
|
||||
@@ -39,6 +39,8 @@ class ImagePaths {
|
||||
String get icSelected => _getImagePath('ic_selected.svg');
|
||||
String get icExpandAttachment => _getImagePath('ic_expand_attachment.svg');
|
||||
String get icDownload => _getImagePath('ic_download.svg');
|
||||
String get icMore => _getImagePath('ic_more.svg');
|
||||
String get icPhotoLibrary => _getImagePath('ic_photo_library.svg');
|
||||
|
||||
String _getImagePath(String imageName) {
|
||||
return AssetsPaths.images + imageName;
|
||||
|
||||
@@ -6,10 +6,16 @@ abstract class ViewState extends Success {}
|
||||
|
||||
class UIState extends ViewState {
|
||||
static final idle = UIState();
|
||||
static final loading = UIState();
|
||||
|
||||
UIState() : super();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
class LoadingState extends UIState {
|
||||
LoadingState();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ContextMenuHeaderBuilder {
|
||||
final Key _key;
|
||||
String? _label;
|
||||
TextStyle? _textStyle;
|
||||
|
||||
ContextMenuHeaderBuilder(this._key);
|
||||
|
||||
void addLabel(String label) {
|
||||
_label = label;
|
||||
}
|
||||
|
||||
void textStyle(TextStyle textStyle) {
|
||||
_textStyle = textStyle;
|
||||
}
|
||||
|
||||
ListTile build() {
|
||||
return ListTile(
|
||||
key: _key,
|
||||
title: Transform(
|
||||
transform: Matrix4.translationValues(12, 5, 0.0),
|
||||
child: Text(
|
||||
_label ?? '',
|
||||
style: _textStyle ?? TextStyle(fontSize: 20.0, color: AppColor.nameUserColor, fontWeight: FontWeight.w500),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
import 'package:core/presentation/views/context_menu/context_menu_action_builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
class SimpleContextMenuActionBuilder extends ContextMenuActionBuilder<void> {
|
||||
SimpleContextMenuActionBuilder(
|
||||
Key key,
|
||||
SvgPicture actionIcon,
|
||||
String actionName
|
||||
) : super(key, actionIcon, actionName);
|
||||
|
||||
@override
|
||||
ListTile build() {
|
||||
return ListTile(
|
||||
key: key,
|
||||
leading: Padding(
|
||||
padding: EdgeInsets.only(left: 12),
|
||||
child: actionIcon),
|
||||
title: Text(actionName, style: actionTextStyle()),
|
||||
onTap: () {
|
||||
if (onContextMenuActionClick != null) {
|
||||
onContextMenuActionClick!(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class LoadingDialogBuilder {
|
||||
final Key _key;
|
||||
final String _title;
|
||||
|
||||
LoadingDialogBuilder(this._key, this._title);
|
||||
|
||||
Widget build() {
|
||||
return CupertinoAlertDialog(
|
||||
key: _key,
|
||||
title: Text(_title, style: TextStyle(fontSize: 17.0, color: AppColor.appColor)),
|
||||
content: Padding(
|
||||
padding: EdgeInsets.only(top: 16.0, left: 16.0, right: 16.0),
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 20.0,
|
||||
height: 20.0,
|
||||
child: CupertinoActivityIndicator()),
|
||||
SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:model/model.dart';
|
||||
|
||||
@@ -12,6 +14,8 @@ class AccountRequest with EquatableMixin {
|
||||
'password': password.value,
|
||||
};
|
||||
|
||||
String basicAuth() => 'Basic ${base64Encode(utf8.encode('${userName.userName}:${password.value}'))}';
|
||||
|
||||
@override
|
||||
List<Object> get props => [userName, password];
|
||||
}
|
||||
@@ -16,14 +16,14 @@ class Attachment with EquatableMixin {
|
||||
final MediaType? type;
|
||||
final String? cid;
|
||||
|
||||
Attachment(
|
||||
Attachment({
|
||||
this.partId,
|
||||
this.blobId,
|
||||
this.size,
|
||||
this.name,
|
||||
this.type,
|
||||
this.cid
|
||||
);
|
||||
});
|
||||
|
||||
String getDownloadUrl(String baseDownloadUrl, AccountId accountId) {
|
||||
final downloadUriTemplate = UriTemplate('$baseDownloadUrl');
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||
import 'package:uri/uri.dart';
|
||||
|
||||
extension SessionExtension on Session {
|
||||
String getDownloadUrl() {
|
||||
@@ -9,4 +11,13 @@ extension SessionExtension on Session {
|
||||
}
|
||||
return Uri.decodeFull(baseUrl);
|
||||
}
|
||||
|
||||
Uri getUploadUrl(AccountId accountId) {
|
||||
final baseUrl = '${uploadUrl.origin}${uploadUrl.path}';
|
||||
final uploadUriTemplate = UriTemplate('${Uri.decodeFull(baseUrl)}');
|
||||
final uploadUri = uploadUriTemplate.expand({
|
||||
'accountId' : '${accountId.id.value}'
|
||||
});
|
||||
return Uri.parse(uploadUri);
|
||||
}
|
||||
}
|
||||
@@ -42,3 +42,8 @@ export 'download/download_task_id.dart';
|
||||
// Contact
|
||||
export 'contact/contact.dart';
|
||||
export 'contact/device_contact.dart';
|
||||
|
||||
// Upload
|
||||
export 'upload/file_info.dart';
|
||||
export 'upload/upload_request.dart';
|
||||
export 'upload/upload_response.dart';
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
|
||||
class FileInfo with EquatableMixin {
|
||||
final String fileName;
|
||||
final String filePath;
|
||||
final int fileSize;
|
||||
|
||||
FileInfo(this.fileName, this.filePath, this.fileSize);
|
||||
|
||||
factory FileInfo.empty() {
|
||||
return FileInfo('', '', 0);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object> get props => [fileName, filePath, fileSize];
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:model/model.dart';
|
||||
|
||||
class UploadRequest with EquatableMixin {
|
||||
|
||||
final Uri uploadUrl;
|
||||
final FileInfo fileInfo;
|
||||
final AccountId accountId;
|
||||
final AccountRequest accountRequest;
|
||||
|
||||
UploadRequest(this.uploadUrl, this.accountId, this.fileInfo, this.accountRequest);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [uploadUrl, accountId, fileInfo, accountRequest];
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:jmap_dart_client/http/converter/account_id_converter.dart';
|
||||
import 'package:jmap_dart_client/http/converter/id_converter.dart';
|
||||
import 'package:jmap_dart_client/http/converter/media_type_converter.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:model/email/attachment.dart';
|
||||
|
||||
part 'upload_response.g.dart';
|
||||
|
||||
@AccountIdConverter()
|
||||
@MediaTypeConverter()
|
||||
@IdConverter()
|
||||
@JsonSerializable()
|
||||
class UploadResponse with EquatableMixin {
|
||||
|
||||
final AccountId accountId;
|
||||
final Id blobId;
|
||||
final MediaType type;
|
||||
final int size;
|
||||
|
||||
UploadResponse(this.accountId, this.blobId, this.type, this.size);
|
||||
|
||||
factory UploadResponse.fromJson(Map<String, dynamic> json) => _$UploadResponseFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$UploadResponseToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [accountId, blobId, type, size];
|
||||
}
|
||||
|
||||
extension UploadResponseExtension on UploadResponse {
|
||||
Attachment toAttachmentFile(String nameFile) {
|
||||
return Attachment(blobId: blobId, size: UnsignedInt(size), name: nameFile, type: type);
|
||||
}
|
||||
}
|
||||
@@ -119,6 +119,9 @@ dependencies:
|
||||
url: git://github.com/linagora/flutter_contacts.git
|
||||
ref: master
|
||||
|
||||
# file_picker
|
||||
file_picker: 3.0.2+2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
Reference in New Issue
Block a user