Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add in-app changelog #1208

Merged
merged 7 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/core/enums/local_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ enum LocalSettings {
markPostAsReadOnScroll(name: 'setting_general_mark_post_read_on_scroll', key: 'markPostAsReadOnScroll', category: LocalSettingsCategories.general, subCategory: LocalSettingsSubCategories.feed),
showInAppUpdateNotification(
name: 'setting_notifications_show_inapp_update', key: 'showInAppUpdateNotifications', category: LocalSettingsCategories.general, subCategory: LocalSettingsSubCategories.notifications),
showUpdateChangelogs(name: 'setting_show_update_changelogs', key: 'showUpdateChangelogs', category: LocalSettingsCategories.general, subCategory: LocalSettingsSubCategories.notifications),
scoreCounters(name: 'setting_score_counters', key: "showScoreCounters", category: LocalSettingsCategories.general, subCategory: LocalSettingsSubCategories.feed),
appLanguageCode(name: 'setting_app_language_code', key: 'appLanguage', category: LocalSettingsCategories.general, subCategory: LocalSettingsSubCategories.feedTypeAndSorts),
enableInboxNotifications(
Expand Down Expand Up @@ -275,6 +276,7 @@ extension LocalizationExt on AppLocalizations {
'markPostAsReadOnMediaView': markPostAsReadOnMediaView,
'markPostAsReadOnScroll': markPostAsReadOnScroll,
'showInAppUpdateNotifications': showInAppUpdateNotifications,
'showUpdateChangelogs': showUpdateChangelogs,
'enableInboxNotifications': enableInboxNotifications,
'showScoreCounters': showScoreCounters,
'appLanguage': appLanguage,
Expand Down
36 changes: 32 additions & 4 deletions lib/core/update/check_github_update.dart
Original file line number Diff line number Diff line change
@@ -1,28 +1,56 @@
import 'package:thunder/utils/global_context.dart';

import '../../globals.dart' as globals;

import 'dart:convert';

import 'package:http/http.dart' as http;
import 'package:thunder/core/models/version.dart';
import 'package:version/version.dart' as version_parser;
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

Future<String> getCurrentVersion({bool removeInternalBuildNumber = false}) async {
String getCurrentVersion({bool removeInternalBuildNumber = false, bool trimV = false}) {
RegExp regex = RegExp(r'(.+)\+.*');
Match? match = regex.firstMatch(globals.currentVersion);

// When removeInternalBuildNumber is specified, we remove the internal build number (e.g., +17, +18, etc.)
if (removeInternalBuildNumber && match != null) {
return 'v${match.group(1)}';
return '${trimV ? '' : 'v'}${match.group(1)}';
}

return '${trimV ? '' : 'v'}${globals.currentVersion}';
}

String? _currentVersionChangelog;

Future<String> fetchCurrentVersionChangelog() async {
if (_currentVersionChangelog != null) return _currentVersionChangelog!;

const url = 'https://api.github.com/repos/thunder-app/thunder/releases';

final String currentVersion = getCurrentVersion(removeInternalBuildNumber: true, trimV: true);

try {
final response = await http.get(Uri.parse(url)).timeout(const Duration(seconds: 5));

if (response.statusCode == 200) {
var releases = json.decode(response.body);
var thisRelease = (releases as List).firstWhere((release) => release['tag_name'] == currentVersion);
_currentVersionChangelog = thisRelease['body'] as String;
return _currentVersionChangelog!;
}
} catch (e) {
// Ignore, we will return error message below.
}

return 'v${globals.currentVersion}';
return GlobalContext.context.mounted ? AppLocalizations.of(GlobalContext.context)!.unableToRetrieveChangelog(currentVersion) : '';
}

Future<Version> fetchVersion() async {
const url = 'https://api.github.com/repos/thunder-app/thunder/releases';

try {
String currentVersion = await getCurrentVersion();
String currentVersion = getCurrentVersion();
version_parser.Version currentVersionParsed = version_parser.Version.parse(_trimV(currentVersion));

final response = await http.get(Uri.parse(url)).timeout(const Duration(seconds: 5));
Expand Down
32 changes: 32 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@
"@clearedUserPreferences": {},
"close": "Close",
"@close": {},
"collapse": "Collapse",
"@collapse": {
"description": "Action to collapse something"
},
"collapseCommentPreview": "Collapse Comment Preview",
"@collapseCommentPreview": {
"description": "Semantic label for the collapse button in Setting -> Appearance -> Comments"
Expand Down Expand Up @@ -427,6 +431,10 @@
"@displayUserScore": {
"description": "Option for displaying user scores or karma."
},
"doNotShowAgain": "Do Not Show Again",
"@doNotShowAgain": {
"description": "Action for hiding something permanently"
},
"downloadingMedia": "Downloading media to share…",
"@downloadingMedia": {},
"downvote": "Downvote",
Expand Down Expand Up @@ -481,6 +489,10 @@
"@exceptionProcessingUri": {
"description": "An unspecified error during link processing."
},
"expand": "Expand",
"@expand": {
"description": "Action to expand something"
},
"expandCommentPreview": "Expand Comment Preview",
"@expandCommentPreview": {
"description": "Semantic label for the expand button in Setting -> Appearance -> Comments"
Expand Down Expand Up @@ -1447,6 +1459,14 @@
"@showThumbnailPreviewOnRight": {
"description": "Toggle to show thumbnails on the right side."
},
"showUpdateChangelogs": "Show Update Changelogs",
"@showUpdateChangelogs": {
"description": "Setting for showing changelogs after updates"
},
"showUpdateChangelogsSubtitle": "Display a list of changes after an update",
"@showUpdateChangelogsSubtitle": {
"description": "Subtitle for setting for showing changelogs after updates"
},
"showUserDisplayNames": "Show User Display Names",
"@showUserDisplayNames": {
"description": "Toggle to show user display names."
Expand Down Expand Up @@ -1537,6 +1557,10 @@
"@theming": {
"description": "Title of Theming in Settings -> Appearance -> Theming"
},
"thunderHasBeenUpdated": "Thunder has been updated to version {version}!",
"@thunderHasBeenUpdated": {
"description": "Heading for changelog when Thunder has been updated"
},
"timeoutComments": "Error: Timeout when attempting to fetch comments",
"@timeoutComments": {},
"timeoutErrorMessage": "There was a timeout waiting for a response.",
Expand Down Expand Up @@ -1639,6 +1663,10 @@
"@unableToNavigateToInstance": {
"description": "Error message for when we can't navigate to a Lemmy instance"
},
"unableToRetrieveChangelog": "Unable to retrieve changelog for version {version}.",
"@unableToRetrieveChangelog": {
"description": "Error message for when we are unable to retrieve the changelog."
},
"unbannedUser": "Unbanned User",
"@unbannedUser": {
"description": "Short decription for moderator action to unban a user"
Expand Down Expand Up @@ -1751,6 +1779,10 @@
"@username": {},
"users": "Users",
"@users": {},
"versionNumber": "Version {version}",
"@versionNumber": {
"description": "String for describing the current version"
},
"viewAll": "View all",
"@viewAll": {
"description": "A title for viewing all of something (e.g., instances)"
Expand Down
14 changes: 5 additions & 9 deletions lib/settings/pages/about_settings_page.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import 'package:flutter/material.dart';
import 'package:thunder/core/enums/local_settings.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

import 'package:thunder/feed/utils/utils.dart';
import 'package:thunder/feed/view/feed_page.dart';
import 'package:thunder/utils/links.dart';
import 'package:thunder/core/enums/local_settings.dart';
import 'package:thunder/core/update/check_github_update.dart';

class AboutSettingsPage extends StatelessWidget {
Expand All @@ -14,6 +15,7 @@ class AboutSettingsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
final AppLocalizations l10n = AppLocalizations.of(context)!;

return Scaffold(
appBar: AppBar(centerTitle: false),
Expand All @@ -25,14 +27,8 @@ class AboutSettingsPage extends StatelessWidget {
Text('Thunder', style: theme.textTheme.headlineMedium),
Padding(
padding: const EdgeInsets.all(16.0),
child: FutureBuilder(
future: getCurrentVersion(removeInternalBuildNumber: true),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Center(child: Text('Version ${snapshot.data ?? 'N/A'}'));
}
return Container();
},
child: Center(
child: Text(l10n.versionNumber(getCurrentVersion(removeInternalBuildNumber: true))),
),
),
ListView(
Expand Down
19 changes: 19 additions & 0 deletions lib/settings/pages/general_settings_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ class _GeneralSettingsPageState extends State<GeneralSettingsPage> with SingleTi
/// When enabled, an app update notification will be shown when an update is available
bool showInAppUpdateNotification = false;

/// When enabled, an in-app "notification" will be shown that lets the user view the changelog
bool showUpdateChangelogs = true;

/// When enabled, system-level notifications will be displayed for new inbox messages
bool enableInboxNotifications = false;

Expand Down Expand Up @@ -190,6 +193,10 @@ class _GeneralSettingsPageState extends State<GeneralSettingsPage> with SingleTi
await prefs.setBool(LocalSettings.showInAppUpdateNotification.name, value);
setState(() => showInAppUpdateNotification = value);
break;
case LocalSettings.showUpdateChangelogs:
await prefs.setBool(LocalSettings.showUpdateChangelogs.name, value);
setState(() => showUpdateChangelogs = value);
break;
case LocalSettings.enableInboxNotifications:
await prefs.setBool(LocalSettings.enableInboxNotifications.name, value);
setState(() => enableInboxNotifications = value);
Expand Down Expand Up @@ -251,6 +258,7 @@ class _GeneralSettingsPageState extends State<GeneralSettingsPage> with SingleTi
imageCachingMode = ImageCachingMode.values.byName(prefs.getString(LocalSettings.imageCachingMode.name) ?? ImageCachingMode.relaxed.name);

showInAppUpdateNotification = prefs.getBool(LocalSettings.showInAppUpdateNotification.name) ?? false;
showUpdateChangelogs = prefs.getBool(LocalSettings.showUpdateChangelogs.name) ?? true;
enableInboxNotifications = prefs.getBool(LocalSettings.enableInboxNotifications.name) ?? false;
});
}
Expand Down Expand Up @@ -713,6 +721,17 @@ class _GeneralSettingsPageState extends State<GeneralSettingsPage> with SingleTi
highlightKey: settingToHighlight == LocalSettings.showInAppUpdateNotification ? settingToHighlightKey : null,
),
),
SliverToBoxAdapter(
child: ToggleOption(
description: l10n.showUpdateChangelogs,
subtitle: l10n.showUpdateChangelogsSubtitle,
value: showUpdateChangelogs,
iconEnabled: Icons.featured_play_list_rounded,
iconDisabled: Icons.featured_play_list_outlined,
onToggle: (bool value) => setPreferences(LocalSettings.showUpdateChangelogs, value),
highlightKey: settingToHighlight == LocalSettings.showUpdateChangelogs ? settingToHighlightKey : null,
),
),
if (!kIsWeb && Platform.isAndroid)
SliverToBoxAdapter(
child: ToggleOption(
Expand Down
16 changes: 3 additions & 13 deletions lib/settings/pages/settings_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -159,19 +159,9 @@ class _SettingsPageState extends State<SettingsPage> {
hasScrollBody: false,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: FutureBuilder(
future: getCurrentVersion(removeInternalBuildNumber: true),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Align(
alignment: Alignment.bottomCenter,
child: Text(
'Thunder ${snapshot.data ?? 'N/A'}',
),
);
}
return Container();
},
child: Align(
alignment: Alignment.bottomCenter,
child: Text('Thunder ${getCurrentVersion(removeInternalBuildNumber: true)}'),
),
),
)
Expand Down
2 changes: 2 additions & 0 deletions lib/thunder/bloc/thunder_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class ThunderBloc extends Bloc<ThunderEvent, ThunderState> {
bool markPostReadOnMediaView = prefs.getBool(LocalSettings.markPostAsReadOnMediaView.name) ?? false;
bool markPostReadOnScroll = prefs.getBool(LocalSettings.markPostAsReadOnScroll.name) ?? false;
bool showInAppUpdateNotification = prefs.getBool(LocalSettings.showInAppUpdateNotification.name) ?? false;
bool showUpdateChangelogs = prefs.getBool(LocalSettings.showUpdateChangelogs.name) ?? true;
bool enableInboxNotifications = prefs.getBool(LocalSettings.enableInboxNotifications.name) ?? false;
String? appLanguageCode = prefs.getString(LocalSettings.appLanguageCode.name) ?? 'en';
FullNameSeparator userSeparator = FullNameSeparator.values.byName(prefs.getString(LocalSettings.userFormat.name) ?? FullNameSeparator.at.name);
Expand Down Expand Up @@ -255,6 +256,7 @@ class ThunderBloc extends Bloc<ThunderEvent, ThunderState> {
markPostReadOnMediaView: markPostReadOnMediaView,
markPostReadOnScroll: markPostReadOnScroll,
showInAppUpdateNotification: showInAppUpdateNotification,
showUpdateChangelogs: showUpdateChangelogs,
enableInboxNotifications: enableInboxNotifications,
appLanguageCode: appLanguageCode,
userSeparator: userSeparator,
Expand Down
5 changes: 5 additions & 0 deletions lib/thunder/bloc/thunder_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class ThunderState extends Equatable {
this.markPostReadOnScroll = false,
this.disableFeedFab = false,
this.showInAppUpdateNotification = false,
this.showUpdateChangelogs = true,
this.enableInboxNotifications = false,
this.scoreCounters = false,
this.userSeparator = FullNameSeparator.at,
Expand Down Expand Up @@ -165,6 +166,7 @@ class ThunderState extends Equatable {
final bool markPostReadOnScroll;
final bool disableFeedFab;
final bool showInAppUpdateNotification;
final bool showUpdateChangelogs;
final bool enableInboxNotifications;
final String? appLanguageCode;
final FullNameSeparator userSeparator;
Expand Down Expand Up @@ -307,6 +309,7 @@ class ThunderState extends Equatable {
bool? markPostReadOnMediaView,
bool? markPostReadOnScroll,
bool? showInAppUpdateNotification,
bool? showUpdateChangelogs,
bool? enableInboxNotifications,
bool? scoreCounters,
FullNameSeparator? userSeparator,
Expand Down Expand Up @@ -441,6 +444,7 @@ class ThunderState extends Equatable {
markPostReadOnScroll: markPostReadOnScroll ?? this.markPostReadOnScroll,
disableFeedFab: disableFeedFab,
showInAppUpdateNotification: showInAppUpdateNotification ?? this.showInAppUpdateNotification,
showUpdateChangelogs: showUpdateChangelogs ?? this.showUpdateChangelogs,
enableInboxNotifications: enableInboxNotifications ?? this.enableInboxNotifications,
scoreCounters: scoreCounters ?? this.scoreCounters,
appLanguageCode: appLanguageCode ?? this.appLanguageCode,
Expand Down Expand Up @@ -583,6 +587,7 @@ class ThunderState extends Equatable {
markPostReadOnScroll,
disableFeedFab,
showInAppUpdateNotification,
showUpdateChangelogs,
enableInboxNotifications,
userSeparator,
communitySeparator,
Expand Down
Loading
Loading