diff --git a/lib/about_page.dart b/lib/about_page.dart index 40e3593d..26dd8c6f 100755 --- a/lib/about_page.dart +++ b/lib/about_page.dart @@ -1,19 +1,50 @@ -import 'package:flutter/material.dart'; +import 'dart:io'; -class AboutPage extends StatelessWidget { +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:logging/logging.dart'; +import 'package:yubico_authenticator/core/state.dart'; + +final log = Logger('about'); + +class AboutPage extends ConsumerWidget { const AboutPage({Key? key}) : super(key: key); @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { + final rpcState = ref.watch(rpcStateProvider); return Scaffold( appBar: AppBar( title: const Text('About Yubico Authenticator'), ), body: Center( child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: const [ - Text('About placeholder'), + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('ykman version: ${rpcState.version}'), + Text('Dart version: ${Platform.version}'), + const SizedBox(height: 8.0), + Text('Log level: ${ref.watch(logLevelProvider)}'), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + TextButton( + onPressed: () { + ref.read(logLevelProvider.notifier).setLevel(Level.INFO); + log.info('Log level changed to INFO'); + }, + child: const Text('INFO'), + ), + TextButton( + onPressed: () { + ref.read(logLevelProvider.notifier).setLevel(Level.CONFIG); + log.config('Log level changed to CONFIG'); + }, + child: const Text('DEBUG'), + ), + ], + ), ], ), ), diff --git a/lib/core/models.dart b/lib/core/models.dart index ed28c86e..5d168472 100644 --- a/lib/core/models.dart +++ b/lib/core/models.dart @@ -30,3 +30,8 @@ class RpcResponse with _$RpcResponse { factory RpcResponse.fromJson(Map json) => _$RpcResponseFromJson(json); } + +@freezed +class RpcState with _$RpcState { + const factory RpcState(String version) = _RpcState; +} diff --git a/lib/core/models.freezed.dart b/lib/core/models.freezed.dart index 45bbbf37..77699340 100755 --- a/lib/core/models.freezed.dart +++ b/lib/core/models.freezed.dart @@ -796,3 +796,125 @@ abstract class RpcError implements RpcResponse { $RpcErrorCopyWith get copyWith => throw _privateConstructorUsedError; } + +/// @nodoc +class _$RpcStateTearOff { + const _$RpcStateTearOff(); + + _RpcState call(String version) { + return _RpcState( + version, + ); + } +} + +/// @nodoc +const $RpcState = _$RpcStateTearOff(); + +/// @nodoc +mixin _$RpcState { + String get version => throw _privateConstructorUsedError; + + @JsonKey(ignore: true) + $RpcStateCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $RpcStateCopyWith<$Res> { + factory $RpcStateCopyWith(RpcState value, $Res Function(RpcState) then) = + _$RpcStateCopyWithImpl<$Res>; + $Res call({String version}); +} + +/// @nodoc +class _$RpcStateCopyWithImpl<$Res> implements $RpcStateCopyWith<$Res> { + _$RpcStateCopyWithImpl(this._value, this._then); + + final RpcState _value; + // ignore: unused_field + final $Res Function(RpcState) _then; + + @override + $Res call({ + Object? version = freezed, + }) { + return _then(_value.copyWith( + version: version == freezed + ? _value.version + : version // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc +abstract class _$RpcStateCopyWith<$Res> implements $RpcStateCopyWith<$Res> { + factory _$RpcStateCopyWith(_RpcState value, $Res Function(_RpcState) then) = + __$RpcStateCopyWithImpl<$Res>; + @override + $Res call({String version}); +} + +/// @nodoc +class __$RpcStateCopyWithImpl<$Res> extends _$RpcStateCopyWithImpl<$Res> + implements _$RpcStateCopyWith<$Res> { + __$RpcStateCopyWithImpl(_RpcState _value, $Res Function(_RpcState) _then) + : super(_value, (v) => _then(v as _RpcState)); + + @override + _RpcState get _value => super._value as _RpcState; + + @override + $Res call({ + Object? version = freezed, + }) { + return _then(_RpcState( + version == freezed + ? _value.version + : version // ignore: cast_nullable_to_non_nullable + as String, + )); + } +} + +/// @nodoc + +class _$_RpcState implements _RpcState { + const _$_RpcState(this.version); + + @override + final String version; + + @override + String toString() { + return 'RpcState(version: $version)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _RpcState && + (identical(other.version, version) || other.version == version)); + } + + @override + int get hashCode => Object.hash(runtimeType, version); + + @JsonKey(ignore: true) + @override + _$RpcStateCopyWith<_RpcState> get copyWith => + __$RpcStateCopyWithImpl<_RpcState>(this, _$identity); +} + +abstract class _RpcState implements RpcState { + const factory _RpcState(String version) = _$_RpcState; + + @override + String get version; + @override + @JsonKey(ignore: true) + _$RpcStateCopyWith<_RpcState> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/core/state.dart b/lib/core/state.dart index 5ed61ba4..bf749b32 100644 --- a/lib/core/state.dart +++ b/lib/core/state.dart @@ -15,6 +15,22 @@ final rpcProvider = Provider((ref) { throw UnimplementedError(); }); +final rpcStateProvider = StateNotifierProvider( + (ref) => RpcStateNotifier(ref.watch(rpcProvider))); + +class RpcStateNotifier extends StateNotifier { + final RpcSession rpc; + RpcStateNotifier(this.rpc) : super(const RpcState('unknown')) { + _init(); + } + + _init() async { + final response = await rpc.command('get', []); + if (mounted) { + state = state.copyWith(version: response['data']['version']); + } + } +} final logLevelProvider = StateNotifierProvider( (ref) => LogLevelNotifier(ref.watch(rpcProvider), Logger.root.level));