Skip to content

Commit

Permalink
TF-3157 Remove unnecessary background service worker
Browse files Browse the repository at this point in the history
  • Loading branch information
tddang-linagora committed Nov 5, 2024
1 parent c5f49b9 commit 75e8ca9
Show file tree
Hide file tree
Showing 20 changed files with 151 additions and 447 deletions.
1 change: 0 additions & 1 deletion core/lib/data/constants/constant.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ class Constant {
static const octetStreamMimeType = 'application/octet-stream';
static const pdfExtension = '.pdf';
static const imageType = 'image';
static const wsServiceWorkerBroadcastChannel = 'background-message';
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

abstract class WebSocketDatasource {
Stream<dynamic> getWebSocketChannel(Session session, AccountId accountId);
Future<WebSocketChannel> getWebSocketChannel(
Session session,
AccountId accountId);
}
Original file line number Diff line number Diff line change
@@ -1,57 +1,39 @@

import 'package:core/data/constants/constant.dart';
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/broadcast_channel/broadcast_channel.dart';
import 'dart:async';

import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart';
import 'package:jmap_dart_client/jmap/core/capability/websocket_capability.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:rxdart/transformers.dart';
import 'package:tmail_ui_user/features/push_notification/data/datasource/web_socket_datasource.dart';
import 'package:tmail_ui_user/features/push_notification/data/model/connect_web_socket_message.dart';
import 'package:tmail_ui_user/features/push_notification/data/network/web_socket_api.dart';
import 'package:tmail_ui_user/features/push_notification/domain/exceptions/web_socket_exceptions.dart';
import 'package:tmail_ui_user/features/push_notification/domain/model/web_socket_action.dart';
import 'package:tmail_ui_user/main/error/capability_validator.dart';
import 'package:tmail_ui_user/main/exceptions/exception_thrower.dart';
import 'package:universal_html/html.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

class WebSocketDatasourceImpl implements WebSocketDatasource {
final WebSocketApi _webSocketApi;
final ExceptionThrower _exceptionThrower;

const WebSocketDatasourceImpl(this._webSocketApi, this._exceptionThrower);

static const String _webSocketClosed = 'webSocketClosed';

@override
Stream getWebSocketChannel(Session session, AccountId accountId) {
return Stream
.castFrom(_getWebSocketChannel(session, accountId))
.doOnError(_exceptionThrower.throwException);
}

Stream _getWebSocketChannel(
Session session,
AccountId accountId,
) async* {
final broadcastChannel = BroadcastChannel(Constant.wsServiceWorkerBroadcastChannel);
try {
Future<WebSocketChannel> getWebSocketChannel(Session session, AccountId accountId) {
return Future.sync(() async {
_verifyWebSocketCapabilities(session, accountId);
final webSocketTicket = await _webSocketApi.getWebSocketTicket(session, accountId);
final webSocketUri = _getWebSocketUri(session, accountId);
window.navigator.serviceWorker?.controller?.postMessage(ConnectWebSocketMessage(
webSocketAction: WebSocketAction.connect,
webSocketUrl: webSocketUri.toString(),
webSocketTicket: webSocketTicket
).toJson());

yield* _webSocketListener(broadcastChannel);
} catch (e) {
logError('RemoteWebSocketDatasourceImpl::getWebSocketChannel():error: $e');
rethrow;
}
final webSocketChannel = WebSocketChannel.connect(
Uri.parse('$webSocketUri?ticket=$webSocketTicket'),
protocols: ["jmap"],
);

await webSocketChannel.ready;

return webSocketChannel;
}).catchError(_exceptionThrower.throwException);
}

void _verifyWebSocketCapabilities(Session session, AccountId accountId) {
Expand All @@ -77,14 +59,4 @@ class WebSocketDatasourceImpl implements WebSocketDatasource {

return webSocketUri;
}

Stream _webSocketListener(BroadcastChannel broadcastChannel) {
return broadcastChannel.onMessage.map((event) {
if (event.data == _webSocketClosed) {
throw WebSocketClosedException();
}

return event.data;
});
}
}
31 changes: 0 additions & 31 deletions lib/features/push_notification/data/model/web_socket_echo.dart

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart';
import 'package:tmail_ui_user/features/push_notification/data/model/web_socket_request.dart';

class WebSocketEchoRequest extends WebSocketRequest {
static const String type = 'Request';
static const String id = 'R1';
static final CapabilityIdentifier usingCapability = CapabilityIdentifier.jmapCore;
static const String method = 'Core/echo';

@override
Map<String, dynamic> toJson() {
return {
'@type': type,
'id': id,
'using': [usingCapability.value.toString()],
'methodCalls': [[method, {}, 'c0']],
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'package:fcm/model/type_name.dart';

class WebSocketPushEnableRequest {
static const String type = 'WebSocketPushEnable';

static Map<String, dynamic> toJson({
required List<TypeName> dataTypes,
}) {
return {
'@type': type,
'dataTypes': dataTypes.map((typeName) => typeName.value).toList(),
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
abstract class WebSocketRequest {
const WebSocketRequest();

Map<String, dynamic> toJson();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:tmail_ui_user/features/push_notification/data/datasource/web_socket_datasource.dart';
import 'package:tmail_ui_user/features/push_notification/domain/repository/web_socket_repository.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

class WebSocketRepositoryImpl implements WebSocketRepository {
final WebSocketDatasource _webSocketDatasource;

WebSocketRepositoryImpl(this._webSocketDatasource);

@override
Stream getWebSocketChannel(Session session, AccountId accountId)
=> _webSocketDatasource.getWebSocketChannel(session, accountId);
Future<WebSocketChannel> getWebSocketChannel(
Session session,
AccountId accountId
) => _webSocketDatasource.getWebSocketChannel(session, accountId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

abstract class WebSocketRepository {
Stream getWebSocketChannel(Session session, AccountId accountId);
Future<WebSocketChannel> getWebSocketChannel(
Session session,
AccountId accountId);
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/push/state_change.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

class InitializingWebSocketPushChannel extends LoadingState {}

class WebSocketPushStateReceived extends UIState {
final StateChange? stateChange;
class WebSocketConnectionSuccess extends UIState {
final WebSocketChannel webSocketChannel;

WebSocketPushStateReceived(this.stateChange);
WebSocketConnectionSuccess(this.webSocketChannel);

@override
List<Object?> get props => [stateChange];
List<Object?> get props => [webSocketChannel];
}

class WebSocketConnectionFailed extends FeatureFailure {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import 'dart:convert';

import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/utils/app_logger.dart';
import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/push/state_change.dart';
import 'package:tmail_ui_user/features/push_notification/data/model/web_socket_echo.dart';
import 'package:tmail_ui_user/features/push_notification/domain/repository/web_socket_repository.dart';
import 'package:tmail_ui_user/features/push_notification/domain/state/web_socket_push_state.dart';

Expand All @@ -22,31 +18,13 @@ class ConnectWebSocketInteractor {
) async* {
try {
yield Right(InitializingWebSocketPushChannel());
yield* _webSocketRepository
.getWebSocketChannel(session, accountId)
.map(_toStateChange);
final webSocketChannel = await _webSocketRepository.getWebSocketChannel(
session,
accountId);
yield Right(WebSocketConnectionSuccess(webSocketChannel));
} catch (e) {
logError('ConnectWebSocketInteractor::execute: $e');
yield Left(WebSocketConnectionFailed(exception: e));
}
}

Either<Failure, Success> _toStateChange(dynamic data) {
StateChange? possibleStateChange;
try {
if (data is String) {
data = jsonDecode(data);
}
possibleStateChange = StateChange.fromJson(data);
return Right(WebSocketPushStateReceived(possibleStateChange));
} catch (e) {
logError('ConnectWebSocketInteractor::_toStateChange: '
'websocket message is not StateChange: $data');
final dataIsWebSocketEcho = WebSocketEcho.isValid(data);
if (dataIsWebSocketEcho) {
return Right(WebSocketPushStateReceived(null));
}
return Left(WebSocketConnectionFailed(exception: e));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ abstract class PushBaseController {
Session? session;
AccountId? accountId;

StreamSubscription<Either<Failure, Success>>? _stateStreamSubscription;

void consumeState(Stream<Either<Failure, Success>> newStateStream) {
_stateStreamSubscription = newStateStream.listen(
newStateStream.listen(
_handleStateStream,
onError: handleErrorViewState,
);
Expand All @@ -40,11 +38,6 @@ abstract class PushBaseController {
logError('PushBaseController::handleErrorViewState():error: $error | stackTrace: $stackTrace');
}

void cancelStateStreamSubscription() {
_stateStreamSubscription?.cancel();
_stateStreamSubscription = null;
}

void initialize({AccountId? accountId, Session? session}) {
this.accountId = accountId;
this.session = session;
Expand Down
Loading

0 comments on commit 75e8ca9

Please sign in to comment.