From 280827d8ec1a23d8668150c171740e958d4b5213 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Sun, 19 Mar 2023 12:38:57 -0400 Subject: [PATCH 1/6] Changelog now rendered as MarkDown --- lib/components/generated_form.dart | 1 + lib/pages/apps.dart | 34 +++++++++++++++++++++++------- pubspec.lock | 16 ++++++++++++++ pubspec.yaml | 1 + 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/lib/components/generated_form.dart b/lib/components/generated_form.dart index a9cdfc0..a281899 100644 --- a/lib/components/generated_form.dart +++ b/lib/components/generated_form.dart @@ -476,6 +476,7 @@ class _GeneratedFormState extends State { rowItems.add(Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.min, children: [ rowInput.value, ...widget.items[rowInputs.key][rowInput.key].belowWidgets diff --git a/lib/pages/apps.dart b/lib/pages/apps.dart index 8da87c2..393c2ff 100644 --- a/lib/pages/apps.dart +++ b/lib/pages/apps.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:obtainium/components/custom_app_bar.dart'; import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/components/generated_form_modal.dart'; @@ -14,6 +15,7 @@ import 'package:obtainium/providers/source_provider.dart'; import 'package:provider/provider.dart'; import 'package:share_plus/share_plus.dart'; import 'package:url_launcher/url_launcher_string.dart'; +import 'package:markdown/markdown.dart' as md; class AppsPage extends StatefulWidget { const AppsPage({super.key}); @@ -242,14 +244,8 @@ class AppsPageState extends State { builder: (BuildContext context) { return GeneratedFormModal( title: tr('changes'), - items: [], + items: const [], additionalWidgets: [ - Text(changeLog), - changesUrl != null - ? const SizedBox( - height: 16, - ) - : const SizedBox.shrink(), changesUrl != null ? GestureDetector( child: Text( @@ -265,7 +261,29 @@ class AppsPageState extends State { .externalApplication); }, ) - : const SizedBox.shrink() + : const SizedBox.shrink(), + changesUrl != null + ? const SizedBox( + height: 16, + ) + : const SizedBox.shrink(), + SizedBox( + width: MediaQuery.of(context).size.width, + height: + MediaQuery.of(context).size.height - + 350, + child: Markdown( + data: changeLog, + extensionSet: md.ExtensionSet( + md.ExtensionSet.gitHubFlavored + .blockSyntaxes, + [ + md.EmojiSyntax(), + ...md.ExtensionSet.gitHubFlavored + .inlineSyntaxes + ], + ), + )), ], singleNullReturnButton: tr('ok'), ); diff --git a/pubspec.lock b/pubspec.lock index 9dea795..b0b7d14 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -235,6 +235,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + sha256: "7b25c10de1fea883f3c4f9b8389506b54053cd00807beab69fd65c8653a2711f" + url: "https://pub.dev" + source: hosted + version: "0.6.14" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -325,6 +333,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + markdown: + dependency: transitive + description: + name: markdown + sha256: b3c60dee8c2af50ad0e6e90cceba98e47718a6ee0a7a6772c77846a0cc21f78b + url: "https://pub.dev" + source: hosted + version: "7.0.1" matcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index e061020..932daf5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,6 +59,7 @@ dependencies: sqflite: ^2.2.0+3 easy_localization: ^3.0.1 android_intent_plus: ^3.1.5 + flutter_markdown: ^0.6.14 dev_dependencies: From f1fc43a3e70f369c4dc4f35d9ca850a071a51924 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Sun, 19 Mar 2023 12:44:17 -0400 Subject: [PATCH 2/6] Don't show 'Changes' button if it doesn't do anything --- lib/pages/apps.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/pages/apps.dart b/lib/pages/apps.dart index 393c2ff..3e5084e 100644 --- a/lib/pages/apps.dart +++ b/lib/pages/apps.dart @@ -431,7 +431,9 @@ class AppsPageState extends State { child: Text( listedApps[index].app.releaseDate == null - ? tr('changes') + ? showChanges != null + ? tr('changes') + : '' : DateFormat('yyyy-MM-dd') .format(listedApps[index] .app From 48d2532323c9a5fa7649e4c4f04af61cec2c1a8a Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Sun, 19 Mar 2023 12:49:43 -0400 Subject: [PATCH 3/6] Links in changelog openable --- lib/pages/apps.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/pages/apps.dart b/lib/pages/apps.dart index 3e5084e..412d8f1 100644 --- a/lib/pages/apps.dart +++ b/lib/pages/apps.dart @@ -274,6 +274,18 @@ class AppsPageState extends State { 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, From 6db31e2b240842c7284bfb5d13e875a0e6aec0e8 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Sun, 19 Mar 2023 12:52:34 -0400 Subject: [PATCH 4/6] Support for normal text changelogs (by Source) --- lib/pages/apps.dart | 68 +++++++++++++++++------------- lib/providers/source_provider.dart | 1 + 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/lib/pages/apps.dart b/lib/pages/apps.dart index 412d8f1..a0beb61 100644 --- a/lib/pages/apps.dart +++ b/lib/pages/apps.dart @@ -231,8 +231,9 @@ class AppsPageState extends State { SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { - String? changesUrl = SourceProvider() - .getSource(listedApps[index].app.url) + AppSource appSource = + SourceProvider().getSource(listedApps[index].app.url); + String? changesUrl = appSource .changeLogPageFromStandardUrl(listedApps[index].app.url); String? changeLog = listedApps[index].app.changeLog; var showChanges = (changeLog == null && changesUrl == null) @@ -267,35 +268,42 @@ class AppsPageState extends State { height: 16, ) : const SizedBox.shrink(), - SizedBox( - width: MediaQuery.of(context).size.width, - height: - MediaQuery.of(context).size.height - + 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 - ], - ), - )), + 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'), ); diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index 270b4c4..fd4254d 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -228,6 +228,7 @@ class AppSource { String? host; late String name; bool enforceTrackOnly = false; + bool changeLogIfAnyIsMarkDown = true; AppSource() { name = runtimeType.toString(); From 08555bac753419adda8c7c757c78684eb851260f Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Sun, 19 Mar 2023 13:50:14 -0400 Subject: [PATCH 5/6] Added VLC as a Source --- README.md | 1 + lib/app_sources/vlc.dart | 62 ++++++++++++++++++++++++++++++ lib/providers/source_provider.dart | 2 + 3 files changed, 65 insertions(+) create mode 100644 lib/app_sources/vlc.dart diff --git a/README.md b/README.md index 3766352..107e70f 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Currently supported App sources: - Any URLs ending with `/fdroid/`, where `` can be anything - most often `repo` - [Steam](https://store.steampowered.com/mobile) - [Telegram App](https://telegram.org) +- [VLC](https://www.videolan.org/vlc/download-android.html) - [Neutron Code](https://neutroncode.com) - "HTML" (Fallback) - Any other URL that returns an HTML page with links to APK files (if multiple, the last file alphabetically is picked) diff --git a/lib/app_sources/vlc.dart b/lib/app_sources/vlc.dart new file mode 100644 index 0000000..e4678d7 --- /dev/null +++ b/lib/app_sources/vlc.dart @@ -0,0 +1,62 @@ +import 'package:html/parser.dart'; +import 'package:http/http.dart'; +import 'package:obtainium/app_sources/html.dart'; +import 'package:obtainium/custom_errors.dart'; +import 'package:obtainium/providers/source_provider.dart'; + +class VLC extends AppSource { + VLC() { + host = 'videolan.org'; + } + + @override + String standardizeURL(String url) { + return 'https://$host'; + } + + @override + Future getLatestAPKDetails( + String standardUrl, + Map additionalSettings, + ) async { + Response res = await get( + Uri.parse('https://www.videolan.org/vlc/download-android.html')); + if (res.statusCode == 200) { + var dwUrlBase = 'get.videolan.org/vlc-android'; + var dwLinks = parse(res.body) + .querySelectorAll('a') + .where((element) => + element.attributes['href']?.contains(dwUrlBase) ?? false) + .toList(); + String? version = dwLinks.isNotEmpty + ? dwLinks.first.attributes['href'] + ?.split('/') + .where((s) => s.isNotEmpty) + .last + : null; + if (version == null) { + throw NoVersionError(); + } + String? targetUrl = 'https://$dwUrlBase/$version/'; + Response res2 = await get(Uri.parse(targetUrl)); + String mirrorDwBase = + 'https://plug-mirror.rcac.purdue.edu/vlc/vlc-android/$version/'; + List apkUrls = []; + if (res2.statusCode == 200) { + apkUrls = parse(res2.body) + .querySelectorAll('a') + .map((e) => e.attributes['href']) + .where((h) => + h != null && h.isNotEmpty && h.toLowerCase().endsWith('.apk')) + .map((e) => mirrorDwBase + e!) + .toList(); + } else { + throw getObtainiumHttpError(res2); + } + + return APKDetails(version, apkUrls, AppNames('VideoLAN', 'VLC')); + } else { + throw getObtainiumHttpError(res); + } + } +} diff --git a/lib/providers/source_provider.dart b/lib/providers/source_provider.dart index fd4254d..1b19c19 100644 --- a/lib/providers/source_provider.dart +++ b/lib/providers/source_provider.dart @@ -20,6 +20,7 @@ import 'package:obtainium/app_sources/signal.dart'; import 'package:obtainium/app_sources/sourceforge.dart'; import 'package:obtainium/app_sources/steammobile.dart'; import 'package:obtainium/app_sources/telegramapp.dart'; +import 'package:obtainium/app_sources/vlc.dart'; import 'package:obtainium/components/generated_form.dart'; import 'package:obtainium/custom_errors.dart'; import 'package:obtainium/mass_app_sources/githubstars.dart'; @@ -348,6 +349,7 @@ class SourceProvider { FDroidRepo(), SteamMobile(), TelegramApp(), + VLC(), NeutronCode(), HTML() // This should ALWAYS be the last option as they are tried in order ]; From 1112c79c149e7a8dc88b0d03d16e8fa3f9f1e2da Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Sun, 19 Mar 2023 13:53:40 -0400 Subject: [PATCH 6/6] Increment version --- lib/main.dart | 2 +- pubspec.lock | 8 ++++---- pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index fec7297..7be4cea 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,7 +21,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart'; // ignore: implementation_imports import 'package:easy_localization/src/localization.dart'; -const String currentVersion = '0.11.11'; +const String currentVersion = '0.11.12'; const String currentReleaseTag = 'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES diff --git a/pubspec.lock b/pubspec.lock index b0b7d14..66602aa 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -718,10 +718,10 @@ packages: dependency: transitive description: name: url_launcher_ios - sha256: "7ab1e5b646623d6a2537aa59d5d039f90eebef75a7c25e105f6f75de1f7750c3" + sha256: "3dedc66ca3c0bef9e6a93c0999aee102556a450afcc1b7bcfeace7a424927d92" url: "https://pub.dev" source: hosted - version: "6.1.2" + version: "6.1.3" url_launcher_linux: dependency: transitive description: @@ -782,10 +782,10 @@ packages: dependency: "direct main" description: name: webview_flutter - sha256: b6cd42db3ced5411f3d01599906156885b18e4188f7065a8a351eb84bee347e0 + sha256: "47663d51a9061451aa3880a214ee9a65dcbb933b77bc44388e194279ab3ccaf6" url: "https://pub.dev" source: hosted - version: "4.0.6" + version: "4.0.7" webview_flutter_android: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 932daf5..0a5d632 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 0.11.11+132 # When changing this, update the tag in main() accordingly +version: 0.11.12+133 # When changing this, update the tag in main() accordingly environment: sdk: '>=2.18.2 <3.0.0'