diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..1647a4e0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +# Welcome! + +This is the first release of Gear on the Go. \ No newline at end of file diff --git a/lib/Frontend/go_router_config.dart b/lib/Frontend/go_router_config.dart index 5c45f344..629f76e9 100644 --- a/lib/Frontend/go_router_config.dart +++ b/lib/Frontend/go_router_config.dart @@ -9,6 +9,7 @@ import 'package:tail_app/Frontend/pages/developer/developer_menu.dart'; import 'package:tail_app/Frontend/pages/developer/developer_pincode.dart'; import 'package:tail_app/Frontend/pages/direct_gear_control.dart'; import 'package:tail_app/Frontend/pages/intro.dart'; +import 'package:tail_app/Frontend/pages/markdown_viewer.dart'; import 'package:tail_app/Frontend/pages/more.dart'; import 'package:tail_app/Frontend/pages/move_list.dart'; import 'package:tail_app/Frontend/pages/ota_update.dart'; @@ -96,6 +97,14 @@ final GoRouter router = GoRouter( parentNavigatorKey: _rootNavigatorKey, builder: (BuildContext context, GoRouterState state) => ViewPDF(assetPath: state.extra! as String), ), + GoRoute( + name: 'More/viewMarkdown', + path: 'viewMarkdown', + parentNavigatorKey: _rootNavigatorKey, + builder: (BuildContext context, GoRouterState state) { + return MarkdownViewer(markdownInfo: state.extra! as MarkdownInfo); + }, + ), ], pageBuilder: (context, state) { return NoTransitionPage( diff --git a/lib/Frontend/intn_defs.dart b/lib/Frontend/intn_defs.dart index 62a629bd..53ea920a 100644 --- a/lib/Frontend/intn_defs.dart +++ b/lib/Frontend/intn_defs.dart @@ -253,7 +253,9 @@ String moreManualSubTitle() => Intl.message('Tap to view', name: 'moreManualSubT String moreUsefulLinksTitle() => Intl.message("Useful Links", name: 'moreUsefulLinksTitle', desc: 'Title for Useful Links header on More page'); -String morePrivacyPolicyLinkTitle() => Intl.message("Privacy Policy", name: 'morePrivacyPolicyLinkTitle', desc: 'Title for UPrivacy policy link under Useful Links on More page'); +String morePrivacyPolicyLinkTitle() => Intl.message("Privacy Policy", name: 'morePrivacyPolicyLinkTitle', desc: 'Title for Privacy policy link under Useful Links on More page'); + +String homeChangelogLinkTitle() => Intl.message("Changelog", name: 'homeChangelogLinkTitle', desc: 'Title for Changelog on Home page'); String moreTitle() => Intl.message("More", name: 'moreTitle', desc: 'Title for More page'); diff --git a/lib/Frontend/pages/home.dart b/lib/Frontend/pages/home.dart index 620770ab..ba0222bf 100644 --- a/lib/Frontend/pages/home.dart +++ b/lib/Frontend/pages/home.dart @@ -1,12 +1,15 @@ import 'package:app_settings/app_settings.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:go_router/go_router.dart'; import 'package:logging/logging.dart' as log; import 'package:tail_app/Backend/Bluetooth/bluetooth_manager_plus.dart'; import 'package:tail_app/constants.dart'; import 'package:url_launcher/url_launcher.dart'; import '../intn_defs.dart'; +import 'markdown_viewer.dart'; final log.Logger homeLogger = log.Logger('Home'); @@ -63,16 +66,20 @@ class _HomeState extends ConsumerState { title: Text(subTitle()), subtitle: const Text('This is a fan made app to control The Tail Company tails, ears, and wings'), ), - Row( - mainAxisAlignment: MainAxisAlignment.end, + ButtonBar( children: [ + TextButton( + onPressed: () async { + context.push('/more/viewMarkdown/', extra: MarkdownInfo(content: await rootBundle.loadString('CHANGELOG.md'), title: homeChangelogLinkTitle())); + }, + child: Text(homeChangelogLinkTitle()), + ), TextButton( onPressed: () async { await launchUrl(Uri.parse('https://thetailcompany.com?utm_source=Tail_App')); }, child: const Text('Tail Company Store'), ), - const SizedBox(width: 8), ], ), ], diff --git a/lib/Frontend/pages/markdown_viewer.dart b/lib/Frontend/pages/markdown_viewer.dart new file mode 100644 index 00000000..259def7e --- /dev/null +++ b/lib/Frontend/pages/markdown_viewer.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:markdown/markdown.dart' as md; +import 'package:url_launcher/url_launcher.dart'; + +class MarkdownInfo { + final String content; + final String title; + + MarkdownInfo({required this.content, required this.title}); +} + +class MarkdownViewer extends StatefulWidget { + const MarkdownViewer({super.key, required this.markdownInfo}); + + final MarkdownInfo markdownInfo; + + @override + _MarkdownViewerState createState() => _MarkdownViewerState(); +} + +class _MarkdownViewerState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.markdownInfo.title), + ), + body: Markdown( + data: widget.markdownInfo.content, + extensionSet: md.ExtensionSet( + md.ExtensionSet.gitHubFlavored.blockSyntaxes, + [md.EmojiSyntax(), ...md.ExtensionSet.gitHubFlavored.inlineSyntaxes], + ), + onTapLink: (linkText, linkUrl, linkTitle) async => await launchUrl(Uri.parse(linkUrl!)), + ), + ); + } +} diff --git a/lib/Frontend/pages/more.dart b/lib/Frontend/pages/more.dart index 74a97f20..054fe4cb 100644 --- a/lib/Frontend/pages/more.dart +++ b/lib/Frontend/pages/more.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:feedback_sentry/feedback_sentry.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -10,6 +11,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry_hive/sentry_hive.dart'; import 'package:tail_app/Frontend/intn_defs.dart'; +import 'package:tail_app/Frontend/pages/markdown_viewer.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../constants.dart'; @@ -128,7 +130,7 @@ class _MoreState extends ConsumerState { title: Text(morePrivacyPolicyLinkTitle()), leading: const Icon(Icons.privacy_tip), onTap: () async { - await launchUrl(Uri.parse('https://github.com/Codel1417/tail_app/blob/master/PRIVACY.md')); + context.push('/more/viewMarkdown/', extra: MarkdownInfo(content: await rootBundle.loadString('PRIVACY.md'), title: morePrivacyPolicyLinkTitle())); }, ), ListTile( diff --git a/pubspec.lock b/pubspec.lock index a25306a3..154310c3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -651,6 +651,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_markdown: + dependency: "direct main" + description: + name: flutter_markdown + sha256: "9921f9deda326f8a885e202b1e35237eadfc1345239a0f6f0f1ff287e047547f" + url: "https://pub.dev" + source: hosted + version: "0.7.1" flutter_native_splash: dependency: "direct dev" description: @@ -984,6 +992,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" + 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 3c675497..e31da6ee 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -66,7 +66,7 @@ dependencies: multi_value_listenable_builder: ^0.0.2 multi_listenable_builder: ^1.0.0 logging_flutter: ^3.0.0 - + flutter_markdown: ^0.7.1 # Dio HTTP dio: ^5.4.3+1 @@ -134,6 +134,8 @@ flutter: assets: - assets/ - assets/tailcostickers/tgs/ + - CHANGELOG.md + - PRIVACY.md sentry: upload_debug_symbols: true upload_source_maps: true