From 7ddd0ac26ab34b0ff10471d6f5e7f9b423539ac0 Mon Sep 17 00:00:00 2001 From: Tommy Chow Date: Tue, 13 Aug 2024 00:41:06 -0700 Subject: [PATCH] Add release notes on launch (#375) * Add markdown release notes * Show release notes on first launch * Update release notes and styles --- assets/release-notes.md | 10 +++ lib/screens/home/home.dart | 28 ++++++++ lib/screens/settings/other_settings.dart | 14 ++-- .../settings/widgets/release_notes.dart | 66 +++++++++++++++++++ pubspec.lock | 16 +++++ pubspec.yaml | 2 + 6 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 assets/release-notes.md create mode 100644 lib/screens/settings/widgets/release_notes.dart diff --git a/assets/release-notes.md b/assets/release-notes.md new file mode 100644 index 00000000..5ea5b358 --- /dev/null +++ b/assets/release-notes.md @@ -0,0 +1,10 @@ +## v4.3.1 + +April 21, 2024 + +### Bug Fixes +* [Android] Fixed stream quality options not showing by @Shingyx in https://github.com/tommyxchow/frosty/pull/340 +* Fixed stream latency not showing by @Shingyx in https://github.com/tommyxchow/frosty/pull/340 +* Fixed stream latency icon color on light mode + +#### See all release notes at https://github.com/tommyxchow/frosty/releases diff --git a/lib/screens/home/home.dart b/lib/screens/home/home.dart index cda33e7e..3fcd8170 100644 --- a/lib/screens/home/home.dart +++ b/lib/screens/home/home.dart @@ -9,8 +9,11 @@ import 'package:frosty/screens/home/top/top.dart'; import 'package:frosty/screens/settings/settings.dart'; import 'package:frosty/screens/settings/stores/auth_store.dart'; import 'package:frosty/screens/settings/stores/settings_store.dart'; +import 'package:frosty/screens/settings/widgets/release_notes.dart'; import 'package:frosty/widgets/profile_picture.dart'; +import 'package:package_info_plus/package_info_plus.dart'; import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class Home extends StatefulWidget { const Home({super.key}); @@ -24,6 +27,31 @@ class _HomeState extends State { late final _homeStore = HomeStore(authStore: _authStore); + Future checkAndShowReleaseNotes() async { + final packageInfo = await PackageInfo.fromPlatform(); + final prefs = await SharedPreferences.getInstance(); + + final currentVersion = packageInfo.version; + final storedVersion = prefs.getString('last_shown_version'); + + if (storedVersion == null || storedVersion != currentVersion) { + if (!mounted) return; + + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const ReleaseNotes()), + ); + + await prefs.setString('last_shown_version', currentVersion); + } + } + + @override + void initState() { + super.initState(); + checkAndShowReleaseNotes(); + } + @override Widget build(BuildContext context) { SystemChrome.setPreferredOrientations([]); diff --git a/lib/screens/settings/other_settings.dart b/lib/screens/settings/other_settings.dart index 1f25a2ed..ee1c3955 100644 --- a/lib/screens/settings/other_settings.dart +++ b/lib/screens/settings/other_settings.dart @@ -7,6 +7,7 @@ import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:frosty/screens/settings/stores/settings_store.dart'; +import 'package:frosty/screens/settings/widgets/release_notes.dart'; import 'package:frosty/screens/settings/widgets/settings_list_switch.dart'; import 'package:frosty/widgets/alert_message.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -86,13 +87,12 @@ class _OtherSettingsState extends State { }, ), ListTile( - leading: const Icon(Icons.launch_rounded), - title: const Text('Changelog'), - onTap: () => launchUrl( - Uri.parse('https://github.com/tommyxchow/frosty/releases'), - mode: widget.settingsStore.launchUrlExternal - ? LaunchMode.externalApplication - : LaunchMode.inAppBrowserView, + leading: const Icon(Icons.notes_rounded), + title: const Text('Release notes'), + onTap: () => Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => const ReleaseNotes(), + ), ), ), ListTile( diff --git a/lib/screens/settings/widgets/release_notes.dart b/lib/screens/settings/widgets/release_notes.dart new file mode 100644 index 00000000..8b0b536a --- /dev/null +++ b/lib/screens/settings/widgets/release_notes.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:frosty/screens/settings/stores/settings_store.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher_string.dart'; + +class ReleaseNotes extends StatefulWidget { + const ReleaseNotes({super.key}); + + @override + State createState() => _ReleaseNotesState(); +} + +class _ReleaseNotesState extends State { + String releaseNotes = ''; + + @override + void initState() { + super.initState(); + + rootBundle.loadString('assets/release-notes.md').then( + (changelog) { + setState(() { + releaseNotes = changelog; + }); + }, + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Release notes'), + ), + body: Column( + children: [ + Expanded( + child: Markdown( + data: releaseNotes, + styleSheet: MarkdownStyleSheet( + h2: const TextStyle(fontSize: 20), + h3: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600), + h3Padding: const EdgeInsets.only(top: 16), + h4: const TextStyle(fontSize: 14), + h4Padding: const EdgeInsets.only(top: 16), + p: const TextStyle(fontSize: 14), + ), + onTapLink: (text, href, title) { + if (href != null) { + launchUrlString( + href, + mode: context.read().launchUrlExternal + ? LaunchMode.externalApplication + : LaunchMode.inAppBrowserView, + ); + } + }, + ), + ), + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index f91664a8..3aa90028 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -427,6 +427,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + sha256: a23c41ee57573e62fc2190a1f36a0480c4d90bde3a8a8d7126e5d5992fb53fb7 + url: "https://pub.dev" + source: hosted + version: "0.7.3+1" flutter_mobx: dependency: "direct main" description: @@ -677,6 +685,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.2-main.4" + markdown: + dependency: transitive + description: + name: markdown + sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051 + url: "https://pub.dev" + source: hosted + version: "7.2.2" matcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1294b63d..2c952a3b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,6 +65,7 @@ dependencies: webview_flutter_android: ^3.7.0 webview_flutter_wkwebview: ^3.4.3 photo_view: ^0.15.0 + flutter_markdown: ^0.7.3+1 dev_dependencies: flutter_test: @@ -123,6 +124,7 @@ flutter: assets: - assets/icons/logo.svg - assets/fonts/ + - assets/release-notes.md # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images