diff --git a/lib/dashboard/drawer/ssi/manage_did/manage_did.dart b/lib/dashboard/drawer/ssi/manage_did/manage_did.dart index f94a8ccd7..cc711a3f9 100644 --- a/lib/dashboard/drawer/ssi/manage_did/manage_did.dart +++ b/lib/dashboard/drawer/ssi/manage_did/manage_did.dart @@ -1,4 +1,5 @@ export 'view/did/did_private_key_page.dart'; export 'view/did/manage_did_page.dart'; export 'view/did_polygon_id/manage_did_polygon_id_page.dart'; +export 'view/jwk_thumbprint_p256_key/jwk_thumbprint_p256_key_page.dart'; export 'widgets/widgets.dart'; diff --git a/lib/dashboard/drawer/ssi/manage_did/view/did_menu.dart b/lib/dashboard/drawer/ssi/manage_did/view/did_menu.dart index 4e32543da..2739c9f75 100644 --- a/lib/dashboard/drawer/ssi/manage_did/view/did_menu.dart +++ b/lib/dashboard/drawer/ssi/manage_did/view/did_menu.dart @@ -97,6 +97,14 @@ class DidView extends StatelessWidget { } }, ), + DrawerItem( + title: l10n.jwkThumbprintP256Key, + onTap: () { + Navigator.of(context).push( + JWKThumbprintP256KeyPage.route(), + ); + }, + ), ], ), ), diff --git a/lib/dashboard/drawer/ssi/manage_did/view/jwk_thumbprint_p256_key/jwk_thumbprint_p256_key_page.dart b/lib/dashboard/drawer/ssi/manage_did/view/jwk_thumbprint_p256_key/jwk_thumbprint_p256_key_page.dart new file mode 100644 index 000000000..ff1440130 --- /dev/null +++ b/lib/dashboard/drawer/ssi/manage_did/view/jwk_thumbprint_p256_key/jwk_thumbprint_p256_key_page.dart @@ -0,0 +1,140 @@ +import 'package:altme/app/app.dart'; +import 'package:altme/dashboard/dashboard.dart'; +import 'package:altme/l10n/l10n.dart'; +import 'package:altme/theme/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class JWKThumbprintP256KeyPage extends StatefulWidget { + const JWKThumbprintP256KeyPage({ + super.key, + }); + + static Route route() { + return MaterialPageRoute( + builder: (_) => const JWKThumbprintP256KeyPage(), + settings: const RouteSettings(name: '/JWKThumbprintP256KeyPage'), + ); + } + + @override + State createState() => + _JWKThumbprintP256KeyPageState(); +} + +class _JWKThumbprintP256KeyPageState extends State + with SingleTickerProviderStateMixin { + late Animation animation; + late AnimationController animationController; + + Future getKey() async { + final privateKey = await getP256KeyToGetAndPresentVC( + context.read().secureStorageProvider, + ); + return privateKey; + } + + @override + void initState() { + super.initState(); + animationController = AnimationController( + vsync: this, + duration: const Duration(seconds: 20), + ); + + final Tween rotationTween = Tween(begin: 20, end: 0); + + animation = rotationTween.animate(animationController) + ..addStatusListener((status) { + if (status == AnimationStatus.completed) { + Navigator.pop(context); + } + }); + animationController.forward(); + } + + @override + void dispose() { + animationController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final l10n = context.l10n; + return BasePage( + scrollView: false, + title: l10n.jwkThumbprintP256Key, + titleAlignment: Alignment.topCenter, + titleLeading: const BackLeadingButton(), + secureScreen: true, + body: BackgroundCard( + width: double.infinity, + height: double.infinity, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + l10n.jwkThumbprintP256Key, + style: Theme.of(context).textTheme.title, + ), + const SizedBox( + height: Sizes.spaceNormal, + ), + FutureBuilder( + future: getKey(), + builder: (context, snapshot) { + switch (snapshot.connectionState) { + case ConnectionState.done: + return Column( + children: [ + Text( + snapshot.data!, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + ), + const SizedBox(height: Sizes.spaceXLarge), + CopyButton( + onTap: () async { + await Clipboard.setData( + ClipboardData(text: snapshot.data!), + ); + AlertMessage.showStateMessage( + context: context, + stateMessage: StateMessage.success( + stringMessage: l10n.copiedToClipboard, + ), + ); + }, + ), + ], + ); + case ConnectionState.waiting: + case ConnectionState.none: + case ConnectionState.active: + return const Text(''); + } + }, + ), + Expanded( + child: Center( + child: AnimatedBuilder( + animation: animation, + builder: (BuildContext context, Widget? child) { + return Text( + timeFormatter(timeInSecond: animation.value.toInt()), + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.displayMedium, + ); + }, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/l10n/arb/app_en.arb b/lib/l10n/arb/app_en.arb index 2363d1f27..978479f64 100644 --- a/lib/l10n/arb/app_en.arb +++ b/lib/l10n/arb/app_en.arb @@ -1056,5 +1056,6 @@ "statusListIndex": "Status list index", "theWalletIsSuspended": "The wallet is suspended.", "clientTypeTitle": "Wallet Client_id Scheme", - "confidentialClient": "Confidential Client" + "confidentialClient": "Confidential Client", + "jwkThumbprintP256Key": "JWK Thumbprint P-256 Key" } diff --git a/lib/l10n/untranslated.json b/lib/l10n/untranslated.json index d451092c5..59c248ba9 100644 --- a/lib/l10n/untranslated.json +++ b/lib/l10n/untranslated.json @@ -25,7 +25,8 @@ "statusListIndex", "theWalletIsSuspended", "clientTypeTitle", - "confidentialClient" + "confidentialClient", + "jwkThumbprintP256Key" ], "es": [ @@ -54,7 +55,8 @@ "statusListIndex", "theWalletIsSuspended", "clientTypeTitle", - "confidentialClient" + "confidentialClient", + "jwkThumbprintP256Key" ], "fr": [ @@ -73,6 +75,7 @@ "statusListIndex", "theWalletIsSuspended", "clientTypeTitle", - "confidentialClient" + "confidentialClient", + "jwkThumbprintP256Key" ] }