From 4dba624f8859a0ff7c355a82b511fd85d4dc34d9 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 4 May 2024 19:56:29 +0600 Subject: [PATCH] refactor: extract update checker as a basic function instead of a hook --- lib/components/root/update_dialog.dart | 46 ++++++++ .../configurators/use_update_checker.dart | 100 ------------------ lib/pages/root/root_app.dart | 5 +- lib/utils/service_utils.dart | 52 ++++++++- 4 files changed, 99 insertions(+), 104 deletions(-) create mode 100644 lib/components/root/update_dialog.dart delete mode 100644 lib/hooks/configurators/use_update_checker.dart diff --git a/lib/components/root/update_dialog.dart b/lib/components/root/update_dialog.dart new file mode 100644 index 00000000..f5388aa1 --- /dev/null +++ b/lib/components/root/update_dialog.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:spotube/components/shared/links/anchor_button.dart'; +import 'package:url_launcher/url_launcher_string.dart'; +import 'package:version/version.dart'; + +class RootAppUpdateDialog extends StatelessWidget { + final Version? version; + const RootAppUpdateDialog({super.key, this.version}); + + @override + Widget build(BuildContext context) { + const url = "https://spotube.krtirtho.dev/downloads"; + return AlertDialog( + title: const Text("Spotube has an update"), + actions: [ + FilledButton( + child: const Text("Download Now"), + onPressed: () => launchUrlString( + url, + mode: LaunchMode.externalApplication, + ), + ), + ], + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text("Spotube v$version has been released"), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text("Read the latest "), + AnchorButton( + "release notes", + style: const TextStyle(color: Colors.blue), + onTap: () => launchUrlString( + url, + mode: LaunchMode.externalApplication, + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/hooks/configurators/use_update_checker.dart b/lib/hooks/configurators/use_update_checker.dart deleted file mode 100644 index 7b937efb..00000000 --- a/lib/hooks/configurators/use_update_checker.dart +++ /dev/null @@ -1,100 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:http/http.dart' as http; -import 'package:spotube/collections/env.dart'; - -import 'package:spotube/components/shared/links/anchor_button.dart'; -import 'package:spotube/hooks/controllers/use_package_info.dart'; -import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; -import 'package:url_launcher/url_launcher_string.dart'; -import 'package:version/version.dart'; - -void useUpdateChecker(WidgetRef ref) { - final isCheckUpdateEnabled = - ref.watch(userPreferencesProvider.select((s) => s.checkUpdate)); - final packageInfo = usePackageInfo( - appName: 'Spotube', - packageName: 'spotube', - ); - final Future> Function() checkUpdate = useCallback( - () async { - final value = await http.get( - Uri.parse( - "https://api.github.com/repos/KRTirtho/spotube/releases/latest"), - ); - final tagName = - (jsonDecode(value.body)["tag_name"] as String).replaceAll("v", ""); - final currentVersion = packageInfo.version == "Unknown" - ? null - : Version.parse(packageInfo.version); - final latestVersion = - tagName == "nightly" ? null : Version.parse(tagName); - return [currentVersion, latestVersion]; - }, - [packageInfo.version], - ); - - final context = useContext(); - - download(String url) => launchUrlString( - url, - mode: LaunchMode.externalApplication, - ); - - useEffect(() { - if (!Env.enableUpdateChecker) return; - if (!isCheckUpdateEnabled) return null; - checkUpdate().then((value) { - final currentVersion = value.first; - final latestVersion = value.last; - if (currentVersion == null || - latestVersion == null || - (latestVersion.isPreRelease && !currentVersion.isPreRelease) || - (!latestVersion.isPreRelease && currentVersion.isPreRelease)) return; - if (latestVersion <= currentVersion) return; - showDialog( - context: context, - barrierDismissible: true, - barrierColor: Colors.black26, - builder: (context) { - const url = - "https://spotube.krtirtho.dev/downloads"; - return AlertDialog( - title: const Text("Spotube has an update"), - actions: [ - FilledButton( - child: const Text("Download Now"), - onPressed: () => download(url), - ), - ], - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text("Spotube v${value.last} has been released"), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text("Read the latest "), - AnchorButton( - "release notes", - style: const TextStyle(color: Colors.blue), - onTap: () => launchUrlString( - url, - mode: LaunchMode.externalApplication, - ), - ), - ], - ), - ], - ), - ); - }, - ); - }); - return null; - }, [packageInfo, isCheckUpdateEnabled]); -} diff --git a/lib/pages/root/root_app.dart b/lib/pages/root/root_app.dart index f3ed6571..42bf3f69 100644 --- a/lib/pages/root/root_app.dart +++ b/lib/pages/root/root_app.dart @@ -14,13 +14,13 @@ import 'package:spotube/components/root/sidebar.dart'; import 'package:spotube/components/root/spotube_navigation_bar.dart'; import 'package:spotube/extensions/context.dart'; import 'package:spotube/hooks/configurators/use_endless_playback.dart'; -import 'package:spotube/hooks/configurators/use_update_checker.dart'; import 'package:spotube/provider/connect/server.dart'; import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/services/connectivity_adapter.dart'; import 'package:spotube/utils/persisted_state_notifier.dart'; import 'package:spotube/utils/platform.dart'; +import 'package:spotube/utils/service_utils.dart'; const rootPaths = { "/": 0, @@ -46,6 +46,8 @@ class RootApp extends HookConsumerWidget { useEffect(() { WidgetsBinding.instance.addPostFrameCallback((_) async { + ServiceUtils.checkForUpdates(context, ref); + final sharedPreferences = await SharedPreferences.getInstance(); if (sharedPreferences.getBool(kIsUsingEncryption) == false && @@ -160,7 +162,6 @@ class RootApp extends HookConsumerWidget { }, [downloader]); // checks for latest version of the application - useUpdateChecker(ref); useEndlessPlayback(ref); diff --git a/lib/utils/service_utils.dart b/lib/utils/service_utils.dart index 88c52896..30c92e1d 100644 --- a/lib/utils/service_utils.dart +++ b/lib/utils/service_utils.dart @@ -1,10 +1,10 @@ import 'dart:convert'; -import 'package:flutter/widgets.dart' hide Element; import 'package:go_router/go_router.dart'; -import 'package:html/dom.dart'; +import 'package:html/dom.dart' hide Text; import 'package:spotify/spotify.dart'; import 'package:spotube/components/library/user_local_tracks.dart'; +import 'package:spotube/components/root/update_dialog.dart'; import 'package:spotube/models/logger.dart'; import 'package:http/http.dart' as http; import 'package:spotube/models/lyrics.dart'; @@ -14,6 +14,16 @@ import 'package:spotube/utils/primitive_utils.dart'; import 'package:collection/collection.dart'; import 'package:html/parser.dart' as parser; +import 'dart:async'; + +import 'package:flutter/material.dart' hide Element; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:spotube/collections/env.dart'; + +import 'package:spotube/provider/user_preferences/user_preferences_provider.dart'; +import 'package:version/version.dart'; + abstract class ServiceUtils { static final logger = getLogger("ServiceUtils"); @@ -318,4 +328,42 @@ abstract class ServiceUtils { } }); } + + static Future checkForUpdates( + BuildContext context, + WidgetRef ref, + ) async { + if (!Env.enableUpdateChecker) return; + if (!ref.read(userPreferencesProvider.select((s) => s.checkUpdate))) return; + + final packageInfo = await PackageInfo.fromPlatform(); + + final value = await http.get( + Uri.parse( + "https://api.github.com/repos/KRTirtho/spotube/releases/latest", + ), + ); + final tagName = + (jsonDecode(value.body)["tag_name"] as String).replaceAll("v", ""); + final currentVersion = packageInfo.version == "Unknown" + ? null + : Version.parse(packageInfo.version); + final latestVersion = tagName == "nightly" ? null : Version.parse(tagName); + + if (currentVersion == null || + latestVersion == null || + (latestVersion.isPreRelease && !currentVersion.isPreRelease) || + (!latestVersion.isPreRelease && currentVersion.isPreRelease)) return; + + if (latestVersion <= currentVersion || !context.mounted) return; + + showDialog( + context: context, + barrierDismissible: true, + barrierColor: Colors.black26, + builder: (context) { + return RootAppUpdateDialog(version: latestVersion); + }, + ); + } }