TF-675 Add UploadController to handle upload attachment

This commit is contained in:
dab246
2022-07-05 19:31:57 +07:00
committed by Dat H. Pham
parent 87beef9230
commit 91bc3018ea
5 changed files with 406 additions and 0 deletions
@@ -0,0 +1,101 @@
import 'package:core/domain/extensions/media_type_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dio/dio.dart';
import 'package:equatable/equatable.dart';
import 'package:http_parser/http_parser.dart';
import 'package:model/email/attachment.dart';
import 'package:model/upload/file_info.dart';
import 'package:tmail_ui_user/features/upload/domain/model/upload_task_id.dart';
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_status.dart';
class UploadFileState with EquatableMixin {
final FileInfo? file;
final UploadTaskId uploadTaskId;
final UploadFileStatus uploadStatus;
final int uploadingProgress;
final Attachment? attachment;
final CancelToken? cancelToken;
UploadFileState(this.uploadTaskId, {
this.file,
this.uploadStatus = UploadFileStatus.waiting,
this.uploadingProgress = 0,
this.attachment,
this.cancelToken,
});
UploadFileState copyWith({
UploadTaskId? uploadTaskId,
FileInfo? file,
UploadFileStatus? uploadStatus,
int? uploadingProgress,
Attachment? attachment,
CancelToken? cancelToken
}) {
return UploadFileState(
uploadTaskId ?? this.uploadTaskId,
file: file ?? this.file,
uploadStatus: uploadStatus ?? this.uploadStatus,
uploadingProgress: uploadingProgress ?? this.uploadingProgress,
attachment: attachment ?? this.attachment,
cancelToken: cancelToken ?? this.cancelToken
);
}
num get fileSize {
if (attachment != null) {
return attachment?.size?.value ?? 0;
} else if (file != null) {
return file?.fileSize ?? 0;
}
return 0;
}
String get fileName {
if (attachment != null) {
return attachment?.name ?? '';
} else if (file != null) {
return file?.fileName ?? '';
}
return '';
}
double get percentUploading => uploadingProgress / 100;
String getIcon(ImagePaths imagePaths) {
var mediaType = attachment?.type;
if (mediaType == null && file != null) {
mediaType = MediaType.parse(file!.mimeType);
}
log('AttachmentExtension::getIcon(): mediaType: $mediaType');
if (mediaType == null) {
return imagePaths.icFileEPup;
}
if (mediaType.isDocFile()) {
return imagePaths.icFileDocx;
} else if (mediaType.isExcelFile()) {
return imagePaths.icFileXlsx;
} else if (mediaType.isPowerPointFile()) {
return imagePaths.icFilePptx;
} else if (mediaType.isPdfFile()) {
return imagePaths.icFilePdf;
} else if (mediaType.isZipFile()) {
return imagePaths.icFileZip;
} else if (mediaType.isImageFile()) {
return imagePaths.icFilePng;
}
return imagePaths.icFileEPup;
}
@override
List<Object?> get props => [
uploadTaskId,
file,
uploadStatus,
uploadingProgress,
attachment
];
}
@@ -0,0 +1,64 @@
import 'package:collection/collection.dart';
import 'package:tmail_ui_user/features/upload/domain/model/upload_task_id.dart';
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_state.dart';
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_status.dart';
typedef UpdateFileUploadingState = UploadFileState? Function(UploadFileState? currentState);
typedef MatchedState = bool Function(UploadFileState? state);
class UploadFileStateList {
final List<UploadFileState?> _uploadingStateFiles = <UploadFileState?>[];
List<UploadFileState?> get uploadingStateFiles => _uploadingStateFiles.toList(growable: false);
UploadFileStateList add(UploadFileState element) {
_uploadingStateFiles.add(element);
return this;
}
UploadFileStateList updateElementBy(
MatchedState matchedState,
UpdateFileUploadingState updateFileUploadingState,
) {
final matchIndex = _uploadingStateFiles.indexWhere((element) => matchedState(element));
if (matchIndex >= 0) {
_uploadingStateFiles[matchIndex] = updateFileUploadingState(_uploadingStateFiles[matchIndex]);
}
return this;
}
UploadFileStateList updateElementByUploadTaskId(
UploadTaskId uploadTaskId,
UpdateFileUploadingState updateFileUploadingState,
) {
return updateElementBy(
(state) => state?.uploadTaskId == uploadTaskId,
updateFileUploadingState
);
}
bool get allSuccess {
if (_uploadingStateFiles.isEmpty) {
return false;
}
return _uploadingStateFiles
.whereNotNull()
.every((file) => file.uploadStatus == UploadFileStatus.succeed);
}
void clear() {
_uploadingStateFiles.clear();
}
void deleteElementByUploadTaskId(UploadTaskId uploadTaskId) {
final fileState = _uploadingStateFiles
.firstWhereOrNull((fileState) => fileState?.uploadTaskId == uploadTaskId);
if (fileState != null) {
fileState.cancelToken?.cancel();
_uploadingStateFiles.remove(fileState);
}
}
}
@@ -0,0 +1,12 @@
enum UploadFileStatus {
waiting,
uploading,
uploadFailed,
succeed
}
extension UploadFileStatusExtension on UploadFileStatus {
bool get completed =>
this == UploadFileStatus.uploadFailed || this == UploadFileStatus.succeed;
}