From 7f82d9ddbc20aea3af3d9f8fd4016ee37423e6f8 Mon Sep 17 00:00:00 2001 From: Dain Nilsson Date: Thu, 2 Jun 2022 14:53:29 +0200 Subject: [PATCH] Restyle about page. --- assets/graphics/app-icon.png | Bin 0 -> 6063 bytes lib/about_page.dart | 129 ++++++++++++++++++++++++++++----- lib/app/views/main_drawer.dart | 2 +- 3 files changed, 111 insertions(+), 20 deletions(-) create mode 100644 assets/graphics/app-icon.png diff --git a/assets/graphics/app-icon.png b/assets/graphics/app-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..869a2c837e9dceb0223b83207528c880e3d9a110 GIT binary patch literal 6063 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%0DuL_RI=yg>2M^Ej87Skp zB)q_fbY;rPk{krhqG4J_{h^8wn)JxXpA@H32%s`^>{84EjM)Q7#BvIvoce&v{i3fD z*b->0re9$JgBYEpynV$01y~KdB{mfMA<(WRt|a%)ak0xtPY3-q&$au*4t1(3hKB}4W*q{ zK#x&7xrOwH#>bV{SZc0~vlUYsB&moPpQJDn0yzDF55g3glEVsY{WU3PGP=ab(F$O} zss1B!6bG#r<@NCktu{m&G|c7?L`=Y74lZaL0X8$uW`;;>z-&D}<&)5UE8HTfQo{Y!dsEk>&qwM zv3+tDL-^7Js(@IxwLcsCH9xXB0ip|nF4P8M6AVvTEuS~=O9ZriZJxc__b!9Pm#dGS zDXyM)|AvcJG|G6=aTvWV+j4EKcbg;ldUn#MB}mmuov-^Df{y$F$$u%xJXJW8h+I(< zwmvfu^&HF}dsDdgykPPY74F?HkD{wds)D@tH^kVDy9Qt*g$=uPB*xPm0=`5t#yCeXM z)LsRM7HmikWDjT)WP2wPVvJU~prWFPPmdi5w_H;5_=ORgN-q-i1)RDW$=AdfQSu8% z@9z!RM87HTS_y zx29cI+32g~C^9s|ILW9TVad%XY(G~538d`63B@S|V=WnUj$f_{#&5A(*xfznUK{OJ zJrkuf()o)usOpHOJ<_(; zEbTE!0XrIqgow@`$1gf3$n9mgnG^vU*C8moK77oAS^;DAO>RsWJ4dPJS zEIPRt@5eR;0N-(l**kKs`5exAo$A|LlBesM=!X+Ce$uG)Rep`kg=Rbk-V(gJFJ}4( zEQ@|Tlyn$1PrL2TuYPmCK8hn1gn&+)Io&Lb0#|jLsT+HC*gvUdU>wl<>a;|D6B>6K zjeS?uvUhvw+>iAY12&qclmOc_eh3VN%CUiC==xMjYqPQ%)g50pbmeP#Als`cx)zol zYTi1Wq<=>hD3?WSPe?7klKY&{tqR?MXC}fUh|_A;gSHJi!XxV-rhpC^r~(vSkqI7A zz$oxYarXC=ZGHVwPlw~9K;xuVWc1ZO5Sa#Wyz4>d|Mdj;`Lcy9fbG=1A%PVkdz*|~ zh~azwY?02v7Xj^z9yu_k0SC?44j%`IUst1;%lxo7C;Y?oO~XG@rzGJ)b=ztZ6g26P zFA&FXPqkUq)yN+HSmlIRSRsNX{ftcbA3ZV*!t~=xCfClX0$B++BqpiIX}=4t@85<< z=hBHkuarYq?Mq9YPJe+|juDrgQ&9>)1?~Ogm38af``4kDr0@Ua2d0y<5ES%I=0gXi z+s6g@i8=aIgdD{M9PYbD3AdXN9gN2-=cGOvnwkl?snIW=?co? zsRVfj_T>0j*&Cr`jt8;-Wa9H2BE%$CS;~iGqYgnwJ1~{K;l-1aYTrMhpvS^bIjH=+ z#24*VOccZFLTC0K$zVLt82>*U<~>|KHu|&I1{*-r9zSgNKePO!l#*nLxS{|50DtIU AkN^Mx literal 0 HcmV?d00001 diff --git a/lib/about_page.dart b/lib/about_page.dart index dacfa209..a3342d66 100755 --- a/lib/about_page.dart +++ b/lib/about_page.dart @@ -1,12 +1,12 @@ import 'dart:convert'; -import 'dart:io'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:logging/logging.dart'; -import 'package:yubico_authenticator/app/state.dart'; +import 'app/state.dart'; import 'version.dart'; import 'app/logging.dart'; import 'app/message.dart'; @@ -22,23 +22,69 @@ class AboutPage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return ResponsiveDialog( - title: const Text('Yubico Authenticator'), + title: const Text('About'), child: Column( mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + //crossAxisAlignment: CrossAxisAlignment.start, children: [ + Image.asset('assets/graphics/app-icon.png', scale: 1 / 0.75), + Padding( + padding: const EdgeInsets.symmetric(vertical: 24.0), + child: Text( + 'Yubico Authenticator', + style: Theme.of(context).textTheme.titleMedium, + ), + ), const Text('Yubico Authenticator: $version'), - if (isDesktop) - Text('ykman version: ${ref.watch(rpcStateProvider).version}'), - Text('Dart version: ${Platform.version}'), - const SizedBox(height: 8.0), - const Divider(), + if (isDesktop) Text('ykman: ${ref.watch(rpcStateProvider).version}'), + //Text('Dart version: ${Platform.version}'), + const Text('Copyright © 2022 Yubico'), + const Text('All rights reserved'), + const Text(''), + Row( + mainAxisSize: MainAxisSize.min, + children: const [ + UrlLink(text: 'Terms of use', url: 'https://example.com'), + SizedBox(width: 8.0), + UrlLink(text: 'Privacy policy', url: 'https://example.com'), + ], + ), + const Padding( + padding: EdgeInsets.only(top: 24.0, bottom: 8.0), + child: Divider(), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Text( + 'Help and feedback', + style: Theme.of(context).textTheme.titleMedium, + ), + ), + Row( + mainAxisSize: MainAxisSize.min, + children: const [ + UrlLink(text: 'Send us feedback', url: 'https://example.com'), + SizedBox(width: 8.0), + UrlLink(text: 'I need help', url: 'https://example.com'), + ], + ), + const Padding( + padding: EdgeInsets.only(top: 24.0, bottom: 8.0), + child: Divider(), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Text( + 'Troubleshooting', + style: Theme.of(context).textTheme.titleMedium, + ), + ), const LoggingPanel(), if (isDesktop) ...[ - const Divider(), + const SizedBox(height: 12.0), OutlinedButton.icon( - icon: const Icon(Icons.healing), - label: const Text('Run diagnostics...'), + icon: const Icon(Icons.bug_report_outlined), + label: const Text('Run diagnostics'), onPressed: () async { _log.info('Running diagnostics...'); final response = @@ -66,13 +112,16 @@ class LoggingPanel extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - return Row( + return Column( + //crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('Log level:'), - const SizedBox(width: 8.0), - DropdownButton( + const SizedBox(height: 12.0), + DropdownButtonFormField( + decoration: const InputDecoration( + labelText: 'Log level', + border: OutlineInputBorder(), + ), value: ref.watch(logLevelProvider), - isDense: true, items: Levels.LEVELS .map((e) => DropdownMenuItem( value: e, @@ -85,10 +134,10 @@ class LoggingPanel extends ConsumerWidget { showMessage(context, 'Log level set to $level'); }, ), - const SizedBox(width: 8.0), + const SizedBox(height: 12.0), OutlinedButton.icon( icon: const Icon(Icons.copy), - label: const Text('Copy log'), + label: const Text('Copy log to clipboard'), onPressed: () async { _log.info('Copying log to clipboard ($version)...'); final logs = await ref.read(logLevelProvider.notifier).getLogs(); @@ -104,3 +153,45 @@ class LoggingPanel extends ConsumerWidget { ); } } + +class UrlLink extends StatefulWidget { + final String text; + final String url; + + const UrlLink({super.key, required this.text, required this.url}); + + @override + State createState() => _UrlLinkState(); +} + +class _UrlLinkState extends State { + late TapGestureRecognizer _tapRecognizer; + + @override + void initState() { + super.initState(); + _tapRecognizer = TapGestureRecognizer(); + _tapRecognizer.onTap = () { + print("TODO: Go to ${widget.url}"); + }; + } + + @override + void dispose() { + _tapRecognizer.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return RichText( + text: TextSpan( + text: widget.text, + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + decoration: TextDecoration.underline, + ), + recognizer: _tapRecognizer, + )); + } +} diff --git a/lib/app/views/main_drawer.dart b/lib/app/views/main_drawer.dart index 265e58b0..c3d9f5ef 100755 --- a/lib/app/views/main_drawer.dart +++ b/lib/app/views/main_drawer.dart @@ -97,7 +97,7 @@ class MainPageDrawer extends ConsumerWidget { }, ), DrawerItem( - titleText: 'Help and feedback', + titleText: 'Help and about', icon: const Icon(Icons.help), onTap: () { final nav = Navigator.of(context);