Skip to content

Commit

Permalink
feat: Display image of card for SD-JWT #2503
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Mar 15, 2024
1 parent 2417635 commit f41f7aa
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 38 deletions.
65 changes: 65 additions & 0 deletions lib/app/shared/helper_functions/helper_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:io';
import 'package:altme/app/app.dart';
import 'package:altme/dashboard/dashboard.dart';
import 'package:altme/oidc4vc/oidc4vc.dart';
import 'package:altme/selective_disclosure/selective_disclosure.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:convert/convert.dart';

Expand Down Expand Up @@ -1591,3 +1592,67 @@ Future<(String?, String?, String?, String?)> getClientDetails({
}
return (display, credentialSupported);
}

String? getClaimsData(
Map<String, dynamic> uncryptedDatas,
CredentialModel credentialModel,
String key,
) {
String? data;

final JsonPath dataPath = JsonPath(
// ignore: prefer_interpolation_to_compose_strings
r'$..' + key,
);

try {
final uncryptedDataPath = dataPath.read(uncryptedDatas).first;
data = uncryptedDataPath.value.toString();
} catch (e) {
try {
final credentialModelPath = dataPath.read(credentialModel.data).first;
data = credentialModelPath.value.toString();
} catch (e) {
data = null;
}
}

return data;
}

String? getPicture({
required CredentialModel credentialModel,
}) {
if (credentialModel.format.toString() != VCFormatType.vcSdJWT.value) {
return null;
}

final credentialSupported = credentialModel.credentialSupported;
if (credentialSupported == null) return null;

final claims = credentialSupported['claims'];
if (claims is! Map<String, dynamic>) return null;

final picture = claims['picture'];
if (picture == null) return null;
if (picture is! Map<String, dynamic>) return null;

if (picture.containsKey('mandatory')) {
final mandatory = picture['mandatory'];
if (mandatory is! bool) return null;
}

final valueType = picture['value_type'];
if (valueType == null) return null;

if (valueType == 'image/jpeg') {
final selectiveDisclosure = SelectiveDisclosure(credentialModel);

final data =
getClaimsData(selectiveDisclosure.values, credentialModel, 'picture');

return data;
} else {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,17 @@ class _CredentialsDetailsViewState extends State<CredentialsDetailsView> {
final isSecure = profileData.profileSetting.selfSovereignIdentityOptions
.customOidc4vcProfile.securityLevel;

final credentialSupported = widget.credentialModel.credentialSupported;

final claims = credentialSupported?['claims'];
final containClaims = claims != null;

String? credentialImage;

if (containClaims) {
credentialImage = getPicture(credentialModel: widget.credentialModel);
}

return BlocConsumer<CredentialDetailsCubit, CredentialDetailsState>(
listener: (context, state) {
if (state.status == AppStatus.loading) {
Expand Down Expand Up @@ -188,11 +199,30 @@ class _CredentialsDetailsViewState extends State<CredentialsDetailsView> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
CredentialDisplay(
credentialModel: widget.credentialModel,
credDisplayType: CredDisplayType.Detail,
profileSetting: profileSetting,
),
if (credentialImage != null)
AspectRatio(
aspectRatio: Sizes.credentialAspectRatio,
child: ClipRRect(
borderRadius: BorderRadius.circular(
Sizes.credentialBorderRadius,
),
child: CachedImageFromNetwork(
credentialImage,
fit: BoxFit.contain,
width: double.infinity,
bgColor: Colors.transparent,
height: double.infinity,
errorMessage: '',
showLoading: false,
),
),
)
else
CredentialDisplay(
credentialModel: widget.credentialModel,
credDisplayType: CredDisplayType.Detail,
profileSetting: profileSetting,
),
const SizedBox(height: 20),
Column(
children: [
Expand Down Expand Up @@ -304,10 +334,7 @@ class _CredentialsDetailsViewState extends State<CredentialsDetailsView> {

/// selective disclouse data - _sd
/// and normal data too
if (widget.credentialModel.credentialSupported !=
null &&
widget.credentialModel.credentialSupported!
.containsKey('claims')) ...[
if (containClaims) ...[
DisplaySelectiveDisclosure(
credentialModel: widget.credentialModel,
claims: null,
Expand Down
31 changes: 2 additions & 29 deletions lib/selective_disclosure/widget/display_selective_disclosure.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:altme/selective_disclosure/selective_disclosure.dart';
import 'package:altme/theme/theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:json_path/json_path.dart';

class DisplaySelectiveDisclosure extends StatelessWidget {
const DisplaySelectiveDisclosure({
Expand Down Expand Up @@ -45,7 +44,8 @@ class DisplaySelectiveDisclosure extends StatelessWidget {

if (display == null) return Container();
title = display['name'].toString();
data = getData(selectiveDisclosure.values, credentialModel, key);
data =
getClaimsData(selectiveDisclosure.values, credentialModel, key);

if (data == null) return Container();

Expand Down Expand Up @@ -113,31 +113,4 @@ class DisplaySelectiveDisclosure extends StatelessWidget {
return null;
}
}

String? getData(
Map<String, dynamic> uncryptedDatas,
CredentialModel credentialModel,
String key,
) {
String? data;

final JsonPath dataPath = JsonPath(
// ignore: prefer_interpolation_to_compose_strings
r'$..' + key,
);

try {
final uncryptedDataPath = dataPath.read(uncryptedDatas).first;
data = uncryptedDataPath.value.toString();
} catch (e) {
try {
final credentialModelPath = dataPath.read(credentialModel.data).first;
data = credentialModelPath.value.toString();
} catch (e) {
data = null;
}
}

return data;
}
}

0 comments on commit f41f7aa

Please sign in to comment.