diff --git a/lib/models/authenticator/entity_result.dart b/lib/models/authenticator/entity_result.dart new file mode 100644 index 000000000..3e7e04c8b --- /dev/null +++ b/lib/models/authenticator/entity_result.dart @@ -0,0 +1,7 @@ +class EntityResult { + final int generatedID; + final String rawData; + final bool hasSynced; + + EntityResult(this.generatedID, this.rawData, this.hasSynced); +} diff --git a/lib/models/code.dart b/lib/models/code.dart index 4c05c11dc..444ef7846 100644 --- a/lib/models/code.dart +++ b/lib/models/code.dart @@ -13,6 +13,7 @@ class Code { final Algorithm algorithm; final Type type; final String rawData; + bool? hasSynced; Code( this.account, diff --git a/lib/services/authenticator_service.dart b/lib/services/authenticator_service.dart index e333a8cef..491d1c6ab 100644 --- a/lib/services/authenticator_service.dart +++ b/lib/services/authenticator_service.dart @@ -11,6 +11,7 @@ import 'package:ente_auth/events/signed_in_event.dart'; import 'package:ente_auth/gateway/authenticator.dart'; import 'package:ente_auth/models/authenticator/auth_entity.dart'; import 'package:ente_auth/models/authenticator/auth_key.dart'; +import 'package:ente_auth/models/authenticator/entity_result.dart'; import 'package:ente_auth/models/authenticator/local_auth_entity.dart'; import 'package:ente_auth/store/authenticator_db.dart'; import 'package:ente_auth/utils/crypto_util.dart'; @@ -44,11 +45,11 @@ class AuthenticatorService { }); } - Future> getAllIDtoStringMap() async { + Future> getEntities() async { final List result = await _db.getAll(); - final Map entries = {}; + final List entities = []; if (result.isEmpty) { - return entries; + return entities; } final key = await getOrCreateAuthDataKey(); for (LocalAuthEntity e in result) { @@ -58,12 +59,18 @@ class AuthenticatorService { key, Sodium.base642bin(e.header), ); - entries[e.generatedID] = utf8.decode(decryptedValue); + entities.add( + EntityResult( + e.generatedID, + utf8.decode(decryptedValue), + e.id != null, + ), + ); } catch (e, s) { _logger.severe(e, s); } } - return entries; + return entities; } Future addEntry(String plainText, bool shouldSync) async { diff --git a/lib/store/code_store.dart b/lib/store/code_store.dart index 5e8acb374..30faaab7e 100644 --- a/lib/store/code_store.dart +++ b/lib/store/code_store.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:ente_auth/core/event_bus.dart'; import 'package:ente_auth/events/codes_updated_event.dart'; +import 'package:ente_auth/models/authenticator/entity_result.dart'; import 'package:ente_auth/models/code.dart'; import 'package:ente_auth/services/authenticator_service.dart'; import 'package:logging/logging.dart'; @@ -19,13 +20,14 @@ class CodeStore { } Future> getAllCodes() async { - final Map rawCodesMap = - await _authenticatorService.getAllIDtoStringMap(); + final List entities = + await _authenticatorService.getEntities(); final List codes = []; - for (final entry in rawCodesMap.entries) { - final decodeJson = jsonDecode(entry.value); + for (final entity in entities) { + final decodeJson = jsonDecode(entity.rawData); final code = Code.fromRawData(decodeJson); - code.id = entry.key; + code.id = entity.generatedID; + code.hasSynced = entity.hasSynced; codes.add(code); } codes.sort((c1, c2) { diff --git a/lib/ui/code_widget.dart b/lib/ui/code_widget.dart index 614aad5e5..236ded0a5 100644 --- a/lib/ui/code_widget.dart +++ b/lib/ui/code_widget.dart @@ -103,26 +103,41 @@ class _CodeWidgetState extends State { ), Padding( padding: const EdgeInsets.only(left: 16, right: 16), - child: Column( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - Uri.decodeFull(widget.code.issuer).trim(), - style: Theme.of(context).textTheme.headline6, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + Uri.decodeFull(widget.code.issuer).trim(), + style: + Theme.of(context).textTheme.headline6, + ), + const SizedBox(height: 2), + Text( + Uri.decodeFull( + widget.code.account, + ).trim(), + style: Theme.of(context) + .textTheme + .caption + ?.copyWith( + fontSize: 12, + color: Colors.grey, + ), + ), + ], ), - const SizedBox(height: 2), - Text( - Uri.decodeFull( - widget.code.account, - ).trim(), - style: Theme.of(context) - .textTheme - .caption - ?.copyWith( - fontSize: 12, - color: Colors.grey, + widget.code.hasSynced != null && + widget.code.hasSynced! + ? Container() + : const Icon( + Icons.sync_disabled, + size: 20, + color: Colors.amber, ), - ), ], ), ),