import 'package:flutter/foundation.dart'; import 'package:umbrix/core/app_info/app_info_provider.dart'; import 'package:umbrix/core/localization/locale_preferences.dart'; import 'package:umbrix/core/preferences/preferences_provider.dart'; import 'package:umbrix/core/utils/preferences_utils.dart'; import 'package:umbrix/features/app_update/data/app_update_data_providers.dart'; import 'package:umbrix/features/app_update/model/app_update_failure.dart'; import 'package:umbrix/features/app_update/model/remote_version_entity.dart'; import 'package:umbrix/features/app_update/notifier/app_update_state.dart'; import 'package:umbrix/utils/utils.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:upgrader/upgrader.dart'; import 'package:version/version.dart'; part 'app_update_notifier.g.dart'; const _debugUpgrader = true; @riverpod Upgrader upgrader(UpgraderRef ref) => Upgrader( // Removed appcastConfig - no updates for Umbrix debugLogging: _debugUpgrader && kDebugMode, durationUntilAlertAgain: const Duration(hours: 12), messages: UpgraderMessages( code: ref.watch(localePreferencesProvider).languageCode, ), ); @Riverpod(keepAlive: true) class AppUpdateNotifier extends _$AppUpdateNotifier with AppLogger { @override AppUpdateState build() => const AppUpdateState.initial(); PreferencesEntry get _ignoreReleasePref => PreferencesEntry( preferences: ref.read(sharedPreferencesProvider).requireValue, key: 'ignored_release_version', defaultValue: null, ); Future check() async { loggy.debug("checking for update"); state = const AppUpdateState.checking(); final appInfo = ref.watch(appInfoProvider).requireValue; if (!appInfo.release.allowCustomUpdateChecker) { loggy.debug( "custom update checkers are not allowed for [${appInfo.release.name}] release", ); return state = const AppUpdateState.disabled(); } return ref.watch(appUpdateRepositoryProvider).getLatestVersion().match( (err) { loggy.warning("failed to get latest version", err); return state = AppUpdateState.error(err); }, (remote) { try { final latestVersion = Version.parse(remote.version); final currentVersion = Version.parse(appInfo.version); if (latestVersion > currentVersion) { if (remote.version == _ignoreReleasePref.read()) { loggy.debug("ignored release [${remote.version}]"); return state = AppUpdateStateIgnored(remote); } loggy.debug("new version available: $remote"); return state = AppUpdateState.available(remote); } loggy.info( "already using latest version[$currentVersion], remote: [${remote.version}]", ); return state = const AppUpdateState.notAvailable(); } catch (error, stackTrace) { loggy.warning("error parsing versions", error, stackTrace); return state = AppUpdateState.error( AppUpdateFailure.unexpected(error, stackTrace), ); } }, ).run(); } Future ignoreRelease(RemoteVersionEntity version) async { loggy.debug("ignoring release [${version.version}]"); await _ignoreReleasePref.write(version.version); state = AppUpdateStateIgnored(version); } }