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> {
|
extends AsyncNotifier<void> {
|
||||||
@override
|
@override
|
||||||
Future<void> build() => .wait(
|
Future<void> build() => .wait(
|
||||||
providers.map((provider) => ref.read(provider.future)),
|
providers.map((provider) => ref.watch(provider.future)),
|
||||||
eagerError: true,
|
eagerError: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
Future<bool> build() async {
|
Future<bool> build() async {
|
||||||
if (!Platform.isLinux && !Platform.isAndroid) return false;
|
if (!Platform.isLinux && !Platform.isAndroid) return false;
|
||||||
|
|
||||||
final client = ref.watch(ClientController.provider.notifier);
|
|
||||||
final registered = await UnifiedPush.initialize(
|
final registered = await UnifiedPush.initialize(
|
||||||
linuxOptions: .new(
|
linuxOptions: .new(
|
||||||
dbusName: "nexus.federated.nexus.UnifiedPush",
|
dbusName: "nexus.federated.nexus.UnifiedPush",
|
||||||
|
|
@ -36,21 +35,23 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
.watch(PushKeyController.provider(instance).notifier)
|
.watch(PushKeyController.provider(instance).notifier)
|
||||||
.set(pushKey);
|
.set(pushKey);
|
||||||
|
|
||||||
await client.registerPusher(
|
await ref
|
||||||
.new(
|
.watch(ClientController.provider.notifier)
|
||||||
appDisplayName: "Nexus",
|
.registerPusher(
|
||||||
appId: "nexus.federated.nexus",
|
.new(
|
||||||
data: .webPush(
|
appDisplayName: "Nexus",
|
||||||
url: .parse(endpoint.url),
|
appId: "nexus.federated.nexus",
|
||||||
auth: endpoint.pubKeySet!.auth,
|
data: .webPush(
|
||||||
),
|
url: .parse(endpoint.url),
|
||||||
deviceDisplayName:
|
auth: endpoint.pubKeySet!.auth,
|
||||||
"Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}",
|
),
|
||||||
kind: .webPush,
|
deviceDisplayName:
|
||||||
lang: "en",
|
"Nexus on ${toBeginningOfSentenceCase(Platform.operatingSystem)}",
|
||||||
pushKey: pushKey,
|
kind: .webPush,
|
||||||
),
|
lang: "en",
|
||||||
);
|
pushKey: pushKey,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onMessage: (message, instance) async {
|
onMessage: (message, instance) async {
|
||||||
debugPrint("UP message received for $instance");
|
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.",
|
"Failed to decrypt notification. Try toggling off and on UnifiedPush in settings.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final event = await client.handlePush(
|
final event = await ref
|
||||||
json.decode(String.fromCharCodes(message.content)),
|
.watch(ClientController.provider.notifier)
|
||||||
);
|
.handlePush(json.decode(String.fromCharCodes(message.content)));
|
||||||
|
|
||||||
if (event == null ||
|
if (event == null ||
|
||||||
event.unreadType?.shouldNotify() != true ||
|
event.unreadType?.shouldNotify() != true ||
|
||||||
|
|
@ -120,8 +121,11 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> register([bool alreadyRegistered = false]) async {
|
Future<void> register([bool alreadyRegistered = false]) async {
|
||||||
final clientState = ref.watch(ClientStateController.provider);
|
final clientStateProvider = ClientStateController.provider;
|
||||||
if (clientState?.deviceId == null) return ref.invalidateSelf();
|
while (ref.watch(clientStateProvider)?.deviceId == null) {
|
||||||
|
await Future.delayed(.new(milliseconds: 250));
|
||||||
|
}
|
||||||
|
final clientState = ref.watch(clientStateProvider);
|
||||||
|
|
||||||
final capabilities = await ref
|
final capabilities = await ref
|
||||||
.watch(ClientController.provider.notifier)
|
.watch(ClientController.provider.notifier)
|
||||||
|
|
|
||||||
|
|
@ -151,54 +151,56 @@ class const App({super.key}) extends StatelessWidget {
|
||||||
builder: (_, ref, _) => ref
|
builder: (_, ref, _) => ref
|
||||||
.watch(ClientController.provider)
|
.watch(ClientController.provider)
|
||||||
.betterWhen(
|
.betterWhen(
|
||||||
data: (_) => ref
|
data: (_) => switch (ref.watch(
|
||||||
.watch(
|
MultiProviderController.provider(
|
||||||
MultiProviderController.provider(
|
.new([
|
||||||
.new([
|
NotificationController.provider,
|
||||||
NotificationController.provider,
|
UnifiedPushController.provider,
|
||||||
UnifiedPushController.provider,
|
MemberListOpenedController.provider,
|
||||||
MemberListOpenedController.provider,
|
KeyController.provider(KeyController.roomKey),
|
||||||
KeyController.provider(KeyController.roomKey),
|
KeyController.provider(KeyController.spaceKey),
|
||||||
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),
|
|
||||||
),
|
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
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