fix race condition on startup
This commit is contained in:
parent
386b3ad1cf
commit
6e47594a91
3 changed files with 74 additions and 68 deletions
|
|
@ -7,7 +7,7 @@ class MultiProviderController(final IList<AsyncNotifierProvider> providers)
|
|||
extends AsyncNotifier<void> {
|
||||
@override
|
||||
Future<void> build() => .wait(
|
||||
providers.map((provider) => ref.read(provider.future)),
|
||||
providers.map((provider) => ref.watch(provider.future)),
|
||||
eagerError: true,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
|||
Future<bool> build() async {
|
||||
if (!Platform.isLinux && !Platform.isAndroid) return false;
|
||||
|
||||
final client = ref.watch(ClientController.provider.notifier);
|
||||
final registered = await UnifiedPush.initialize(
|
||||
linuxOptions: .new(
|
||||
dbusName: "nexus.federated.nexus.UnifiedPush",
|
||||
|
|
@ -36,21 +35,23 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
|||
.watch(PushKeyController.provider(instance).notifier)
|
||||
.set(pushKey);
|
||||
|
||||
await client.registerPusher(
|
||||
.new(
|
||||
appDisplayName: "Nexus",
|
||||
appId: "nexus.federated.nexus",
|
||||
data: .webPush(
|
||||
url: .parse(endpoint.url),
|
||||
auth: endpoint.pubKeySet!.auth,
|
||||
),
|
||||
deviceDisplayName:
|
||||
"Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}",
|
||||
kind: .webPush,
|
||||
lang: "en",
|
||||
pushKey: pushKey,
|
||||
),
|
||||
);
|
||||
await ref
|
||||
.watch(ClientController.provider.notifier)
|
||||
.registerPusher(
|
||||
.new(
|
||||
appDisplayName: "Nexus",
|
||||
appId: "nexus.federated.nexus",
|
||||
data: .webPush(
|
||||
url: .parse(endpoint.url),
|
||||
auth: endpoint.pubKeySet!.auth,
|
||||
),
|
||||
deviceDisplayName:
|
||||
"Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}",
|
||||
kind: .webPush,
|
||||
lang: "en",
|
||||
pushKey: pushKey,
|
||||
),
|
||||
);
|
||||
},
|
||||
onMessage: (message, instance) async {
|
||||
debugPrint("UP message received for $instance");
|
||||
|
|
@ -59,9 +60,9 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
|||
"Failed to decrypt notification. Try toggling off and on UnifiedPush in settings.",
|
||||
);
|
||||
}
|
||||
final event = await client.handlePush(
|
||||
json.decode(String.fromCharCodes(message.content)),
|
||||
);
|
||||
final event = await ref
|
||||
.watch(ClientController.provider.notifier)
|
||||
.handlePush(json.decode(String.fromCharCodes(message.content)));
|
||||
|
||||
if (event == null ||
|
||||
event.unreadType?.shouldNotify() != true ||
|
||||
|
|
@ -120,8 +121,11 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
|||
}
|
||||
|
||||
Future<void> register([bool alreadyRegistered = false]) async {
|
||||
final clientState = ref.watch(ClientStateController.provider);
|
||||
if (clientState?.deviceId == null) return ref.invalidateSelf();
|
||||
final clientStateProvider = ClientStateController.provider;
|
||||
while (ref.watch(clientStateProvider)?.deviceId == null) {
|
||||
await Future.delayed(.new(milliseconds: 250));
|
||||
}
|
||||
final clientState = ref.watch(clientStateProvider);
|
||||
|
||||
final capabilities = await ref
|
||||
.watch(ClientController.provider.notifier)
|
||||
|
|
|
|||
|
|
@ -151,54 +151,56 @@ class const App({super.key}) extends StatelessWidget {
|
|||
builder: (_, ref, _) => ref
|
||||
.watch(ClientController.provider)
|
||||
.betterWhen(
|
||||
data: (_) => ref
|
||||
.watch(
|
||||
MultiProviderController.provider(
|
||||
.new([
|
||||
NotificationController.provider,
|
||||
UnifiedPushController.provider,
|
||||
MemberListOpenedController.provider,
|
||||
KeyController.provider(KeyController.roomKey),
|
||||
KeyController.provider(KeyController.spaceKey),
|
||||
]),
|
||||
),
|
||||
)
|
||||
.betterWhen(
|
||||
data: (_) => Consumer(
|
||||
builder: (_, ref, _) {
|
||||
final clientState = ref.watch(
|
||||
ClientStateController.provider,
|
||||
);
|
||||
|
||||
if (clientState == null ||
|
||||
!clientState.isInitialized) {
|
||||
return Loading();
|
||||
}
|
||||
|
||||
if (!clientState.isLoggedIn) {
|
||||
return SelectServerPage();
|
||||
} else if (!clientState.isVerified) {
|
||||
return VerifyPage();
|
||||
} else {
|
||||
return ChatPage();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
loading: () => Scaffold(
|
||||
appBar: Appbar(
|
||||
actions: .new([
|
||||
IconButton(
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (_) => SettingsPage(),
|
||||
),
|
||||
icon: Icon(Icons.settings),
|
||||
),
|
||||
data: (_) => switch (ref.watch(
|
||||
MultiProviderController.provider(
|
||||
.new([
|
||||
NotificationController.provider,
|
||||
UnifiedPushController.provider,
|
||||
MemberListOpenedController.provider,
|
||||
KeyController.provider(KeyController.roomKey),
|
||||
KeyController.provider(KeyController.spaceKey),
|
||||
]),
|
||||
),
|
||||
body: Loading(),
|
||||
),
|
||||
)) {
|
||||
AsyncData(value: _) || AsyncLoading(value: _?) => Consumer(
|
||||
builder: (_, ref, _) {
|
||||
final clientState = ref.watch(
|
||||
ClientStateController.provider,
|
||||
);
|
||||
|
||||
if (clientState == null || !clientState.isInitialized) {
|
||||
return Loading();
|
||||
}
|
||||
|
||||
if (!clientState.isLoggedIn) {
|
||||
return SelectServerPage();
|
||||
} else if (!clientState.isVerified) {
|
||||
return VerifyPage();
|
||||
} else {
|
||||
return ChatPage();
|
||||
}
|
||||
},
|
||||
),
|
||||
|
||||
AsyncLoading _ => Scaffold(
|
||||
appBar: Appbar(
|
||||
actions: .new([
|
||||
IconButton(
|
||||
onPressed: () => showDialog(
|
||||
context: context,
|
||||
builder: (_) => SettingsPage(),
|
||||
),
|
||||
icon: Icon(Icons.settings),
|
||||
),
|
||||
]),
|
||||
),
|
||||
body: Loading(),
|
||||
),
|
||||
AsyncError(:final error, :final stackTrace) => ErrorDialog(
|
||||
error,
|
||||
stackTrace,
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in a new issue