mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-12-23 10:11:52 +03:00
Remember last used app
This also disables Home functionality on Android.
This commit is contained in:
parent
908d2352dd
commit
6f3137752b
@ -23,7 +23,7 @@ import com.yubico.authenticator.device.Info
|
||||
import com.yubico.yubikit.android.transport.usb.UsbYubiKeyDevice
|
||||
|
||||
enum class OperationContext(val value: Int) {
|
||||
Oath(0), Yubikey(1), Invalid(-1);
|
||||
Home(0), Oath(1), Yubikey(2), Invalid(-1);
|
||||
|
||||
companion object {
|
||||
fun getByValue(value: Int) = values().firstOrNull { it.value == value } ?: Invalid
|
||||
|
@ -64,8 +64,8 @@ Future<Widget> initialize() async {
|
||||
oathStateProvider.overrideWithProvider(androidOathStateProvider.call),
|
||||
credentialListProvider
|
||||
.overrideWithProvider(androidCredentialListProvider.call),
|
||||
currentAppProvider.overrideWith(
|
||||
(ref) => AndroidSubPageNotifier(ref.watch(supportedAppsProvider))),
|
||||
currentAppProvider.overrideWith((ref) => AndroidSubPageNotifier(
|
||||
ref.watch(supportedAppsProvider), ref.watch(prefProvider))),
|
||||
managementStateProvider.overrideWithProvider(androidManagementState.call),
|
||||
currentDeviceProvider.overrideWith(
|
||||
() => AndroidCurrentDeviceNotifier(),
|
||||
@ -95,6 +95,7 @@ Future<Widget> initialize() async {
|
||||
..setFeature(features.fido, false)
|
||||
..setFeature(features.piv, false)
|
||||
..setFeature(features.otp, false)
|
||||
..setFeature(features.home, false)
|
||||
..setFeature(features.management, false);
|
||||
});
|
||||
|
||||
|
@ -91,7 +91,7 @@ final androidSupportedThemesProvider = StateProvider<List<ThemeMode>>((ref) {
|
||||
});
|
||||
|
||||
class AndroidSubPageNotifier extends CurrentAppNotifier {
|
||||
AndroidSubPageNotifier(super.supportedApps) {
|
||||
AndroidSubPageNotifier(super.supportedApps, super.prefs) {
|
||||
_handleSubPage(state);
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,8 @@ abstract class CurrentDeviceNotifier extends Notifier<DeviceNode?> {
|
||||
|
||||
final currentAppProvider =
|
||||
StateNotifierProvider<CurrentAppNotifier, Application>((ref) {
|
||||
final notifier = CurrentAppNotifier(ref.watch(supportedAppsProvider));
|
||||
final notifier = CurrentAppNotifier(
|
||||
ref.watch(supportedAppsProvider), ref.watch(prefProvider));
|
||||
ref.listen<AsyncValue<YubiKeyData>>(currentDeviceDataProvider, (_, data) {
|
||||
notifier._notifyDeviceChanged(data.whenOrNull(data: ((data) => data)));
|
||||
}, fireImmediately: true);
|
||||
@ -212,16 +213,29 @@ final currentAppProvider =
|
||||
|
||||
class CurrentAppNotifier extends StateNotifier<Application> {
|
||||
final List<Application> _supportedApps;
|
||||
static const String _key = 'APP_STATE_LAST_APP';
|
||||
final SharedPreferences _prefs;
|
||||
|
||||
CurrentAppNotifier(this._supportedApps) : super(_supportedApps.first);
|
||||
CurrentAppNotifier(this._supportedApps, this._prefs)
|
||||
: super(_fromName(_prefs.getString(_key), _supportedApps));
|
||||
|
||||
void setCurrentApp(Application app) {
|
||||
state = app;
|
||||
_prefs.setString(_key, app.name);
|
||||
}
|
||||
|
||||
void _notifyDeviceChanged(YubiKeyData? data) {
|
||||
if (data == null ||
|
||||
state.getAvailability(data) != Availability.unsupported) {
|
||||
if (data == null) {
|
||||
state = _supportedApps.first;
|
||||
return;
|
||||
}
|
||||
|
||||
String? lastAppName = _prefs.getString(_key);
|
||||
if (lastAppName != null && lastAppName != state.name) {
|
||||
// Try switching to saved app
|
||||
state = Application.values.firstWhere((app) => app.name == lastAppName);
|
||||
}
|
||||
if (state.getAvailability(data) != Availability.unsupported) {
|
||||
// Keep current app
|
||||
return;
|
||||
}
|
||||
@ -231,6 +245,10 @@ class CurrentAppNotifier extends StateNotifier<Application> {
|
||||
orElse: () => _supportedApps.first,
|
||||
);
|
||||
}
|
||||
|
||||
static Application _fromName(String? name, List<Application> supportedApps) =>
|
||||
supportedApps.firstWhere((element) => element.name == name,
|
||||
orElse: () => supportedApps.first);
|
||||
}
|
||||
|
||||
abstract class QrScanner {
|
||||
|
@ -19,6 +19,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
||||
import '../../core/state.dart';
|
||||
import '../models.dart';
|
||||
import '../state.dart';
|
||||
import 'device_picker.dart';
|
||||
@ -126,7 +127,9 @@ class NavigationContent extends ConsumerWidget {
|
||||
.where(
|
||||
(app) => app.getAvailability(data) != Availability.unsupported)
|
||||
.toList()
|
||||
: [Application.home];
|
||||
: !isAndroid // TODO: Remove check when Home is implemented on Android
|
||||
? [Application.home]
|
||||
: <Application>[];
|
||||
availableApps.remove(Application.management);
|
||||
final currentApp = ref.watch(currentAppProvider);
|
||||
|
||||
@ -138,9 +141,7 @@ class NavigationContent extends ConsumerWidget {
|
||||
duration: const Duration(milliseconds: 150),
|
||||
child: DevicePickerContent(extended: extended),
|
||||
),
|
||||
|
||||
const SizedBox(height: 32),
|
||||
|
||||
AnimatedSize(
|
||||
duration: const Duration(milliseconds: 150),
|
||||
child: Column(
|
||||
@ -153,7 +154,7 @@ class NavigationContent extends ConsumerWidget {
|
||||
Icon(app._icon, fill: app == currentApp ? 1.0 : 0.0),
|
||||
collapsed: !extended,
|
||||
selected: app == currentApp,
|
||||
onTap: currentApp == Application.home ||
|
||||
onTap: data == null && currentApp == Application.home ||
|
||||
data != null &&
|
||||
app.getAvailability(data) ==
|
||||
Availability.enabled
|
||||
@ -171,32 +172,6 @@ class NavigationContent extends ConsumerWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// // Non-YubiKey pages
|
||||
// NavigationItem(
|
||||
// leading: const Icon(Icons.settings_outlined),
|
||||
// key: settingDrawerIcon,
|
||||
// title: l10n.s_settings,
|
||||
// collapsed: !extended,
|
||||
// onTap: () {
|
||||
// if (shouldPop) {
|
||||
// Navigator.of(context).pop();
|
||||
// }
|
||||
// Actions.maybeInvoke(context, const SettingsIntent());
|
||||
// },
|
||||
// ),
|
||||
// NavigationItem(
|
||||
// leading: const Icon(Icons.help_outline),
|
||||
// key: helpDrawerIcon,
|
||||
// title: l10n.s_help_and_about,
|
||||
// collapsed: !extended,
|
||||
// onTap: () {
|
||||
// if (shouldPop) {
|
||||
// Navigator.of(context).pop();
|
||||
// }
|
||||
// Actions.maybeInvoke(context, const AboutIntent());
|
||||
// },
|
||||
// ),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -21,6 +21,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../app/views/message_page.dart';
|
||||
import '../../core/state.dart';
|
||||
import '../../management/models.dart';
|
||||
import 'key_actions.dart';
|
||||
|
||||
@ -59,13 +60,15 @@ class HomeMessagePage extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
|
||||
// TODO: Remove Android check when Home is implemented on Android
|
||||
return MessagePage(
|
||||
title: l10n.s_home,
|
||||
title: !isAndroid ? l10n.s_home : null,
|
||||
graphic: graphic,
|
||||
header: header,
|
||||
message: message,
|
||||
footnote: footnote,
|
||||
keyActionsBuilder: (context) => homeBuildActions(context, null, ref),
|
||||
keyActionsBuilder:
|
||||
!isAndroid ? (context) => homeBuildActions(context, null, ref) : null,
|
||||
actionButtonBuilder: actionButtonBuilder,
|
||||
actionsBuilder: actionsBuilder,
|
||||
fileDropOverlay: fileDropOverlay,
|
||||
|
Loading…
Reference in New Issue
Block a user