-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TW-1586: update the view of downloading file: process, cancel and mul…
…tiple downloading
- Loading branch information
1 parent
9b9c944
commit cd95d8a
Showing
7 changed files
with
444 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,191 @@ | ||
import 'dart:async'; | ||
import 'dart:io'; | ||
|
||
import 'package:dartz/dartz.dart' hide State, OpenFile; | ||
import 'package:fluffychat/app_state/failure.dart'; | ||
import 'package:fluffychat/app_state/success.dart'; | ||
import 'package:fluffychat/di/global/get_it_initializer.dart'; | ||
import 'package:fluffychat/presentation/model/chat/downloading_state_presentation_model.dart'; | ||
import 'package:fluffychat/utils/manager/download_manager/download_file_state.dart'; | ||
import 'package:fluffychat/utils/manager/download_manager/download_manager.dart'; | ||
import 'package:fluffychat/utils/matrix_sdk_extensions/download_file_extension.dart'; | ||
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart'; | ||
import 'package:fluffychat/utils/platform_infos.dart'; | ||
import 'package:fluffychat/widgets/file_widget/download_file_tile_widget.dart'; | ||
import 'package:fluffychat/widgets/file_widget/file_tile_widget.dart'; | ||
import 'package:fluffychat/widgets/file_widget/message_file_tile_style.dart'; | ||
import 'package:fluffychat/widgets/mixins/handle_download_and_preview_file_mixin.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'package:matrix/matrix.dart'; | ||
|
||
class MessageDownloadContent extends StatelessWidget { | ||
class MessageDownloadContent extends StatefulWidget { | ||
final Event event; | ||
final void Function(Event event)? onFileTapped; | ||
|
||
final String? highlightText; | ||
|
||
const MessageDownloadContent( | ||
this.event, { | ||
Key? key, | ||
this.onFileTapped, | ||
this.highlightText, | ||
}) : super(key: key); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final filename = event.filename; | ||
final filetype = event.fileType; | ||
final sizeString = event.sizeString; | ||
State<MessageDownloadContent> createState() => _MessageDownloadContentState(); | ||
} | ||
|
||
class _MessageDownloadContentState extends State<MessageDownloadContent> | ||
with HandleDownloadAndPreviewFileMixin { | ||
final downloadManager = getIt.get<DownloadManager>(); | ||
|
||
final downloadFileStateNotifier = ValueNotifier<DownloadPresentationState>( | ||
const NotDownloadPresentationState(), | ||
); | ||
|
||
StreamSubscription<Either<Failure, Success>>? streamSubscription; | ||
|
||
@override | ||
void initState() { | ||
super.initState(); | ||
checkDownloadFileState(); | ||
} | ||
|
||
void checkDownloadFileState() async { | ||
if (!PlatformInfos.isWeb) { | ||
final filePath = await widget.event.getFileNameInAppDownload(); | ||
final file = File(filePath); | ||
if (await file.exists() && | ||
await file.length() == widget.event.getFileSize()) { | ||
downloadFileStateNotifier.value = DownloadedPresentationState( | ||
filePath: filePath, | ||
); | ||
return; | ||
} | ||
} | ||
setupListeningForStreamSubcription(); | ||
if (streamSubscription != null) { | ||
downloadFileStateNotifier.value = const DownloadingPresentationState(); | ||
} | ||
} | ||
|
||
Logs().i( | ||
'filename: $filename, filetype: $filetype, sizeString: $sizeString, content: ${event.content}', | ||
void setupListeningForStreamSubcription() { | ||
streamSubscription = downloadManager | ||
.getDownloadStateStream(widget.event.eventId) | ||
?.listen(setupDownloadingProcess); | ||
} | ||
|
||
void setupDownloadingProcess(Either<Failure, Success> event) { | ||
event.fold( | ||
(failure) { | ||
Logs().e('MessageDownloadContent::onDownloadingProcess(): $failure'); | ||
downloadFileStateNotifier.value = const NotDownloadPresentationState(); | ||
}, | ||
(success) { | ||
if (success is DownloadingFileState) { | ||
if (success.total != 0) { | ||
downloadFileStateNotifier.value = DownloadingPresentationState( | ||
receive: success.receive, | ||
total: success.total, | ||
); | ||
} | ||
} else if (success is DownloadNativeFileSuccessState) { | ||
downloadFileStateNotifier.value = DownloadedPresentationState( | ||
filePath: success.filePath, | ||
); | ||
} else if (success is DownloadMatrixFileSuccessState) { | ||
downloadFileStateNotifier.value = FileWebDownloadedPresentationState( | ||
matrixFile: success.matrixFile, | ||
); | ||
} | ||
}, | ||
); | ||
return InkWell( | ||
onTap: onFileTapped != null | ||
? () { | ||
onFileTapped?.call(event); | ||
} | ||
: null, | ||
child: FileTileWidget( | ||
mimeType: event.mimeType, | ||
fileType: filetype, | ||
filename: filename, | ||
highlightText: highlightText, | ||
sizeString: sizeString, | ||
style: MessageFileTileStyle(), | ||
), | ||
} | ||
|
||
@override | ||
void dispose() { | ||
streamSubscription?.cancel(); | ||
downloadFileStateNotifier.dispose(); | ||
super.dispose(); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
final filename = widget.event.filename; | ||
final filetype = widget.event.fileType; | ||
final sizeString = widget.event.sizeString; | ||
return ValueListenableBuilder( | ||
valueListenable: downloadFileStateNotifier, | ||
builder: (context, DownloadPresentationState state, child) { | ||
if (state is DownloadedPresentationState) { | ||
return InkWell( | ||
onTap: () async { | ||
openDownloadedFileForPreview( | ||
filePath: state.filePath, | ||
mimeType: widget.event.mimeType, | ||
); | ||
}, | ||
child: FileTileWidget( | ||
mimeType: widget.event.mimeType, | ||
fileType: filetype, | ||
filename: filename, | ||
highlightText: widget.highlightText, | ||
sizeString: sizeString, | ||
style: const MessageFileTileStyle(), | ||
), | ||
); | ||
} else if (state is DownloadingPresentationState) { | ||
return DownloadFileTileWidget( | ||
mimeType: widget.event.mimeType, | ||
fileType: filetype, | ||
filename: filename, | ||
highlightText: widget.highlightText, | ||
sizeString: sizeString, | ||
style: const MessageFileTileStyle(), | ||
downloadFileStateNotifier: downloadFileStateNotifier, | ||
onCancelDownload: () { | ||
downloadFileStateNotifier.value = | ||
const NotDownloadPresentationState(); | ||
downloadManager.cancelDownload(widget.event.eventId); | ||
}, | ||
); | ||
} else if (state is FileWebDownloadedPresentationState) { | ||
return InkWell( | ||
onTap: () { | ||
handlePreviewWeb( | ||
event: widget.event, | ||
context: context, | ||
); | ||
}, | ||
child: FileTileWidget( | ||
mimeType: widget.event.mimeType, | ||
fileType: filetype, | ||
filename: filename, | ||
highlightText: widget.highlightText, | ||
sizeString: sizeString, | ||
style: const MessageFileTileStyle(), | ||
), | ||
); | ||
} | ||
|
||
return InkWell( | ||
onTap: () { | ||
downloadFileStateNotifier.value = | ||
const DownloadingPresentationState(); | ||
downloadManager.download( | ||
event: widget.event, | ||
); | ||
setupListeningForStreamSubcription(); | ||
}, | ||
child: DownloadFileTileWidget( | ||
mimeType: widget.event.mimeType, | ||
fileType: filetype, | ||
filename: filename, | ||
highlightText: widget.highlightText, | ||
sizeString: sizeString, | ||
downloadFileStateNotifier: downloadFileStateNotifier, | ||
style: const MessageFileTileStyle(), | ||
), | ||
); | ||
}, | ||
); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
lib/presentation/model/chat/downloading_state_presentation_model.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import 'package:equatable/equatable.dart'; | ||
import 'package:matrix/matrix.dart'; | ||
|
||
abstract class DownloadPresentationState with EquatableMixin { | ||
const DownloadPresentationState(); | ||
|
||
@override | ||
List<Object?> get props => []; | ||
} | ||
|
||
class NotDownloadPresentationState extends DownloadPresentationState { | ||
const NotDownloadPresentationState() : super(); | ||
} | ||
|
||
class DownloadedPresentationState extends DownloadPresentationState { | ||
final String filePath; | ||
|
||
const DownloadedPresentationState({required this.filePath}) : super(); | ||
|
||
@override | ||
List<Object?> get props => [filePath]; | ||
} | ||
|
||
class FileWebDownloadedPresentationState extends DownloadPresentationState { | ||
final MatrixFile matrixFile; | ||
|
||
const FileWebDownloadedPresentationState({required this.matrixFile}) | ||
: super(); | ||
|
||
@override | ||
List<Object?> get props => [matrixFile]; | ||
} | ||
|
||
class DownloadingPresentationState extends DownloadPresentationState { | ||
final int? receive; | ||
|
||
final int? total; | ||
|
||
const DownloadingPresentationState({ | ||
this.receive, | ||
this.total, | ||
}); | ||
|
||
@override | ||
List<Object?> get props => [receive, total]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,11 @@ | ||
extension DoubleExtension on int { | ||
String bytesToMB() { | ||
return (this / (1024 * 1024)).toString(); | ||
extension IntExtension on int { | ||
String bytesToMB({int? placeDecimal}) { | ||
return (this / (1024 * 1024)).toStringAsFixed(placeDecimal ?? 0); | ||
} | ||
|
||
String bytesToKB({int? placeDecimal}) { | ||
return (this / 1024).toStringAsFixed(placeDecimal ?? 0); | ||
} | ||
|
||
static const oneKB = 1024 * 1024; | ||
} |
Oops, something went wrong.