diff --git a/lib/pages/app.dart b/lib/pages/app.dart index f4f20fc..6970cb3 100644 --- a/lib/pages/app.dart +++ b/lib/pages/app.dart @@ -4,6 +4,7 @@ import 'package:flutter/services.dart'; import 'package:obtainium/components/generated_form_modal.dart'; import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/main.dart'; +import 'package:obtainium/pages/apps.dart'; import 'package:obtainium/pages/settings.dart'; import 'package:obtainium/providers/apps_provider.dart'; import 'package:obtainium/providers/settings_provider.dart'; @@ -108,6 +109,7 @@ class _AppPageState extends State { infoLines = '$infoLines\n${app?.app.apkUrls.length == 1 ? app?.app.apkUrls[0].key : plural('apk', app?.app.apkUrls.length ?? 0)}'; } + var changeLogFn = app != null ? getChangeLogFn(context, app.app) : null; return Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, @@ -125,13 +127,26 @@ class _AppPageState extends State { .textTheme .bodyLarge! .copyWith(fontWeight: FontWeight.bold)), - app?.app.releaseDate == null - ? const SizedBox.shrink() - : Text( - app!.app.releaseDate.toString(), - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.labelSmall, - ), + changeLogFn != null || app?.app.releaseDate != null + ? GestureDetector( + onTap: changeLogFn, + child: Text( + app?.app.releaseDate == null + ? tr('changes') + : app!.app.releaseDate.toString(), + textAlign: TextAlign.center, + style: + Theme.of(context).textTheme.labelSmall!.copyWith( + decoration: changeLogFn != null + ? TextDecoration.underline + : null, + fontStyle: changeLogFn != null + ? FontStyle.italic + : null, + ), + ), + ) + : const SizedBox.shrink(), const SizedBox( height: 8, ), diff --git a/lib/pages/apps.dart b/lib/pages/apps.dart index 0a94dd6..52125ed 100644 --- a/lib/pages/apps.dart +++ b/lib/pages/apps.dart @@ -26,6 +26,92 @@ class AppsPage extends StatefulWidget { State createState() => AppsPageState(); } +showChangeLogDialog(BuildContext context, App app, String? changesUrl, + AppSource appSource, String changeLog) { + showDialog( + context: context, + builder: (BuildContext context) { + return GeneratedFormModal( + title: tr('changes'), + items: const [], + message: app.latestVersion, + additionalWidgets: [ + changesUrl != null + ? GestureDetector( + child: Text( + changesUrl, + style: const TextStyle( + decoration: TextDecoration.underline, + fontStyle: FontStyle.italic), + ), + onTap: () { + launchUrlString(changesUrl, + mode: LaunchMode.externalApplication); + }, + ) + : const SizedBox.shrink(), + changesUrl != null + ? const SizedBox( + height: 16, + ) + : const SizedBox.shrink(), + appSource.changeLogIfAnyIsMarkDown + ? SizedBox( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height - 350, + child: Markdown( + data: changeLog, + onTapLink: (text, href, title) { + if (href != null) { + launchUrlString( + href.startsWith('http://') || + href.startsWith('https://') + ? href + : '${Uri.parse(app.url).origin}/$href', + mode: LaunchMode.externalApplication); + } + }, + extensionSet: md.ExtensionSet( + md.ExtensionSet.gitHubFlavored.blockSyntaxes, + [ + md.EmojiSyntax(), + ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes + ], + ), + )) + : Text(changeLog), + ], + singleNullReturnButton: tr('ok'), + ); + }); +} + +getChangeLogFn(BuildContext context, App app) { + AppSource appSource = + SourceProvider().getSource(app.url, overrideSource: app.overrideSource); + String? changesUrl = appSource.changeLogPageFromStandardUrl(app.url); + String? changeLog = app.changeLog; + if (changeLog?.split('\n').length == 1) { + if (RegExp( + '(http|ftp|https)://([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?') + .hasMatch(changeLog!)) { + if (changesUrl == null) { + changesUrl = changeLog; + changeLog = null; + } + } + } + return (changeLog == null && changesUrl == null) + ? null + : () { + if (changeLog != null) { + showChangeLogDialog(context, app, changesUrl, appSource, changeLog); + } else { + launchUrlString(changesUrl!, mode: LaunchMode.externalApplication); + } + }; +} + class AppsPageState extends State { AppsFilter filter = AppsFilter(); final AppsFilter neutralFilter = AppsFilter(); @@ -262,66 +348,6 @@ class AppsPageState extends State { .where((a) => selectedAppIds.contains(a.id)) .toSet(); - showChangeLogDialog( - String? changesUrl, AppSource appSource, String changeLog, int index) { - showDialog( - context: context, - builder: (BuildContext context) { - return GeneratedFormModal( - title: tr('changes'), - items: const [], - message: listedApps[index].app.latestVersion, - additionalWidgets: [ - changesUrl != null - ? GestureDetector( - child: Text( - changesUrl, - style: const TextStyle( - decoration: TextDecoration.underline, - fontStyle: FontStyle.italic), - ), - onTap: () { - launchUrlString(changesUrl, - mode: LaunchMode.externalApplication); - }, - ) - : const SizedBox.shrink(), - changesUrl != null - ? const SizedBox( - height: 16, - ) - : const SizedBox.shrink(), - appSource.changeLogIfAnyIsMarkDown - ? SizedBox( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height - 350, - child: Markdown( - data: changeLog, - onTapLink: (text, href, title) { - if (href != null) { - launchUrlString( - href.startsWith('http://') || - href.startsWith('https://') - ? href - : '${Uri.parse(listedApps[index].app.url).origin}/$href', - mode: LaunchMode.externalApplication); - } - }, - extensionSet: md.ExtensionSet( - md.ExtensionSet.gitHubFlavored.blockSyntaxes, - [ - md.EmojiSyntax(), - ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes - ], - ), - )) - : Text(changeLog), - ], - singleNullReturnButton: tr('ok'), - ); - }); - } - getLoadingWidgets() { return [ if (listedApps.isEmpty) @@ -351,35 +377,6 @@ class AppsPageState extends State { ]; } - getChangeLogFn(int appIndex) { - AppSource appSource = SourceProvider().getSource( - listedApps[appIndex].app.url, - overrideSource: listedApps[appIndex].app.overrideSource); - String? changesUrl = - appSource.changeLogPageFromStandardUrl(listedApps[appIndex].app.url); - String? changeLog = listedApps[appIndex].app.changeLog; - if (changeLog?.split('\n').length == 1) { - if (RegExp( - '(http|ftp|https)://([\\w_-]+(?:(?:\\.[\\w_-]+)+))([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])?') - .hasMatch(changeLog!)) { - if (changesUrl == null) { - changesUrl = changeLog; - changeLog = null; - } - } - } - return (changeLog == null && changesUrl == null) - ? null - : () { - if (changeLog != null) { - showChangeLogDialog(changesUrl, appSource, changeLog, appIndex); - } else { - launchUrlString(changesUrl!, - mode: LaunchMode.externalApplication); - } - }; - } - getUpdateButton(int appIndex) { return IconButton( visualDensity: VisualDensity.compact, @@ -444,7 +441,7 @@ class AppsPageState extends State { } getSingleAppHorizTile(int index) { - var showChangesFn = getChangeLogFn(index); + var showChangesFn = getChangeLogFn(context, listedApps[index].app); var hasUpdate = listedApps[index].app.installedVersion != null && listedApps[index].app.installedVersion != listedApps[index].app.latestVersion;