diff --git a/lib/data/shared_prefs_service.dart b/lib/data/shared_prefs_service.dart index 57f947d..2662d7f 100644 --- a/lib/data/shared_prefs_service.dart +++ b/lib/data/shared_prefs_service.dart @@ -32,6 +32,8 @@ class UserPreferencesService { static const primaryColorKey = "primaryColor"; static const dynamicColorKey = "dynamicColor"; + static const seenChangelogVersionKey = "seenChangelogVersion"; + final SharedPreferences _sharedPreferences; UserPreferencesService(this._sharedPreferences) { @@ -157,4 +159,7 @@ class UserPreferencesService { bool get dynamicColor => _sharedPreferences.getBool(dynamicColorKey) ?? false; set dynamicColor(bool value) => _sharedPreferences.setBool(dynamicColorKey, value); + + String get seenChangelogVersion => _sharedPreferences.getString(seenChangelogVersionKey) ?? ''; + set seenChangelogVersion(String value) => _sharedPreferences.setString(seenChangelogVersionKey, value); } diff --git a/lib/screens/shared/release_notes_dialog/bloc_release_notes.dart b/lib/screens/shared/release_notes_dialog/bloc_release_notes.dart new file mode 100644 index 0000000..c7c2bc9 --- /dev/null +++ b/lib/screens/shared/release_notes_dialog/bloc_release_notes.dart @@ -0,0 +1,27 @@ +import 'dart:async'; + +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:lightmeter/data/shared_prefs_service.dart'; +import 'package:lightmeter/screens/shared/release_notes_dialog/state_release_notes.dart'; +import 'package:package_info_plus/package_info_plus.dart'; + +class ReleaseNotesBloc extends Cubit { + final UserPreferencesService _userPreferencesService; + + ReleaseNotesBloc(this._userPreferencesService) : super(const HiddenReleaseNotesDialogState()) { + _showDialogIfNeeded(); + } + + Future _showDialogIfNeeded() async { + PackageInfo.fromPlatform().then((value) { + emit(ShowReleaseNotesDialogState(value.version)); + if (value.version != _userPreferencesService.seenChangelogVersion) { + emit(ShowReleaseNotesDialogState(value.version)); + } + }); + } + + void setChangelogVersion() { + _userPreferencesService.seenChangelogVersion = (state as ShowReleaseNotesDialogState).version; + } +} diff --git a/lib/screens/shared/release_notes_dialog/flow_dialog_release_notes.dart b/lib/screens/shared/release_notes_dialog/flow_dialog_release_notes.dart new file mode 100644 index 0000000..b52710e --- /dev/null +++ b/lib/screens/shared/release_notes_dialog/flow_dialog_release_notes.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:lightmeter/providers/services_provider.dart'; +import 'package:lightmeter/screens/shared/release_notes_dialog/bloc_release_notes.dart'; +import 'package:lightmeter/screens/shared/release_notes_dialog/state_release_notes.dart'; +import 'package:lightmeter/screens/shared/release_notes_dialog/widget_dialog_release_notes.dart'; + +class ReleaseNotesFlow extends StatelessWidget { + final Widget child; + + const ReleaseNotesFlow({required this.child, super.key}); + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => ReleaseNotesBloc(ServicesProvider.of(context).userPreferencesService), + child: BlocListener( + listener: (context, state) { + if (state is ShowReleaseNotesDialogState) { + showDialog( + context: context, + builder: (_) => ReleaseNotesDialog(version: state.version), + ).then((_) => context.read().setChangelogVersion()); + } + }, + child: child, + ), + ); + } +} diff --git a/lib/screens/shared/release_notes_dialog/state_release_notes.dart b/lib/screens/shared/release_notes_dialog/state_release_notes.dart new file mode 100644 index 0000000..73404ec --- /dev/null +++ b/lib/screens/shared/release_notes_dialog/state_release_notes.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; + +@immutable +sealed class ReleaseNotesState { + const ReleaseNotesState(); +} + +class HiddenReleaseNotesDialogState extends ReleaseNotesState { + const HiddenReleaseNotesDialogState(); +} + +class ShowReleaseNotesDialogState extends ReleaseNotesState { + final String version; + + const ShowReleaseNotesDialogState(this.version); +} diff --git a/lib/screens/shared/release_notes_dialog/widget_dialog_release_notes.dart b/lib/screens/shared/release_notes_dialog/widget_dialog_release_notes.dart index 271de44..390399d 100644 --- a/lib/screens/shared/release_notes_dialog/widget_dialog_release_notes.dart +++ b/lib/screens/shared/release_notes_dialog/widget_dialog_release_notes.dart @@ -1,12 +1,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart' show rootBundle; +import 'package:lightmeter/data/models/supported_locale.dart'; import 'package:lightmeter/generated/l10n.dart'; import 'package:lightmeter/providers/user_preferences_provider.dart'; import 'package:lightmeter/res/dimens.dart'; -import 'package:package_info_plus/package_info_plus.dart'; class ReleaseNotesDialog extends StatelessWidget { - const ReleaseNotesDialog({super.key}); + final String version; + + const ReleaseNotesDialog({required this.version, super.key}); @override Widget build(BuildContext context) { @@ -16,12 +18,9 @@ class ReleaseNotesDialog extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - FutureBuilder( - future: PackageInfo.fromPlatform(), - builder: (context, snapshot) => Text( - S.of(context).changesInVersion(snapshot.data?.version ?? ''), - style: Theme.of(context).textTheme.titleSmall, - ), + Text( + S.of(context).changesInVersion(version), + style: Theme.of(context).textTheme.titleSmall, ), const SizedBox(height: Dimens.grid8), FutureBuilder( @@ -41,12 +40,19 @@ class ReleaseNotesDialog extends StatelessWidget { } Future loadReleaseNotes(BuildContext context) async { - String path(String locale) => 'assets/release_notes/release_notes_$locale.md'; + late final String localeName; + + switch (UserPreferencesProvider.localeOf(context)) { + case SupportedLocale.ru: + localeName = SupportedLocale.ru.name; + default: + localeName = SupportedLocale.en.name; + } try { - return rootBundle.loadString(path(UserPreferencesProvider.localeOf(context).name)); + return rootBundle.loadString('assets/release_notes/release_notes_${localeName}_$version.md'); } catch (e) { - return rootBundle.loadString(path('en')); + return ''; } } }