From e7bab3f7912d227652d69d4b3e1da8e8352f62c8 Mon Sep 17 00:00:00 2001 From: Martin Chaine Date: Tue, 8 Aug 2023 23:32:26 +0200 Subject: [PATCH] A few enhancements to the Session Details screen (#51) * obfuscate secrets and tokens but allow to copy them with a tap * add a missing const * add an icon to the log out button * fix small screen support --- lib/pages/session_details.dart | 73 ++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/lib/pages/session_details.dart b/lib/pages/session_details.dart index 8e08a836..136ecbaf 100644 --- a/lib/pages/session_details.dart +++ b/lib/pages/session_details.dart @@ -1,11 +1,32 @@ import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:frigoligo/wallabag/wallabag.dart'; import 'package:provider/provider.dart'; import '../models/db.dart'; import '../providers/settings.dart'; +Widget _copyText(BuildContext context, String text, [bool obfuscate = false]) { + var content = text; + if (obfuscate) { + const showLen = 8; + final prefix = text.substring(0, showLen); + final suffix = text.substring(text.length - showLen); + content = '$prefix...$suffix'; + } + return InkWell( + onTap: () async { + await Clipboard.setData(ClipboardData(text: content)); + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('Copied to your clipboard!'))); + } + }, + child: Text(content, style: const TextStyle(fontFamily: 'monospace')), + ); +} + class SessionDetailsPage extends StatelessWidget { const SessionDetailsPage({super.key}); @@ -13,33 +34,60 @@ class SessionDetailsPage extends StatelessWidget { Widget build(BuildContext context) { final settings = context.read(); final wallabag = WallabagInstance.get(); + + String sinceLastSync = 'never'; + final lastSync = settings[Sk.lastRefresh]; + if (lastSync > 0) { + final now = DateTime.now().millisecondsSinceEpoch / 1000; + final elapsed = now - lastSync; + if (elapsed < 1000) { + sinceLastSync = '${elapsed.toStringAsFixed(0)} seconds ago'; + } else { + final asMinutes = elapsed / 60; + sinceLastSync = '${asMinutes.toStringAsFixed(0)} minutes ago'; + } + } + final accessToken = wallabag.tokenData?.accessToken; + final accessTokenValidity = wallabag.tokenData != null + ? wallabag.tokenData!.expiresIn.toIso8601String() + : 'invalid'; + return Scaffold( appBar: AppBar( title: const Text('Session details'), ), - body: Column( + body: ListView( children: [ ListTile( title: const Text('Server'), - subtitle: Text(wallabag.connectionData.server), + subtitle: + _copyText(context, 'https://${wallabag.connectionData.server}'), ), ListTile( title: const Text('Client ID'), - subtitle: Text(wallabag.connectionData.clientId), + subtitle: + _copyText(context, wallabag.connectionData.clientId, true), ), ListTile( title: const Text('Client secret'), - subtitle: Text(wallabag.connectionData.clientSecret), + subtitle: + _copyText(context, wallabag.connectionData.clientSecret, true), + ), + ListTile( + title: const Text('Access token'), + subtitle: + _copyText(context, accessToken.toString(), accessToken != null), + ), + ListTile( + title: const Text('Token valid until'), + subtitle: Text(accessTokenValidity), ), ListTile( - title: const Text('Token data'), - subtitle: Text( - wallabag.tokenData != null - ? wallabag.tokenData!.toJson().toString() - : 'none', - ), + title: const Text('Last server sync'), + subtitle: Text(sinceLastSync), ), - ElevatedButton( + const SizedBox(height: 8.0), + ElevatedButton.icon( onPressed: () async { final result = await showOkCancelAlertDialog( context: context, @@ -58,7 +106,8 @@ class SessionDetailsPage extends StatelessWidget { .pushNamedAndRemoveUntil('/', (r) => false); } }, - child: const Text('Log out session'), + icon: const Icon(Icons.logout), + label: const Text('Log out session'), ), ], ),