Add preparing state to attachment upload state
Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
@@ -308,12 +308,7 @@ class Channel {
|
||||
attachments: message.attachments?.map(
|
||||
(it) {
|
||||
if (it.uploadState.isSuccess) return it;
|
||||
return it.copyWith(
|
||||
uploadState: UploadState.inProgress(
|
||||
uploaded: 0,
|
||||
total: it.file?.size ?? it.extraData['file_size'],
|
||||
),
|
||||
);
|
||||
return it.copyWith(uploadState: UploadState.preparing());
|
||||
},
|
||||
)?.toList(),
|
||||
);
|
||||
@@ -370,12 +365,7 @@ class Channel {
|
||||
attachments: message.attachments?.map(
|
||||
(it) {
|
||||
if (it.uploadState.isSuccess) return it;
|
||||
return it.copyWith(
|
||||
uploadState: UploadState.inProgress(
|
||||
uploaded: 0,
|
||||
total: it.file?.size ?? it.extraData['file_size'],
|
||||
),
|
||||
);
|
||||
return it.copyWith(uploadState: UploadState.preparing());
|
||||
},
|
||||
)?.toList(),
|
||||
);
|
||||
|
||||
@@ -10,6 +10,9 @@ part 'attachment_file.g.dart';
|
||||
/// Union class to hold various [UploadState] of a attachment.
|
||||
@freezed
|
||||
abstract class UploadState with _$UploadState {
|
||||
/// Preparing state of the union
|
||||
const factory UploadState.preparing() = Preparing;
|
||||
|
||||
/// InProgress state of the union
|
||||
const factory UploadState.inProgress({int uploaded, int total}) = InProgress;
|
||||
|
||||
@@ -26,6 +29,9 @@ abstract class UploadState with _$UploadState {
|
||||
|
||||
/// Helper extension for UploadState
|
||||
extension UploadStateX on UploadState {
|
||||
/// Returns true if state is [Preparing]
|
||||
bool get isPreparing => this is Preparing;
|
||||
|
||||
/// Returns true if state is [InProgress]
|
||||
bool get isInProgress => this is InProgress;
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ part of 'attachment_file.dart';
|
||||
T _$identity<T>(T value) => value;
|
||||
UploadState _$UploadStateFromJson(Map<String, dynamic> json) {
|
||||
switch (json['runtimeType'] as String) {
|
||||
case 'preparing':
|
||||
return Preparing.fromJson(json);
|
||||
case 'inProgress':
|
||||
return InProgress.fromJson(json);
|
||||
case 'success':
|
||||
@@ -26,6 +28,11 @@ UploadState _$UploadStateFromJson(Map<String, dynamic> json) {
|
||||
class _$UploadStateTearOff {
|
||||
const _$UploadStateTearOff();
|
||||
|
||||
// ignore: unused_element
|
||||
Preparing preparing() {
|
||||
return const Preparing();
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
InProgress inProgress({int uploaded, int total}) {
|
||||
return InProgress(
|
||||
@@ -60,12 +67,14 @@ const $UploadState = _$UploadStateTearOff();
|
||||
mixin _$UploadState {
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object>({
|
||||
@required TResult preparing(),
|
||||
@required TResult inProgress(int uploaded, int total),
|
||||
@required TResult success(),
|
||||
@required TResult failed(String error),
|
||||
});
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object>({
|
||||
TResult preparing(),
|
||||
TResult inProgress(int uploaded, int total),
|
||||
TResult success(),
|
||||
TResult failed(String error),
|
||||
@@ -73,12 +82,14 @@ mixin _$UploadState {
|
||||
});
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object>({
|
||||
@required TResult preparing(Preparing value),
|
||||
@required TResult inProgress(InProgress value),
|
||||
@required TResult success(Success value),
|
||||
@required TResult failed(Failed value),
|
||||
});
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object>({
|
||||
TResult preparing(Preparing value),
|
||||
TResult inProgress(InProgress value),
|
||||
TResult success(Success value),
|
||||
TResult failed(Failed value),
|
||||
@@ -103,6 +114,118 @@ class _$UploadStateCopyWithImpl<$Res> implements $UploadStateCopyWith<$Res> {
|
||||
final $Res Function(UploadState) _then;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $PreparingCopyWith<$Res> {
|
||||
factory $PreparingCopyWith(Preparing value, $Res Function(Preparing) then) =
|
||||
_$PreparingCopyWithImpl<$Res>;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$PreparingCopyWithImpl<$Res> extends _$UploadStateCopyWithImpl<$Res>
|
||||
implements $PreparingCopyWith<$Res> {
|
||||
_$PreparingCopyWithImpl(Preparing _value, $Res Function(Preparing) _then)
|
||||
: super(_value, (v) => _then(v as Preparing));
|
||||
|
||||
@override
|
||||
Preparing get _value => super._value as Preparing;
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
|
||||
/// @nodoc
|
||||
class _$Preparing implements Preparing {
|
||||
const _$Preparing();
|
||||
|
||||
factory _$Preparing.fromJson(Map<String, dynamic> json) =>
|
||||
_$_$PreparingFromJson(json);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'UploadState.preparing()';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) || (other is Preparing);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => runtimeType.hashCode;
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object>({
|
||||
@required TResult preparing(),
|
||||
@required TResult inProgress(int uploaded, int total),
|
||||
@required TResult success(),
|
||||
@required TResult failed(String error),
|
||||
}) {
|
||||
assert(preparing != null);
|
||||
assert(inProgress != null);
|
||||
assert(success != null);
|
||||
assert(failed != null);
|
||||
return preparing();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object>({
|
||||
TResult preparing(),
|
||||
TResult inProgress(int uploaded, int total),
|
||||
TResult success(),
|
||||
TResult failed(String error),
|
||||
@required TResult orElse(),
|
||||
}) {
|
||||
assert(orElse != null);
|
||||
if (preparing != null) {
|
||||
return preparing();
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object>({
|
||||
@required TResult preparing(Preparing value),
|
||||
@required TResult inProgress(InProgress value),
|
||||
@required TResult success(Success value),
|
||||
@required TResult failed(Failed value),
|
||||
}) {
|
||||
assert(preparing != null);
|
||||
assert(inProgress != null);
|
||||
assert(success != null);
|
||||
assert(failed != null);
|
||||
return preparing(this);
|
||||
}
|
||||
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object>({
|
||||
TResult preparing(Preparing value),
|
||||
TResult inProgress(InProgress value),
|
||||
TResult success(Success value),
|
||||
TResult failed(Failed value),
|
||||
@required TResult orElse(),
|
||||
}) {
|
||||
assert(orElse != null);
|
||||
if (preparing != null) {
|
||||
return preparing(this);
|
||||
}
|
||||
return orElse();
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$_$PreparingToJson(this)..['runtimeType'] = 'preparing';
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Preparing implements UploadState {
|
||||
const factory Preparing() = _$Preparing;
|
||||
|
||||
factory Preparing.fromJson(Map<String, dynamic> json) = _$Preparing.fromJson;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $InProgressCopyWith<$Res> {
|
||||
factory $InProgressCopyWith(
|
||||
@@ -176,10 +299,12 @@ class _$InProgress implements InProgress {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object>({
|
||||
@required TResult preparing(),
|
||||
@required TResult inProgress(int uploaded, int total),
|
||||
@required TResult success(),
|
||||
@required TResult failed(String error),
|
||||
}) {
|
||||
assert(preparing != null);
|
||||
assert(inProgress != null);
|
||||
assert(success != null);
|
||||
assert(failed != null);
|
||||
@@ -189,6 +314,7 @@ class _$InProgress implements InProgress {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object>({
|
||||
TResult preparing(),
|
||||
TResult inProgress(int uploaded, int total),
|
||||
TResult success(),
|
||||
TResult failed(String error),
|
||||
@@ -204,10 +330,12 @@ class _$InProgress implements InProgress {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object>({
|
||||
@required TResult preparing(Preparing value),
|
||||
@required TResult inProgress(InProgress value),
|
||||
@required TResult success(Success value),
|
||||
@required TResult failed(Failed value),
|
||||
}) {
|
||||
assert(preparing != null);
|
||||
assert(inProgress != null);
|
||||
assert(success != null);
|
||||
assert(failed != null);
|
||||
@@ -217,6 +345,7 @@ class _$InProgress implements InProgress {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object>({
|
||||
TResult preparing(Preparing value),
|
||||
TResult inProgress(InProgress value),
|
||||
TResult success(Success value),
|
||||
TResult failed(Failed value),
|
||||
@@ -288,10 +417,12 @@ class _$Success implements Success {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object>({
|
||||
@required TResult preparing(),
|
||||
@required TResult inProgress(int uploaded, int total),
|
||||
@required TResult success(),
|
||||
@required TResult failed(String error),
|
||||
}) {
|
||||
assert(preparing != null);
|
||||
assert(inProgress != null);
|
||||
assert(success != null);
|
||||
assert(failed != null);
|
||||
@@ -301,6 +432,7 @@ class _$Success implements Success {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object>({
|
||||
TResult preparing(),
|
||||
TResult inProgress(int uploaded, int total),
|
||||
TResult success(),
|
||||
TResult failed(String error),
|
||||
@@ -316,10 +448,12 @@ class _$Success implements Success {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object>({
|
||||
@required TResult preparing(Preparing value),
|
||||
@required TResult inProgress(InProgress value),
|
||||
@required TResult success(Success value),
|
||||
@required TResult failed(Failed value),
|
||||
}) {
|
||||
assert(preparing != null);
|
||||
assert(inProgress != null);
|
||||
assert(success != null);
|
||||
assert(failed != null);
|
||||
@@ -329,6 +463,7 @@ class _$Success implements Success {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object>({
|
||||
TResult preparing(Preparing value),
|
||||
TResult inProgress(InProgress value),
|
||||
TResult success(Success value),
|
||||
TResult failed(Failed value),
|
||||
@@ -416,10 +551,12 @@ class _$Failed implements Failed {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult when<TResult extends Object>({
|
||||
@required TResult preparing(),
|
||||
@required TResult inProgress(int uploaded, int total),
|
||||
@required TResult success(),
|
||||
@required TResult failed(String error),
|
||||
}) {
|
||||
assert(preparing != null);
|
||||
assert(inProgress != null);
|
||||
assert(success != null);
|
||||
assert(failed != null);
|
||||
@@ -429,6 +566,7 @@ class _$Failed implements Failed {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeWhen<TResult extends Object>({
|
||||
TResult preparing(),
|
||||
TResult inProgress(int uploaded, int total),
|
||||
TResult success(),
|
||||
TResult failed(String error),
|
||||
@@ -444,10 +582,12 @@ class _$Failed implements Failed {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult map<TResult extends Object>({
|
||||
@required TResult preparing(Preparing value),
|
||||
@required TResult inProgress(InProgress value),
|
||||
@required TResult success(Success value),
|
||||
@required TResult failed(Failed value),
|
||||
}) {
|
||||
assert(preparing != null);
|
||||
assert(inProgress != null);
|
||||
assert(success != null);
|
||||
assert(failed != null);
|
||||
@@ -457,6 +597,7 @@ class _$Failed implements Failed {
|
||||
@override
|
||||
@optionalTypeArgs
|
||||
TResult maybeMap<TResult extends Object>({
|
||||
TResult preparing(Preparing value),
|
||||
TResult inProgress(InProgress value),
|
||||
TResult success(Success value),
|
||||
TResult failed(Failed value),
|
||||
|
||||
@@ -23,6 +23,13 @@ Map<String, dynamic> _$AttachmentFileToJson(AttachmentFile instance) =>
|
||||
'size': instance.size,
|
||||
};
|
||||
|
||||
_$Preparing _$_$PreparingFromJson(Map json) {
|
||||
return _$Preparing();
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$_$PreparingToJson(_$Preparing instance) =>
|
||||
<String, dynamic>{};
|
||||
|
||||
_$InProgress _$_$InProgressFromJson(Map json) {
|
||||
return _$InProgress(
|
||||
uploaded: json['uploaded'] as int,
|
||||
|
||||
@@ -11,6 +11,7 @@ class AttachmentUploadStateBuilder extends StatelessWidget {
|
||||
final FailedBuilder failedBuilder;
|
||||
final WidgetBuilder successBuilder;
|
||||
final InProgressBuilder inProgressBuilder;
|
||||
final WidgetBuilder preparingBuilder;
|
||||
|
||||
const AttachmentUploadStateBuilder({
|
||||
Key key,
|
||||
@@ -19,6 +20,7 @@ class AttachmentUploadStateBuilder extends StatelessWidget {
|
||||
this.failedBuilder,
|
||||
this.successBuilder,
|
||||
this.inProgressBuilder,
|
||||
this.preparingBuilder,
|
||||
}) : assert(message != null),
|
||||
assert(attachment != null),
|
||||
super(key: key);
|
||||
@@ -51,7 +53,11 @@ class AttachmentUploadStateBuilder extends StatelessWidget {
|
||||
var success = successBuilder;
|
||||
success ??= (context) => _SuccessState();
|
||||
|
||||
var preparing = preparingBuilder;
|
||||
preparing ??= (context) => _PreparingState(attachmentId: attachmentId);
|
||||
|
||||
return attachment.uploadState.when(
|
||||
preparing: () => preparing(context),
|
||||
inProgress: (sent, total) => inProgress(context, sent, total),
|
||||
success: () => success(context),
|
||||
failed: (error) => failed(context, error),
|
||||
@@ -94,6 +100,42 @@ class _IconButton extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _PreparingState extends StatelessWidget {
|
||||
final String attachmentId;
|
||||
|
||||
const _PreparingState({
|
||||
Key key,
|
||||
@required this.attachmentId,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final channel = StreamChannel.of(context).channel;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: _IconButton(
|
||||
icon: StreamSvgIcon.close(
|
||||
color: StreamChatTheme.of(context).colorTheme.white,
|
||||
),
|
||||
onPressed: () => channel.cancelAttachmentUpload(attachmentId),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: UploadProgressIndicator(
|
||||
uploaded: 0,
|
||||
total: double.maxFinite.toInt(),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _InProgressState extends StatelessWidget {
|
||||
final int sent;
|
||||
final int total;
|
||||
|
||||
@@ -181,6 +181,14 @@ class FileAttachment extends AttachmentWidget {
|
||||
final attachmentId = attachment.id;
|
||||
var trailingWidget = trailing;
|
||||
trailingWidget ??= attachment.uploadState?.when(
|
||||
preparing: () => Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: _buildButton(
|
||||
icon: StreamSvgIcon.close(color: theme.colorTheme.white),
|
||||
fillColor: theme.colorTheme.overlayDark,
|
||||
onPressed: () => channel.cancelAttachmentUpload(attachmentId),
|
||||
),
|
||||
),
|
||||
inProgress: (_, __) => Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: _buildButton(
|
||||
@@ -232,6 +240,16 @@ class FileAttachment extends AttachmentWidget {
|
||||
color: theme.colorTheme.grey,
|
||||
);
|
||||
return attachment.uploadState?.when(
|
||||
preparing: () {
|
||||
return UploadProgressIndicator(
|
||||
uploaded: 0,
|
||||
total: double.maxFinite.toInt(),
|
||||
showBackground: false,
|
||||
padding: EdgeInsets.zero,
|
||||
textStyle: textStyle,
|
||||
progressIndicatorColor: theme.colorTheme.accentBlue,
|
||||
);
|
||||
},
|
||||
inProgress: (sent, total) {
|
||||
return UploadProgressIndicator(
|
||||
uploaded: sent,
|
||||
|
||||
@@ -11,7 +11,8 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
stream_chat_flutter_core: ^1.1.0-beta
|
||||
stream_chat_flutter_core:
|
||||
path: ../stream_chat_flutter_core
|
||||
flutter_app_badger: ^1.1.2
|
||||
photo_view: ^0.10.3
|
||||
rxdart: ^0.25.0
|
||||
|
||||
@@ -10,7 +10,8 @@ environment:
|
||||
flutter: ">=1.17.0"
|
||||
|
||||
dependencies:
|
||||
stream_chat: ^1.1.0-beta
|
||||
stream_chat:
|
||||
path: ../stream_chat
|
||||
flutter:
|
||||
sdk: flutter
|
||||
rxdart: ^0.25.0
|
||||
|
||||
@@ -13,7 +13,8 @@ dependencies:
|
||||
path: ^1.7.0
|
||||
path_provider: ^1.6.27
|
||||
sqlite3_flutter_libs: ^0.4.0+1
|
||||
stream_chat: ^1.1.0-beta
|
||||
stream_chat:
|
||||
path: ../stream_chat
|
||||
|
||||
dev_dependencies:
|
||||
test: ^1.15.7
|
||||
|
||||
Reference in New Issue
Block a user