parent
9237a3dbed
commit
3a33bf7bfe
5 changed files with 86 additions and 29 deletions
|
|
@ -15,6 +15,8 @@ import "package:nexus/controllers/settings.dart";
|
|||
import "package:nexus/controllers/unified_push.dart";
|
||||
import "package:nexus/controllers/spec_versions.dart";
|
||||
import "package:nexus/controllers/unified_push_allowed.dart";
|
||||
import "package:nexus/controllers/unified_push_distributors.dart";
|
||||
import "package:nexus/helpers/extensions/distributor_name.dart";
|
||||
import "package:nexus/models/account_data.dart";
|
||||
import "package:nexus/models/settings_category.dart";
|
||||
import "package:nexus/main.dart";
|
||||
|
|
@ -138,7 +140,7 @@ class SettingsSectionsController
|
|||
settings: .new([
|
||||
.new(
|
||||
title: "Push notifications",
|
||||
description: "Enable push notifications using Web Push",
|
||||
description: "Enable push notifications using Web Push, and choose which UnifiedPush distributor to use.",
|
||||
builder: (title, description, icon) => HookConsumer(
|
||||
builder: (context, ref, _) {
|
||||
final loading = useState(false);
|
||||
|
|
@ -148,9 +150,14 @@ class SettingsSectionsController
|
|||
final unifiedPushAllowed = ref.watch(
|
||||
UnifiedPushAllowedController.provider,
|
||||
);
|
||||
final distributors = ref.watch(
|
||||
UnifiedPushDistributorsController.provider,
|
||||
);
|
||||
final current = pusherRegistered.value;
|
||||
|
||||
return SwitchListTile(
|
||||
title: Text(title),
|
||||
return DialogListTile<String?>(
|
||||
key: ValueKey(current),
|
||||
title: title,
|
||||
subtitle: Text(
|
||||
unifiedPushAllowed.maybeWhen(
|
||||
data: (data) => data,
|
||||
|
|
@ -158,11 +165,18 @@ class SettingsSectionsController
|
|||
) ??
|
||||
description,
|
||||
),
|
||||
secondary: Icon(icon),
|
||||
value: pusherRegistered.maybeWhen(
|
||||
data: (value) => value,
|
||||
orElse: () => false,
|
||||
),
|
||||
icon: Icon(icon),
|
||||
required: false,
|
||||
initialValue: current,
|
||||
options: [
|
||||
null,
|
||||
...?distributors.value,
|
||||
if (current != null &&
|
||||
distributors.value?.contains(current) != true)
|
||||
current,
|
||||
],
|
||||
getName: (option) =>
|
||||
option == null ? "Off" : option.distributorName,
|
||||
onChanged: loading.value
|
||||
? null
|
||||
: unifiedPushAllowed.maybeWhen(
|
||||
|
|
@ -171,9 +185,10 @@ class SettingsSectionsController
|
|||
)
|
||||
? pusherRegistered.maybeWhen(
|
||||
data: (_) => (value) async {
|
||||
if (value == current) return;
|
||||
try {
|
||||
loading.value = true;
|
||||
if (value) {
|
||||
if (value != null) {
|
||||
if (await ref
|
||||
.watch(
|
||||
NotificationController
|
||||
|
|
@ -187,7 +202,7 @@ class SettingsSectionsController
|
|||
.provider
|
||||
.notifier,
|
||||
)
|
||||
.register();
|
||||
.register(value);
|
||||
} else {
|
||||
// TODO: Handle not granted
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ import "package:unifiedpush/unifiedpush.dart";
|
|||
import "package:unifiedpush_storage_shared_preferences/storage.dart";
|
||||
import "package:window_manager/window_manager.dart";
|
||||
|
||||
class UnifiedPushController extends AsyncNotifier<bool> {
|
||||
class UnifiedPushController extends AsyncNotifier<String?> {
|
||||
Completer<void>? _endpoint;
|
||||
|
||||
@override
|
||||
Future<bool> build() async {
|
||||
if (!Platform.isLinux && !Platform.isAndroid) return false;
|
||||
Future<String?> build() async {
|
||||
if (!Platform.isLinux && !Platform.isAndroid) return null;
|
||||
|
||||
final registered = await UnifiedPush.initialize(
|
||||
linuxOptions: .new(
|
||||
|
|
@ -56,7 +56,7 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
|||
),
|
||||
);
|
||||
|
||||
state = .data(true);
|
||||
state = .data(await UnifiedPush.getDistributor());
|
||||
});
|
||||
|
||||
if (_endpoint case final completer? when !completer.isCompleted) {
|
||||
|
|
@ -125,17 +125,25 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
|||
onUnregistered: deregister,
|
||||
);
|
||||
|
||||
if (!registered) return false;
|
||||
if (!registered) return null;
|
||||
|
||||
try {
|
||||
return await register();
|
||||
} catch (error, stackTrace) {
|
||||
showError(error, stackTrace);
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> register() async {
|
||||
/// Registers with [distributor], or the current/default distributor if none
|
||||
/// is given. Returns the distributor that was registered with.
|
||||
Future<String?> register([String? distributor]) async {
|
||||
if (distributor != null &&
|
||||
state.value != null &&
|
||||
state.value != distributor) {
|
||||
await deregister();
|
||||
}
|
||||
|
||||
state = .loading();
|
||||
try {
|
||||
final deviceIdCompleter = Completer<String>();
|
||||
|
|
@ -163,7 +171,9 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
|||
);
|
||||
}
|
||||
|
||||
if (!await UnifiedPush.tryUseCurrentOrDefaultDistributor()) {
|
||||
if (distributor != null) {
|
||||
await UnifiedPush.saveDistributor(distributor);
|
||||
} else if (!await UnifiedPush.tryUseCurrentOrDefaultDistributor()) {
|
||||
throw Exception("No UnifiedPush distributors found.");
|
||||
}
|
||||
|
||||
|
|
@ -185,10 +195,11 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
|||
onTimeout: () => throw Exception("UnifiedPush registration timed out."),
|
||||
);
|
||||
|
||||
state = .data(true);
|
||||
return true;
|
||||
final current = await UnifiedPush.getDistributor();
|
||||
state = .data(current);
|
||||
return current;
|
||||
} catch (_) {
|
||||
state = .data(false);
|
||||
state = .data(null);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
|
@ -213,10 +224,10 @@ class UnifiedPushController extends AsyncNotifier<bool> {
|
|||
}
|
||||
|
||||
await UnifiedPush.unregister(instance ?? clientState!.deviceId!);
|
||||
state = .data(false);
|
||||
state = .data(null);
|
||||
}
|
||||
|
||||
static final provider = AsyncNotifierProvider<UnifiedPushController, bool>(
|
||||
static final provider = AsyncNotifierProvider<UnifiedPushController, String?>(
|
||||
UnifiedPushController.new,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@ import "dart:io";
|
|||
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/controllers/client.dart";
|
||||
import "package:unifiedpush/unifiedpush.dart";
|
||||
import "package:nexus/controllers/unified_push_distributors.dart";
|
||||
|
||||
class UnifiedPushAllowedController extends AsyncNotifier<String?> {
|
||||
@override
|
||||
Future<String?> build() async {
|
||||
if (!await UnifiedPush.tryUseCurrentOrDefaultDistributor().timeout(
|
||||
.new(seconds: 10),
|
||||
onTimeout: () =>
|
||||
throw Exception("UnifiedPush distributor check timed out."),
|
||||
)) {
|
||||
final distributors = await ref.watch(
|
||||
UnifiedPushDistributorsController.provider.future,
|
||||
);
|
||||
|
||||
if (distributors.isEmpty) {
|
||||
return "No valid distributors found. ${Platform.isLinux
|
||||
? "Try installing KUnifiedPush"
|
||||
: Platform.isAndroid
|
||||
|
|
|
|||
26
lib/controllers/unified_push_distributors.dart
Normal file
26
lib/controllers/unified_push_distributors.dart
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import "dart:io";
|
||||
|
||||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:unifiedpush/unifiedpush.dart";
|
||||
|
||||
class UnifiedPushDistributorsController extends AsyncNotifier<IList<String>> {
|
||||
@override
|
||||
Future<IList<String>> build() async {
|
||||
if (!Platform.isLinux && !Platform.isAndroid) return .new();
|
||||
|
||||
return IList(
|
||||
await UnifiedPush.getDistributors().timeout(
|
||||
.new(seconds: 10),
|
||||
onTimeout: () =>
|
||||
throw Exception("UnifiedPush distributor check timed out."),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static final provider =
|
||||
AsyncNotifierProvider.autoDispose<
|
||||
UnifiedPushDistributorsController,
|
||||
IList<String>
|
||||
>(UnifiedPushDistributorsController.new);
|
||||
}
|
||||
5
lib/helpers/extensions/distributor_name.dart
Normal file
5
lib/helpers/extensions/distributor_name.dart
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
extension DistributorName on String {
|
||||
String get distributorName => startsWith("nexus.federated.nexus")
|
||||
? "Google Play Services"
|
||||
: split(".").last;
|
||||
}
|
||||
Loading…
Reference in a new issue