Skip to content

Commit

Permalink
Release 3.0.13
Browse files Browse the repository at this point in the history
  • Loading branch information
intoxicated committed May 17, 2021
1 parent d41b00e commit b4bc878
Show file tree
Hide file tree
Showing 17 changed files with 237 additions and 149 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## [3.0.13] - May 17, 2021
* Fixed file type mis mapping bug
* Added `cancelUploadingFileMessage` in `BaseChannel`
* Added `joinedAt` in `GroupChannel`
* Improved stability

## [3.0.12] - Apr 25, 2021
* Fixed to apply option to `SendbirdSdk` properly
* Fixed `sendFileMessage` progress inconsistency
Expand Down
150 changes: 88 additions & 62 deletions lib/core/channel/base/base_channel_messages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -150,78 +150,104 @@ extension Messages on BaseChannel {
pending.sender = Sender.fromUser(_sdk.state.currentUser, this);

final queue = _sdk.getMsgQueue(channelUrl);
queue.enqueue(AsyncSimpleTask(() async {
if (params.uploadFile.hasBinary) {
upload = await _sdk.api
.uploadFile(
channelUrl: channelUrl,
requestId: pending.requestId,
params: params,
progress: progress)
.timeout(
Duration(seconds: _sdk.options.fileTransferTimeout),
onTimeout: () {
logger.e('upload timeout');
if (onCompleted != null) {
onCompleted(
pending..sendingStatus = MessageSendingStatus.failed,
SBError(
message: 'upload timeout',
code: ErrorCode.fileUploadTimeout,
),
);
final task = AsyncSimpleTask(
() async {
if (params.uploadFile.hasBinary) {
try {
upload = await _sdk.api
.uploadFile(
channelUrl: channelUrl,
requestId: pending.requestId,
params: params,
progress: progress)
.timeout(
Duration(seconds: _sdk.options.fileTransferTimeout),
onTimeout: () {
logger.e('upload timeout');
if (onCompleted != null) {
onCompleted(
pending..sendingStatus = MessageSendingStatus.failed,
SBError(
message: 'upload timeout',
code: ErrorCode.fileUploadTimeout,
),
);
}
return;
},
);
if (upload == null) {
throw SBError(code: ErrorCode.fileUploadTimeout);
}
return;
},
fileSize = upload.fileSize;
url = upload.url;
} catch (e) {
rethrow;
}
}

if (fileSize != null) params.uploadFile.fileSize = fileSize;
if (url != null) params.uploadFile.url = url;

final cmd = Command.buildFileMessage(
channelUrl: channelUrl,
params: params,
requestId: pending.requestId,
requireAuth: upload?.requireAuth,
thumbnails: upload?.thumbnails,
);
if (upload == null) throw SBError(code: ErrorCode.fileUploadTimeout);

fileSize = upload.fileSize;
url = upload.url;
}

if (fileSize != null) params.uploadFile.fileSize = fileSize;
if (url != null) params.uploadFile.url = url;

final cmd = Command.buildFileMessage(
channelUrl: channelUrl,
params: params,
requestId: pending.requestId,
requireAuth: upload?.requireAuth,
thumbnails: upload?.thumbnails,
);

final msgFromPayload = BaseMessage.msgFromJson<FileMessage>(
cmd.payload,
channelType: channelType,
);
final msgFromPayload = BaseMessage.msgFromJson<FileMessage>(
cmd.payload,
channelType: channelType,
);

if (!_sdk.state.hasActiveUser) {
final error = ConnectionRequiredError();
msgFromPayload
..errorCode = error.code
..sendingStatus = MessageSendingStatus.failed;
if (onCompleted != null) onCompleted(msgFromPayload, error);
return msgFromPayload;
}

_sdk.cmdManager.sendCommand(cmd).then((cmdResult) {
final msg = BaseMessage.msgFromJson<FileMessage>(cmdResult.payload);
if (onCompleted != null) onCompleted(msg, null);
}).catchError((e) {
// pending.errorCode = e?.code ?? ErrorCode.unknownError;
pending
..errorCode = e.code
..sendingStatus = MessageSendingStatus.failed;
if (onCompleted != null) onCompleted(pending, e);
});
}));
if (!_sdk.state.hasActiveUser) {
final error = ConnectionRequiredError();
msgFromPayload
..errorCode = error.code
..sendingStatus = MessageSendingStatus.failed;
if (onCompleted != null) onCompleted(msgFromPayload, error);
return msgFromPayload;
}

_sdk.cmdManager.sendCommand(cmd).then((cmdResult) {
final msg = BaseMessage.msgFromJson<FileMessage>(cmdResult.payload);
if (onCompleted != null) onCompleted(msg, null);
}).catchError((e) {
// pending.errorCode = e?.code ?? ErrorCode.unknownError;
pending
..errorCode = e.code
..sendingStatus = MessageSendingStatus.failed;
if (onCompleted != null) onCompleted(pending, e);
});
},
onCancel: () {
if (onCompleted != null) onCompleted(pending, OperationCancelError());
},
);

queue.enqueue(task);
_sdk.setUploadTask(pending.requestId, task);
_sdk.setMsgQueue(channelUrl, queue);

return pending;
}

bool cancelUploadingFileMessage(String requestId) {
if (requestId == null || requestId == '') {
throw InvalidParameterError();
}
final task = _sdk.getUploadTask(requestId);
if (task == null) {
throw NotFoundError();
}

final queue = _sdk.getMsgQueue(channelUrl);
_sdk.api.cancelUploadingFile(requestId);
return queue.cancel(task.hashCode);
}

/// Resends failed [FileMessage] on this channel with [message].
///
/// It returns [FileMessage] with [MessageSendingStatus.pending] and
Expand Down
8 changes: 7 additions & 1 deletion lib/core/channel/group/group_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,15 @@ class GroupChannel extends BaseChannel {
/// User who invited
Member inviter;

/// The time stamp when current user got a invitation
/// Timestamp when current user got a invitation
/// from other user in the channel
@JsonKey(defaultValue: 0)
int invitedAt;

/// Timestamp when current user joined on this channel
@JsonKey(name: 'joined_ts', defaultValue: 0)
int joinedAt;

/// True if this channel is hidden
bool isHidden;

Expand Down Expand Up @@ -166,6 +171,7 @@ class GroupChannel extends BaseChannel {
this.members,
this.memberCount,
this.joinedMemberCount,
this.joinedAt,
this.myPushTriggerOption,
this.myMemberState,
this.myRole,
Expand Down
2 changes: 2 additions & 0 deletions lib/core/channel/group/group_channel_operations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ extension GroupChannelOperations on GroupChannel {
/// [ChannelEventHandler.onUserLeaved] will be invoked.
Future<void> leave() async {
await _sdk.api.leaveGroupChannel(channelUrl: channelUrl);
invitedAt = 0;
joinedAt = 0;
}

/// Resets (clear) any previous messages on this channel.
Expand Down
9 changes: 6 additions & 3 deletions lib/core/message/base_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,12 @@ class BaseMessage {
reactions,
);

static T msgFromJson<T extends BaseMessage>(Map<String, dynamic> json,
{ChannelType channelType}) {
final cmd = json['type'] as String;
static T msgFromJson<T extends BaseMessage>(
Map<String, dynamic> json, {
ChannelType channelType,
String type,
}) {
final cmd = type ?? json['type'] as String;
T msg;
//basemessage backward compatibility -
if (json['custom'] != null) json['data'] = json['custom'];
Expand Down
4 changes: 4 additions & 0 deletions lib/core/models/error.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,7 @@ class InvalidAccessTokenError extends SBError {
}

class UnknownError extends SBError {}

class NotFoundError extends SBError {}

class OperationCancelError extends SBError {}
7 changes: 1 addition & 6 deletions lib/managers/command_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,13 @@ class CommandManager with SdkAccessor {
Future<Command> sendCommand(Command cmd) async {
if (appState.currentUser == null) {
//NOTE: some test cases execute async socket data
//even after test case was finished
// print('[E] ${this.hashCode}');
logger.e('sendCommand: connection is requred');
throw ConnectionRequiredError();
}
if (cmd == null) {
logger.e('sendCommand: command parameter is null');
throw InvalidParameterError();
}
// if (!webSocket.isConnected()) {
// logger.e('sendCommand: Websocket connection is closed');
// throw WebSocketConnectionClosedError();
// }

try {
await ConnectionManager.readyToExecuteWSRequest();
Expand Down Expand Up @@ -668,6 +662,7 @@ class CommandManager with SdkAccessor {
if (member.isCurrentUser) {
channel.myMemberState = MemberState.none;
channel.invitedAt = 0;
channel.joinedAt = 0;
channel.clearUnreadCount();
if (!channel.isPublic) {
channel.removeFromCache();
Expand Down
29 changes: 17 additions & 12 deletions lib/sdk/internal/sendbird_sdk_internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import 'package:sendbird_sdk/utils/async/async_queue.dart';
import 'package:sendbird_sdk/utils/logger.dart';
import 'package:sendbird_sdk/utils/parsers.dart';

const sdk_version = '3.0.12';
const sdk_version = '3.0.13';
const platform = 'flutter';

/// Internal implementation for main class. Do not directly access this class.
Expand All @@ -42,12 +42,14 @@ class SendbirdSdkInternal with WidgetsBindingObserver {
Completer<User> _loginCompleter;

Options _options;
AsyncQueue _commandQueue = AsyncQueue<String>();
Map<String, AsyncQueue> _messageQueues = {};
Map<String, AsyncSimpleTask> _uploads = {};

Timer _reconnectTimer;
ConnectivityResult _connectionResult;
StreamSubscription _connectionSub;
AsyncQueue _commandQueue = AsyncQueue<String>();

Map<String, String> _extensions = {};
List<String> _extraDatas = [
constants.sbExtraDataPremiumFeatureList,
Expand Down Expand Up @@ -90,6 +92,9 @@ class SendbirdSdkInternal with WidgetsBindingObserver {
_messageQueues[channelUrl] ?? AsyncQueue();
void setMsgQueue(String channelUrl, AsyncQueue queue) =>
_messageQueues[channelUrl] = queue;
AsyncSimpleTask getUploadTask(String requestId) => _uploads[requestId];
void setUploadTask(String requestId, AsyncSimpleTask task) =>
_uploads[requestId] = task;

// socket callbacks

Expand Down Expand Up @@ -123,22 +128,19 @@ class SendbirdSdkInternal with WidgetsBindingObserver {
//NOTE: compute does not gaurantee the order of commands
final op = AsyncTask<String>(func: parseCommand, arg: stringCommand);
final cmd = await _commandQueue.enqueue(op);
// cmdManager.processCommand(cmd);
runZoned(() async {

runZonedGuarded(() async {
try {
_cmdManager.processCommand(cmd);
} catch (e) {
rethrow;
}
}, onError: (e, s) {
//handle error how to toss this..?
//get waiting func and error?
}, (e, trace) {
if (_loginCompleter != null) {
_loginCompleter?.completeError(e);
} else {
logger.e('fatal error thrown ${e.toString()}');
}
// throw e;
});
}

Expand Down Expand Up @@ -270,6 +272,13 @@ class SendbirdSdkInternal with WidgetsBindingObserver {
_cmdManager = CommandManager();
_streamManager.reset();

_commandQueue.cleanUp();
_messageQueues.forEach((key, q) => q.cleanUp());
_messageQueues = {};
_uploads.forEach((key, value) => _api.cancelUploadingFile(key));
_uploads = {};
_loginCompleter = null;

_api = ApiClient();
_api.initialize(appId: _state.appId);

Expand All @@ -280,10 +289,6 @@ class SendbirdSdkInternal with WidgetsBindingObserver {
WidgetsBinding.instance?.removeObserver(this);
_connectionSub?.cancel();

_commandQueue.cleanUp();
_messageQueues = {};
_loginCompleter = null;

ConnectionManager.flushCompleters(error: ConnectionClosedError());
}

Expand Down
24 changes: 14 additions & 10 deletions lib/services/network/api_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -721,19 +721,23 @@ class ApiClient {
body['thumbnail${index + 1}'] =
'${value.width.round()},${value.height.round()}');

final res = await client.multipartRequest(
method: Method.post,
url: url,
body: body,
progress: progress,
);
return UploadResponse.fromJson(res);
try {
final res = await client.multipartRequest(
method: Method.post,
url: url,
body: body,
progress: progress,
);
return UploadResponse.fromJson(res);
} catch (_) {
rethrow;
}
}

// https://github.com/dart-lang/http/issues/424
// Future<void> cancelUploading {

// }
bool cancelUploadingFile(String requestId) {
return client.cancelUploadRequest(requestId);
}

Future<UserMessage> translateUserMessage({
@required ChannelType channelType,
Expand Down
Loading

0 comments on commit b4bc878

Please sign in to comment.