Add scheduled profile update
This commit is contained in:
@@ -147,7 +147,6 @@ Future<void> initAppServices(
|
|||||||
await Future.wait(
|
await Future.wait(
|
||||||
[
|
[
|
||||||
read(singboxServiceProvider).init(),
|
read(singboxServiceProvider).init(),
|
||||||
read(cronServiceProvider).startScheduler(),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
_logger.debug('initialized app services');
|
_logger.debug('initialized app services');
|
||||||
|
|||||||
@@ -37,6 +37,17 @@ class AppView extends HookConsumerWidget with PresLogger {
|
|||||||
theme: theme.light(),
|
theme: theme.light(),
|
||||||
darkTheme: theme.dark(),
|
darkTheme: theme.dark(),
|
||||||
title: Constants.appName,
|
title: Constants.appName,
|
||||||
|
|
||||||
|
// https://github.com/ponnamkarthik/FlutterToast/issues/393
|
||||||
|
builder: (context, child) => Overlay(
|
||||||
|
initialEntries: [
|
||||||
|
if (child != null) ...[
|
||||||
|
OverlayEntry(
|
||||||
|
builder: (context) => child,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,11 +66,11 @@ class AppUpdateNotifier extends _$AppUpdateNotifier with AppLogger {
|
|||||||
).run();
|
).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _schedule() {
|
Future<void> _schedule() async {
|
||||||
loggy.debug("scheduling app update checker");
|
loggy.debug("scheduling app update checker");
|
||||||
ref.watch(cronServiceProvider).schedule(
|
return ref.read(cronServiceProvider).schedule(
|
||||||
key: 'app_update',
|
key: 'app_update',
|
||||||
duration: const Duration(hours: 4),
|
duration: const Duration(hours: 8),
|
||||||
callback: () async {
|
callback: () async {
|
||||||
await Future.delayed(const Duration(seconds: 5));
|
await Future.delayed(const Duration(seconds: 5));
|
||||||
final updateState = await check();
|
final updateState = await check();
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
|
import 'package:hiddify/core/prefs/general_prefs.dart';
|
||||||
import 'package:hiddify/features/common/app_update_notifier.dart';
|
import 'package:hiddify/features/common/app_update_notifier.dart';
|
||||||
import 'package:hiddify/features/common/connectivity/connectivity_controller.dart';
|
import 'package:hiddify/features/common/connectivity/connectivity_controller.dart';
|
||||||
import 'package:hiddify/features/common/window/window_controller.dart';
|
import 'package:hiddify/features/common/window/window_controller.dart';
|
||||||
import 'package:hiddify/features/logs/notifier/notifier.dart';
|
import 'package:hiddify/features/logs/notifier/notifier.dart';
|
||||||
|
import 'package:hiddify/features/profiles/notifier/notifier.dart';
|
||||||
import 'package:hiddify/features/system_tray/controller/system_tray_controller.dart';
|
import 'package:hiddify/features/system_tray/controller/system_tray_controller.dart';
|
||||||
|
import 'package:hiddify/services/service_providers.dart';
|
||||||
import 'package:hiddify/utils/platform_utils.dart';
|
import 'package:hiddify/utils/platform_utils.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
@@ -12,6 +15,15 @@ part 'common_controllers.g.dart';
|
|||||||
// https://github.com/rrousselGit/riverpod/discussions/2730
|
// https://github.com/rrousselGit/riverpod/discussions/2730
|
||||||
@Riverpod(keepAlive: true)
|
@Riverpod(keepAlive: true)
|
||||||
void commonControllers(CommonControllersRef ref) {
|
void commonControllers(CommonControllersRef ref) {
|
||||||
|
ref.listen(
|
||||||
|
introCompletedProvider,
|
||||||
|
(_, completed) async {
|
||||||
|
if (completed) {
|
||||||
|
await ref.read(cronServiceProvider).startScheduler();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fireImmediately: true,
|
||||||
|
);
|
||||||
ref.listen(
|
ref.listen(
|
||||||
logsNotifierProvider,
|
logsNotifierProvider,
|
||||||
(previous, next) {},
|
(previous, next) {},
|
||||||
@@ -26,6 +38,11 @@ void commonControllers(CommonControllersRef ref) {
|
|||||||
(previous, next) {},
|
(previous, next) {},
|
||||||
fireImmediately: true,
|
fireImmediately: true,
|
||||||
);
|
);
|
||||||
|
ref.listen(
|
||||||
|
profilesUpdateNotifierProvider,
|
||||||
|
(previous, next) {},
|
||||||
|
fireImmediately: true,
|
||||||
|
);
|
||||||
if (PlatformUtils.isDesktop) {
|
if (PlatformUtils.isDesktop) {
|
||||||
ref.listen(
|
ref.listen(
|
||||||
windowControllerProvider,
|
windowControllerProvider,
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
export 'profiles_notifier.dart';
|
export 'profiles_notifier.dart';
|
||||||
|
export 'profiles_update_notifier.dart';
|
||||||
|
|||||||
73
lib/features/profiles/notifier/profiles_update_notifier.dart
Normal file
73
lib/features/profiles/notifier/profiles_update_notifier.dart
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fpdart/fpdart.dart';
|
||||||
|
import 'package:hiddify/core/core_providers.dart';
|
||||||
|
import 'package:hiddify/core/router/router.dart';
|
||||||
|
import 'package:hiddify/data/data_providers.dart';
|
||||||
|
import 'package:hiddify/domain/failures.dart';
|
||||||
|
import 'package:hiddify/domain/profiles/profiles.dart';
|
||||||
|
import 'package:hiddify/services/service_providers.dart';
|
||||||
|
import 'package:hiddify/utils/utils.dart';
|
||||||
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
|
part 'profiles_update_notifier.g.dart';
|
||||||
|
|
||||||
|
typedef ProfileUpdateResult = ({
|
||||||
|
String name,
|
||||||
|
Either<ProfileFailure, Unit> failureOrSuccess
|
||||||
|
});
|
||||||
|
|
||||||
|
@Riverpod(keepAlive: true)
|
||||||
|
class ProfilesUpdateNotifier extends _$ProfilesUpdateNotifier with AppLogger {
|
||||||
|
@override
|
||||||
|
Stream<ProfileUpdateResult> build() {
|
||||||
|
ref.listenSelf(
|
||||||
|
(previous, next) {
|
||||||
|
if (next case AsyncData(value: final result)) {
|
||||||
|
final t = ref.read(translationsProvider);
|
||||||
|
final context = rootNavigatorKey.currentContext;
|
||||||
|
if (context == null || !context.mounted) return;
|
||||||
|
SnackBar(content: Text(t.profile.update.successMsg));
|
||||||
|
switch (result.failureOrSuccess) {
|
||||||
|
case Right():
|
||||||
|
CustomToast.success(t.profile.update.successMsg).show(context);
|
||||||
|
case Left(value: final err):
|
||||||
|
CustomToast.error(t.printError(err)).show(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
_schedule();
|
||||||
|
return const Stream.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _schedule() async {
|
||||||
|
loggy.debug("scheduling profiles update worker");
|
||||||
|
return ref.read(cronServiceProvider).schedule(
|
||||||
|
key: 'profiles_update',
|
||||||
|
duration: const Duration(minutes: 10),
|
||||||
|
callback: () async {
|
||||||
|
final failureOrProfiles =
|
||||||
|
await ref.read(profilesRepositoryProvider).watchAll().first;
|
||||||
|
if (failureOrProfiles case Right(value: final profiles)) {
|
||||||
|
for (final profile in profiles) {
|
||||||
|
loggy.debug("checking profile: [${profile.name}]");
|
||||||
|
final updateInterval = profile.options?.updateInterval;
|
||||||
|
if (updateInterval != null &&
|
||||||
|
updateInterval <=
|
||||||
|
DateTime.now().difference(profile.lastUpdate)) {
|
||||||
|
final failureOrSuccess = await ref
|
||||||
|
.read(profilesRepositoryProvider)
|
||||||
|
.update(profile)
|
||||||
|
.run();
|
||||||
|
state = AsyncData(
|
||||||
|
(name: profile.name, failureOrSuccess: failureOrSuccess),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
loggy.debug("skipping profile: [${profile.name}]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,6 @@ class CronService with InfraLogger {
|
|||||||
}) {
|
}) {
|
||||||
loggy.debug("scheduling [$key]");
|
loggy.debug("scheduling [$key]");
|
||||||
jobs[key] = (key, duration, callback);
|
jobs[key] = (key, duration, callback);
|
||||||
_scheduler?.trigger();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> run(Job job) async {
|
Future<void> run(Job job) async {
|
||||||
|
|||||||
Reference in New Issue
Block a user