More platform-independent approach to managing registered state
This commit is contained in:
parent
6e47594a91
commit
41806be9bf
2 changed files with 49 additions and 42 deletions
|
|
@ -15,6 +15,7 @@ import "package:nexus/controllers/rooms.dart";
|
||||||
import "package:nexus/controllers/space_edges.dart";
|
import "package:nexus/controllers/space_edges.dart";
|
||||||
import "package:nexus/controllers/sync_status.dart";
|
import "package:nexus/controllers/sync_status.dart";
|
||||||
import "package:nexus/controllers/top_level_spaces.dart";
|
import "package:nexus/controllers/top_level_spaces.dart";
|
||||||
|
import "package:nexus/controllers/unified_push.dart";
|
||||||
import "package:nexus/helpers/extensions/gomuks_buffer.dart";
|
import "package:nexus/helpers/extensions/gomuks_buffer.dart";
|
||||||
import "package:nexus/main.dart";
|
import "package:nexus/main.dart";
|
||||||
import "package:nexus/models/capabilities.dart";
|
import "package:nexus/models/capabilities.dart";
|
||||||
|
|
@ -344,7 +345,10 @@ class ClientController extends AsyncNotifier<int> {
|
||||||
Future<File> downloadMedia(DownloadMediaRequest request) async =>
|
Future<File> downloadMedia(DownloadMediaRequest request) async =>
|
||||||
.new((await _sendCommand("download_media", request.toJson()))["path"]);
|
.new((await _sendCommand("download_media", request.toJson()))["path"]);
|
||||||
|
|
||||||
Future<void> logout() => _sendCommand("logout");
|
Future<void> logout() async {
|
||||||
|
await ref.watch(UnifiedPushController.provider.notifier).deregister();
|
||||||
|
await _sendCommand("logout");
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> markRead(Room room) async {
|
Future<void> markRead(Room room) async {
|
||||||
final eventRowId = room.timeline[room.timeline.keys.reduce(max)];
|
final eventRowId = room.timeline[room.timeline.keys.reduce(max)];
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,11 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
onNewEndpoint: (endpoint, instance) async {
|
onNewEndpoint: (endpoint, instance) async {
|
||||||
final pushKey = endpoint.pubKeySet!.pubKey;
|
final pushKey = endpoint.pubKeySet!.pubKey;
|
||||||
await ref
|
await ref
|
||||||
.watch(PushKeyController.provider(instance).notifier)
|
.read(PushKeyController.provider(instance).notifier)
|
||||||
.set(pushKey);
|
.set(pushKey);
|
||||||
|
|
||||||
await ref
|
await ref
|
||||||
.watch(ClientController.provider.notifier)
|
.read(ClientController.provider.notifier)
|
||||||
.registerPusher(
|
.registerPusher(
|
||||||
.new(
|
.new(
|
||||||
appDisplayName: "Nexus",
|
appDisplayName: "Nexus",
|
||||||
|
|
@ -52,6 +52,8 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
pushKey: pushKey,
|
pushKey: pushKey,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
state = .data(true);
|
||||||
},
|
},
|
||||||
onMessage: (message, instance) async {
|
onMessage: (message, instance) async {
|
||||||
debugPrint("UP message received for $instance");
|
debugPrint("UP message received for $instance");
|
||||||
|
|
@ -61,14 +63,14 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final event = await ref
|
final event = await ref
|
||||||
.watch(ClientController.provider.notifier)
|
.read(ClientController.provider.notifier)
|
||||||
.handlePush(json.decode(String.fromCharCodes(message.content)));
|
.handlePush(json.decode(String.fromCharCodes(message.content)));
|
||||||
|
|
||||||
if (event == null ||
|
if (event == null ||
|
||||||
event.unreadType?.shouldNotify() != true ||
|
event.unreadType?.shouldNotify() != true ||
|
||||||
(!isInBackground &&
|
(!isInBackground &&
|
||||||
await windowManager.isFocused().onError((_, _) => false) &&
|
await windowManager.isFocused().onError((_, _) => false) &&
|
||||||
await ref.watch(
|
await ref.read(
|
||||||
KeyController.provider(KeyController.roomKey).future,
|
KeyController.provider(KeyController.roomKey).future,
|
||||||
) ==
|
) ==
|
||||||
event.roomId)) {
|
event.roomId)) {
|
||||||
|
|
@ -103,13 +105,7 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
|
|
||||||
if (isInBackground) exit(0);
|
if (isInBackground) exit(0);
|
||||||
},
|
},
|
||||||
onRegistrationFailed: (error, instance) => throw error,
|
onUnregistered: deregister,
|
||||||
onUnregistered: (instance) async {
|
|
||||||
await ref
|
|
||||||
.watch(PushKeyController.provider(instance).notifier)
|
|
||||||
.set(null);
|
|
||||||
ref.invalidateSelf();
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (registered) {
|
if (registered) {
|
||||||
|
|
@ -121,53 +117,60 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> register([bool alreadyRegistered = false]) async {
|
Future<void> register([bool alreadyRegistered = false]) async {
|
||||||
final clientStateProvider = ClientStateController.provider;
|
state = .loading();
|
||||||
while (ref.watch(clientStateProvider)?.deviceId == null) {
|
try {
|
||||||
await Future.delayed(.new(milliseconds: 250));
|
final clientStateProvider = ClientStateController.provider;
|
||||||
}
|
while (ref.read(clientStateProvider)?.deviceId == null) {
|
||||||
final clientState = ref.watch(clientStateProvider);
|
await Future.delayed(.new(milliseconds: 250));
|
||||||
|
}
|
||||||
|
final clientState = ref.read(clientStateProvider);
|
||||||
|
|
||||||
final capabilities = await ref
|
final capabilities = await ref
|
||||||
.watch(ClientController.provider.notifier)
|
.read(ClientController.provider.notifier)
|
||||||
.getCapabilities();
|
.getCapabilities();
|
||||||
|
|
||||||
if (capabilities.webpush?.vapid == null) {
|
if (capabilities.webpush?.vapid == null) {
|
||||||
throw UnsupportedError(
|
throw UnsupportedError(
|
||||||
"Your homeserver does not support MSC4174 (Web Push), and therefore cannot send notifications to Nexus.",
|
"Your homeserver does not support MSC4174 (Web Push), and therefore cannot send notifications to Nexus.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!alreadyRegistered &&
|
||||||
|
!await UnifiedPush.tryUseCurrentOrDefaultDistributor()) {
|
||||||
|
throw Exception("No UnifiedPush distributors found");
|
||||||
|
}
|
||||||
|
|
||||||
|
await UnifiedPush.register(
|
||||||
|
instance: clientState!.deviceId!,
|
||||||
|
vapid: capabilities.webpush?.vapid,
|
||||||
);
|
);
|
||||||
|
} catch (_) {
|
||||||
|
state = .data(false);
|
||||||
|
rethrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!alreadyRegistered &&
|
|
||||||
!await UnifiedPush.tryUseCurrentOrDefaultDistributor()) {
|
|
||||||
throw Exception("No UnifiedPush distributors found");
|
|
||||||
}
|
|
||||||
|
|
||||||
await UnifiedPush.register(
|
|
||||||
instance: clientState!.deviceId!,
|
|
||||||
vapid: capabilities.webpush?.vapid,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!alreadyRegistered) ref.invalidateSelf();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> deregister() async {
|
Future<void> deregister([String? instance]) async {
|
||||||
final clientState = ref.watch(ClientStateController.provider);
|
final clientState = ref.read(ClientStateController.provider);
|
||||||
final key = await ref.watch(
|
|
||||||
PushKeyController.provider(clientState!.deviceId!).future,
|
final keyProvider = PushKeyController.provider(
|
||||||
|
instance ?? clientState!.deviceId!,
|
||||||
);
|
);
|
||||||
|
final key = await ref.read(keyProvider.future);
|
||||||
|
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
await ref
|
await ref
|
||||||
.watch(ClientController.provider.notifier)
|
.read(ClientController.provider.notifier)
|
||||||
.deregisterPusher(.new(appId: "nexus.federated.nexus", pushKey: key));
|
.deregisterPusher(.new(appId: "nexus.federated.nexus", pushKey: key));
|
||||||
|
await ref.read(keyProvider.notifier).set(null);
|
||||||
} else {
|
} else {
|
||||||
debugPrint(
|
debugPrint(
|
||||||
"No matching pushKey found. Skipping deregistration from homeserver.",
|
"No matching pushKey found. Skipping deregistration from homeserver.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await UnifiedPush.unregister(clientState.deviceId!);
|
await UnifiedPush.unregister(instance ?? clientState!.deviceId!);
|
||||||
ref.invalidateSelf();
|
state = .data(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static final provider = AsyncNotifierProvider<UnifiedPushController, bool>(
|
static final provider = AsyncNotifierProvider<UnifiedPushController, bool>(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue