2021-11-19 17:05:57 +03:00
|
|
|
import 'dart:async';
|
|
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
2021-11-22 11:49:52 +03:00
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
2021-11-19 17:05:57 +03:00
|
|
|
|
2022-02-08 15:44:35 +03:00
|
|
|
import '../app/models.dart';
|
2021-12-02 13:44:17 +03:00
|
|
|
import '../app/state.dart';
|
2021-11-19 17:05:57 +03:00
|
|
|
import '../core/state.dart';
|
|
|
|
import 'models.dart';
|
|
|
|
|
|
|
|
final oathStateProvider = StateNotifierProvider.autoDispose
|
2022-02-08 15:44:35 +03:00
|
|
|
.family<OathStateNotifier, OathState?, DevicePath>(
|
2022-01-27 14:34:29 +03:00
|
|
|
(ref, devicePath) => throw UnimplementedError(),
|
2021-11-19 17:05:57 +03:00
|
|
|
);
|
|
|
|
|
2022-01-27 14:34:29 +03:00
|
|
|
abstract class OathStateNotifier extends StateNotifier<OathState?> {
|
|
|
|
OathStateNotifier() : super(null);
|
2021-12-08 13:20:04 +03:00
|
|
|
|
2022-01-27 14:34:29 +03:00
|
|
|
Future<void> reset();
|
2022-02-08 14:25:36 +03:00
|
|
|
Future<bool> unlock(String password, {bool remember = false});
|
2022-01-27 14:34:29 +03:00
|
|
|
Future<bool> setPassword(String? current, String password);
|
|
|
|
Future<bool> unsetPassword(String current);
|
2022-02-08 14:25:36 +03:00
|
|
|
Future<void> forgetPassword();
|
2021-11-19 17:05:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
final credentialListProvider = StateNotifierProvider.autoDispose
|
2022-02-08 15:44:35 +03:00
|
|
|
.family<OathCredentialListNotifier, List<OathPair>?, DevicePath>(
|
2022-01-27 14:34:29 +03:00
|
|
|
(ref, arg) => throw UnimplementedError(),
|
2021-11-19 17:05:57 +03:00
|
|
|
);
|
|
|
|
|
2022-01-27 14:34:29 +03:00
|
|
|
abstract class OathCredentialListNotifier
|
|
|
|
extends StateNotifier<List<OathPair>?> {
|
|
|
|
OathCredentialListNotifier() : super(null);
|
2021-11-19 17:05:57 +03:00
|
|
|
|
|
|
|
@override
|
|
|
|
@protected
|
|
|
|
set state(List<OathPair>? value) {
|
|
|
|
super.state = value != null ? List.unmodifiable(value) : null;
|
|
|
|
}
|
|
|
|
|
2022-01-27 14:34:29 +03:00
|
|
|
Future<OathCode> calculate(OathCredential credential);
|
|
|
|
Future<OathCredential> addAccount(Uri otpauth, {bool requireTouch = false});
|
|
|
|
Future<OathCredential> renameAccount(
|
|
|
|
OathCredential credential, String? issuer, String name);
|
|
|
|
Future<void> deleteAccount(OathCredential credential);
|
2021-11-19 17:05:57 +03:00
|
|
|
}
|
|
|
|
|
2021-12-03 17:15:00 +03:00
|
|
|
final favoritesProvider =
|
|
|
|
StateNotifierProvider<FavoritesNotifier, List<String>>(
|
|
|
|
(ref) => FavoritesNotifier(ref.watch(prefProvider)));
|
2021-11-19 17:05:57 +03:00
|
|
|
|
2021-12-03 17:15:00 +03:00
|
|
|
class FavoritesNotifier extends StateNotifier<List<String>> {
|
|
|
|
static const String _key = 'OATH_STATE_FAVORITES';
|
|
|
|
final SharedPreferences _prefs;
|
|
|
|
FavoritesNotifier(this._prefs) : super(_prefs.getStringList(_key) ?? []);
|
2021-11-22 11:49:52 +03:00
|
|
|
|
2021-12-03 17:15:00 +03:00
|
|
|
toggleFavorite(String credentialId) {
|
|
|
|
if (state.contains(credentialId)) {
|
|
|
|
state = state.toList()..remove(credentialId);
|
|
|
|
} else {
|
|
|
|
state = [credentialId, ...state];
|
2021-11-22 11:49:52 +03:00
|
|
|
}
|
2021-12-03 17:15:00 +03:00
|
|
|
_prefs.setStringList(_key, state);
|
2021-11-19 17:05:57 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
final filteredCredentialsProvider = StateNotifierProvider.autoDispose
|
|
|
|
.family<FilteredCredentialsNotifier, List<OathPair>, List<OathPair>>(
|
|
|
|
(ref, full) {
|
2021-12-03 17:15:00 +03:00
|
|
|
return FilteredCredentialsNotifier(full, ref.watch(searchProvider));
|
2021-11-19 17:05:57 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
class FilteredCredentialsNotifier extends StateNotifier<List<OathPair>> {
|
|
|
|
final String query;
|
|
|
|
FilteredCredentialsNotifier(
|
|
|
|
List<OathPair> full,
|
|
|
|
this.query,
|
2021-12-02 13:44:17 +03:00
|
|
|
) : super(
|
|
|
|
full
|
|
|
|
.where((pair) =>
|
|
|
|
"${pair.credential.issuer ?? ''}:${pair.credential.name}"
|
|
|
|
.toLowerCase()
|
|
|
|
.contains(query.toLowerCase()))
|
|
|
|
.toList()
|
|
|
|
..sort((a, b) {
|
2021-12-03 17:15:00 +03:00
|
|
|
String searchKey(OathCredential c) => (c.issuer ?? '') + c.name;
|
2021-12-02 13:44:17 +03:00
|
|
|
return searchKey(a.credential).compareTo(searchKey(b.credential));
|
|
|
|
}),
|
|
|
|
);
|
2021-11-19 17:05:57 +03:00
|
|
|
}
|