websocket.provider.dart 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import 'dart:convert';
  2. import 'package:flutter/foundation.dart';
  3. import 'package:hive/hive.dart';
  4. import 'package:hooks_riverpod/hooks_riverpod.dart';
  5. import 'package:immich_mobile/constants/hive_box.dart';
  6. import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
  7. import 'package:immich_mobile/shared/models/immich_asset.model.dart';
  8. import 'package:immich_mobile/shared/providers/asset.provider.dart';
  9. import 'package:socket_io_client/socket_io_client.dart';
  10. class WebscoketState {
  11. final Socket? socket;
  12. final bool isConnected;
  13. WebscoketState({
  14. this.socket,
  15. required this.isConnected,
  16. });
  17. WebscoketState copyWith({
  18. Socket? socket,
  19. bool? isConnected,
  20. }) {
  21. return WebscoketState(
  22. socket: socket ?? this.socket,
  23. isConnected: isConnected ?? this.isConnected,
  24. );
  25. }
  26. @override
  27. String toString() =>
  28. 'WebscoketState(socket: $socket, isConnected: $isConnected)';
  29. @override
  30. bool operator ==(Object other) {
  31. if (identical(this, other)) return true;
  32. return other is WebscoketState &&
  33. other.socket == socket &&
  34. other.isConnected == isConnected;
  35. }
  36. @override
  37. int get hashCode => socket.hashCode ^ isConnected.hashCode;
  38. }
  39. class WebsocketNotifier extends StateNotifier<WebscoketState> {
  40. WebsocketNotifier(this.ref)
  41. : super(WebscoketState(socket: null, isConnected: false)) {
  42. debugPrint("Init websocket instance");
  43. }
  44. final Ref ref;
  45. connect() {
  46. var authenticationState = ref.read(authenticationProvider);
  47. if (authenticationState.isAuthenticated) {
  48. var accessToken = Hive.box(userInfoBox).get(accessTokenKey);
  49. var endpoint = Hive.box(userInfoBox).get(serverEndpointKey);
  50. try {
  51. debugPrint("[WEBSOCKET] Attempting to connect to ws");
  52. // Configure socket transports must be sepecified
  53. Socket socket = io(
  54. endpoint,
  55. OptionBuilder()
  56. .setTransports(['websocket'])
  57. .enableReconnection()
  58. .enableForceNew()
  59. .enableForceNewConnection()
  60. .enableAutoConnect()
  61. .setExtraHeaders({"Authorization": "Bearer $accessToken"})
  62. .build(),
  63. );
  64. socket.onConnect((_) {
  65. debugPrint("[WEBSOCKET] Established Websocket Connection");
  66. state = WebscoketState(isConnected: true, socket: socket);
  67. });
  68. socket.onDisconnect((_) {
  69. debugPrint("[WEBSOCKET] Disconnect to Websocket Connection");
  70. state = WebscoketState(isConnected: false, socket: null);
  71. });
  72. socket.on('error', (errorMessage) {
  73. debugPrint("Webcoket Error - $errorMessage");
  74. state = WebscoketState(isConnected: false, socket: null);
  75. });
  76. socket.on('on_upload_success', (data) {
  77. var jsonString = jsonDecode(data.toString());
  78. ImmichAsset newAsset = ImmichAsset.fromMap(jsonString);
  79. ref.watch(assetProvider.notifier).onNewAssetUploaded(newAsset);
  80. });
  81. } catch (e) {
  82. debugPrint("[WEBSOCKET] Catch Websocket Error - ${e.toString()}");
  83. }
  84. }
  85. }
  86. disconnect() {
  87. debugPrint("[WEBSOCKET] Attempting to disconnect");
  88. var socket = state.socket?.disconnect();
  89. if (socket != null) {
  90. if (socket.disconnected) {
  91. state = WebscoketState(isConnected: false, socket: null);
  92. }
  93. }
  94. }
  95. stopListenToEvent(String eventName) {
  96. debugPrint("[Websocket] Stop listening to event $eventName");
  97. state.socket?.off(eventName);
  98. }
  99. listenUploadEvent() {
  100. debugPrint("[Websocket] Start listening to event on_upload_success");
  101. state.socket?.on('on_upload_success', (data) {
  102. var jsonString = jsonDecode(data.toString());
  103. ImmichAsset newAsset = ImmichAsset.fromMap(jsonString);
  104. ref.watch(assetProvider.notifier).onNewAssetUploaded(newAsset);
  105. });
  106. }
  107. }
  108. final websocketProvider =
  109. StateNotifierProvider<WebsocketNotifier, WebscoketState>((ref) {
  110. return WebsocketNotifier(ref);
  111. });