Skip to content

Commit

Permalink
Merge pull request #303 from privacybydesign/ui-improvements
Browse files Browse the repository at this point in the history
UI improvements
  • Loading branch information
w-ensink authored Nov 29, 2024
2 parents 28734b1 + 8dc1a66 commit 40e5dd3
Show file tree
Hide file tree
Showing 24 changed files with 429 additions and 332 deletions.
42 changes: 24 additions & 18 deletions lib/routing.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@ class Routing {
return settings.name == EnrollmentScreen.routeName || settings.name == ChangePinScreen.routeName;
}

static _canPop(RouteSettings settings, BuildContext context) {
// If the current route has a subnavigator and is on the root, defer to that component's `WillPopScope`
if (_isSubnavigatorRoute(settings) && _isRootRoute(settings)) {
return true;
}

// Otherwise if it is a root route, background the app on backpress
if (_isRootRoute(settings)) {
if (settings.name == HomeScreen.routeName) {
// Check if we are in the drawn state.
// We don't want the app to background in this case.
// Defer to home_screen.dart
return true;
}
return false;
}

return true;
}

static Route generateRoute(RouteSettings settings) {
// Try to find the appropriate screen, but keep `RouteNotFoundScreen` as default
WidgetBuilder screenBuilder = (context) => const RouteNotFoundScreen();
Expand All @@ -74,26 +94,12 @@ class Routing {
// if the route is an initial route
return MaterialPageRoute(
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async {
// If the current route has a subnavigator and is on the root, defer to that component's `WillPopScope`
if (_isSubnavigatorRoute(settings) && _isRootRoute(settings)) {
return true;
}

// Otherwise if it is a root route, background the app on backpress
if (_isRootRoute(settings)) {
if (settings.name == HomeScreen.routeName) {
// Check if we are in the drawn state.
// We don't want the app to background in this case.
// Defer to home_screen.dart
return true;
}
return PopScope(
canPop: _canPop(settings, context),
onPopInvokedWithResult: (didPop, popResult) {
if (!didPop) {
IrmaRepositoryProvider.of(context).bridgedDispatch(AndroidSendToBackgroundEvent());
return false;
}

return true;
},
child: screenBuilder(context),
);
Expand Down
86 changes: 45 additions & 41 deletions lib/src/screens/activity/activity_detail_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,52 +28,56 @@ class ActivityDetailScreen extends StatelessWidget {
final lang = FlutterI18n.currentLocale(context)!.languageCode;

return Scaffold(
backgroundColor: theme.backgroundSecondary,
backgroundColor: theme.backgroundTertiary,
appBar: const IrmaAppBar(
titleTranslationKey: 'home.nav_bar.activity',
),
body: SingleChildScrollView(
padding: EdgeInsets.all(theme.defaultSpacing),
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Builder(
builder: (context) {
switch (logEntry.type) {
case LogEntryType.signing:
case LogEntryType.disclosing:
return ActivityDetailDisclosure(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
);
case LogEntryType.issuing:
return ActivityDetailIssuance(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
);
case LogEntryType.removal:
return ActivityDetailRemoval(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
);
}
},
),
//Always add the timestamp of the activity on the bottom
SizedBox(height: theme.smallSpacing),
Center(
child: TranslatedText(
'credential.date_at_time',
key: const Key('activity_timestamp'),
translationParams: {
'date': DateFormat.yMMMMd(lang).format(logEntry.time),
'time': DateFormat.jm(lang).format(logEntry.time),
body: SizedBox(
height: double.infinity,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.all(theme.defaultSpacing),
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Builder(
builder: (context) {
switch (logEntry.type) {
case LogEntryType.signing:
case LogEntryType.disclosing:
return ActivityDetailDisclosure(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
);
case LogEntryType.issuing:
return ActivityDetailIssuance(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
);
case LogEntryType.removal:
return ActivityDetailRemoval(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
);
}
},
style: theme.themeData.textTheme.bodyMedium,
),
),
],
//Always add the timestamp of the activity on the bottom
SizedBox(height: theme.smallSpacing),
Center(
child: TranslatedText(
'credential.date_at_time',
key: const Key('activity_timestamp'),
translationParams: {
'date': DateFormat.yMMMMd(lang).format(logEntry.time),
'time': DateFormat.jm(lang).format(logEntry.time),
},
style: theme.themeData.textTheme.bodyMedium,
),
),
],
),
),
),
),
Expand Down
10 changes: 7 additions & 3 deletions lib/src/screens/activity/activity_tab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,19 @@ class _ActivityTabState extends State<ActivityTab> {
),
),
),
ActivityCard(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
Padding(
padding: EdgeInsets.only(bottom: theme.smallSpacing),
child: ActivityCard(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
),
),
];
},
).flattened.toList();

return ListView(
physics: const AlwaysScrollableScrollPhysics(),
controller: _scrollController,
padding: EdgeInsets.symmetric(
vertical: theme.smallSpacing,
Expand Down
90 changes: 49 additions & 41 deletions lib/src/screens/activity/widgets/activity_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,60 +105,68 @@ class ActivityCard extends StatelessWidget {
label: semanticLabel,
button: true,
child: IrmaCard(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ActivityDetailScreen(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
margin: EdgeInsets.zero,
child: Material(
child: InkWell(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ActivityDetailScreen(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
),
),
),
),
),
child: Semantics(
excludeSemantics: true,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Semantics(
excludeSemantics: true,
child: Padding(
padding: EdgeInsets.all(theme.defaultSpacing),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IrmaAvatar(
size: 52,
logoPath: logo,
initials: title != '' ? title[0] : null,
),
SizedBox(
width: theme.smallSpacing,
),
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
TranslatedText(localizedTimeStamp),
Text(
title,
style: theme.themeData.textTheme.headlineMedium!.copyWith(
color: theme.dark,
),
IrmaAvatar(
size: 52,
logoPath: logo,
initials: title != '' ? title[0] : null,
),
SizedBox(
width: theme.smallSpacing,
),
TranslatedText(
subtitleTranslationKey,
style: theme.themeData.textTheme.bodyMedium!.copyWith(
fontSize: 14,
color: theme.dark,
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TranslatedText(localizedTimeStamp),
Text(
title,
style: theme.themeData.textTheme.headlineMedium!.copyWith(
color: theme.dark,
),
),
TranslatedText(
subtitleTranslationKey,
style: theme.themeData.textTheme.bodyMedium!.copyWith(
fontSize: 14,
color: theme.dark,
),
)
],
),
)
],
),
)
),
Icon(
Icons.chevron_right,
color: Colors.grey.shade700,
),
],
),
),
Icon(
Icons.chevron_right,
color: Colors.grey.shade700,
),
],
),
),
),
),
Expand Down
9 changes: 6 additions & 3 deletions lib/src/screens/activity/widgets/recent_activity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,12 @@ class _RecentActivityState extends State<RecentActivity> {
crossAxisAlignment: CrossAxisAlignment.start,
children: logEntries
.map(
(logEntry) => ActivityCard(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
(logEntry) => Padding(
padding: EdgeInsets.only(bottom: theme.smallSpacing),
child: ActivityCard(
logEntry: logEntry,
irmaConfiguration: irmaConfiguration,
),
),
)
.toList(),
Expand Down
78 changes: 41 additions & 37 deletions lib/src/screens/add_data/add_data_details_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class _AddDataDetailsScreenState extends State<AddDataDetailsScreen> {
);

return Scaffold(
backgroundColor: theme.backgroundSecondary,
backgroundColor: theme.backgroundTertiary,
appBar: IrmaAppBar(
titleTranslationKey: 'data.add.details.title',
leadingAction: widget.inDisclosure ? widget.onCancel : null,
Expand All @@ -66,43 +66,47 @@ class _AddDataDetailsScreenState extends State<AddDataDetailsScreen> {
),
],
),
body: SingleChildScrollView(
controller: _controller,
padding: EdgeInsets.symmetric(
vertical: theme.defaultSpacing,
horizontal: theme.smallSpacing,
),
child: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: paddingText,
child: Text(
widget.credentialType.faqIntro.isEmpty
?
// Fallback generic add credential text
FlutterI18n.translate(
context,
'data.add.details.obtain',
translationParams: {
'credential': widget.credentialType.name.translate(lang),
},
)
: getTranslation(context, widget.credentialType.faqIntro).replaceAll('\\n', '\n'),
style: theme.textTheme.bodyMedium,
),
),
Padding(
padding: paddingQuestions,
child: AddDataQuestions(
inDisclosure: widget.inDisclosure,
credentialType: widget.credentialType,
parentScrollController: _controller,
body: SizedBox(
height: double.infinity,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
controller: _controller,
padding: EdgeInsets.symmetric(
vertical: theme.defaultSpacing,
horizontal: theme.smallSpacing,
),
child: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: paddingText,
child: Text(
widget.credentialType.faqIntro.isEmpty
?
// Fallback generic add credential text
FlutterI18n.translate(
context,
'data.add.details.obtain',
translationParams: {
'credential': widget.credentialType.name.translate(lang),
},
)
: getTranslation(context, widget.credentialType.faqIntro).replaceAll('\\n', '\n'),
style: theme.textTheme.bodyMedium,
),
),
)
],
Padding(
padding: paddingQuestions,
child: AddDataQuestions(
inDisclosure: widget.inDisclosure,
credentialType: widget.credentialType,
parentScrollController: _controller,
),
)
],
),
),
),
),
Expand Down
Loading

0 comments on commit 40e5dd3

Please sign in to comment.