Add widget for empty state and coach mark

This commit is contained in:
Neeraj Gupta 2023-05-06 00:45:34 +05:30
parent 4d88503c2b
commit 73c130ce7e
No known key found for this signature in database
GPG key ID: 3C5A1684DC1729E1
4 changed files with 140 additions and 110 deletions

View file

@ -7,7 +7,7 @@ class PreferenceService {
late final SharedPreferences _prefs; late final SharedPreferences _prefs;
static const kHasShownCoachMarkKey = "has_shown_coach_mark"; static const kHasShownCoachMarkKey = "has_shown_coach_markx";
Future<void> init() async { Future<void> init() async {
_prefs = await SharedPreferences.getInstance(); _prefs = await SharedPreferences.getInstance();

View file

@ -0,0 +1,71 @@
import 'dart:ui';
import 'package:ente_auth/core/event_bus.dart';
import 'package:ente_auth/events/codes_updated_event.dart';
import 'package:ente_auth/l10n/l10n.dart';
import 'package:ente_auth/services/preference_service.dart';
import 'package:flutter/material.dart';
class CoachMarkWidget extends StatelessWidget {
const CoachMarkWidget({super.key});
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
return GestureDetector(
onTap: () async {
await PreferenceService.instance.setHasShownCoachMark(true);
Bus.instance.fire(CodesUpdatedEvent());
},
child: Row(
children: [
Expanded(
child: Container(
width: double.infinity,
color: Theme.of(context).colorScheme.background.withOpacity(0.1),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.swipe_left,
size: 42,
),
const SizedBox(
height: 24,
),
Text(
l10n.swipeHint,
style: Theme.of(context).textTheme.headline6,
),
const SizedBox(
height: 36,
),
SizedBox(
width: 160,
child: OutlinedButton(
onPressed: () async {
await PreferenceService.instance
.setHasShownCoachMark(true);
Bus.instance.fire(CodesUpdatedEvent());
},
child: Text(l10n.ok),
),
)
],
),
],
),
),
),
),
],
),
);
}
}

View file

@ -0,0 +1,61 @@
import 'package:ente_auth/l10n/l10n.dart';
import 'package:flutter/material.dart';
class HomeEmptyStateWidget extends StatelessWidget {
final VoidCallback? onScanTap;
final VoidCallback? onManuallySetupTap;
const HomeEmptyStateWidget({
Key? key,
required this.onScanTap,
required this.onManuallySetupTap,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
return Center(
child: ConstrainedBox(
constraints: const BoxConstraints.tightFor(height: 800, width: 450),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 40.0, horizontal: 40),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Image.asset(
"assets/wallet-front-gradient.png",
width: 200,
height: 200,
),
Text(
l10n.setupFirstAccount,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline4,
),
const SizedBox(height: 64),
SizedBox(
width: 400,
child: OutlinedButton(
onPressed: onScanTap,
child: Text(l10n.importScanQrCode),
),
),
const SizedBox(height: 18),
SizedBox(
width: 400,
child: OutlinedButton(
onPressed: onManuallySetupTap,
child: Text(l10n.importEnterSetupKey),
),
),
],
),
],
),
),
),
);
}
}

View file

@ -1,6 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:ui';
import 'package:ente_auth/core/event_bus.dart'; import 'package:ente_auth/core/event_bus.dart';
import 'package:ente_auth/ente_theme_data.dart'; import 'package:ente_auth/ente_theme_data.dart';
@ -15,6 +14,8 @@ import 'package:ente_auth/store/code_store.dart';
import 'package:ente_auth/ui/account/logout_dialog.dart'; import 'package:ente_auth/ui/account/logout_dialog.dart';
import 'package:ente_auth/ui/code_widget.dart'; import 'package:ente_auth/ui/code_widget.dart';
import 'package:ente_auth/ui/common/loading_widget.dart'; import 'package:ente_auth/ui/common/loading_widget.dart';
import 'package:ente_auth/ui/home/coach_mark_widget.dart';
import 'package:ente_auth/ui/home/home_empty_state.dart';
import 'package:ente_auth/ui/home/speed_dial_label_widget.dart'; import 'package:ente_auth/ui/home/speed_dial_label_widget.dart';
import 'package:ente_auth/ui/scanner_page.dart'; import 'package:ente_auth/ui/scanner_page.dart';
import 'package:ente_auth/ui/settings_page.dart'; import 'package:ente_auth/ui/settings_page.dart';
@ -206,7 +207,10 @@ class _HomePageState extends State<HomePage> {
final l10n = context.l10n; final l10n = context.l10n;
if (_hasLoaded) { if (_hasLoaded) {
if (_filteredCodes.isEmpty && _searchText.isEmpty) { if (_filteredCodes.isEmpty && _searchText.isEmpty) {
return _getEmptyState(); return HomeEmptyStateWidget(
onScanTap: _redirectToManualEntryPage,
onManuallySetupTap: _redirectToManualEntryPage,
);
} else { } else {
final list = ListView.builder( final list = ListView.builder(
itemBuilder: ((context, index) { itemBuilder: ((context, index) {
@ -218,7 +222,7 @@ class _HomePageState extends State<HomePage> {
return Stack( return Stack(
children: [ children: [
list, list,
_getCoachMarkWidget(), const CoachMarkWidget(),
], ],
); );
} else if (_showSearchBox) { } else if (_showSearchBox) {
@ -291,110 +295,4 @@ class _HomePageState extends State<HomePage> {
], ],
); );
} }
Widget _getEmptyState() {
final l10n = context.l10n;
return Center(
child: ConstrainedBox(
constraints: const BoxConstraints.tightFor(height: 800, width: 450),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 40.0, horizontal: 40),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
Image.asset(
"assets/wallet-front-gradient.png",
width: 200,
height: 200,
),
Text(
l10n.setupFirstAccount,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline4,
),
const SizedBox(height: 64),
SizedBox(
width: 400,
child: OutlinedButton(
onPressed: _redirectToScannerPage,
child: Text(l10n.importScanQrCode),
),
),
const SizedBox(height: 18),
SizedBox(
width: 400,
child: OutlinedButton(
onPressed: _redirectToManualEntryPage,
child: Text(l10n.importEnterSetupKey),
),
),
],
),
],
),
),
),
);
}
Widget _getCoachMarkWidget() {
final l10n = context.l10n;
return GestureDetector(
onTap: () async {
await PreferenceService.instance.setHasShownCoachMark(true);
setState(() {});
},
child: Row(
children: [
Expanded(
child: Container(
width: double.infinity,
color: Theme.of(context).colorScheme.background.withOpacity(0.1),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 8, sigmaY: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.swipe_left,
size: 42,
),
const SizedBox(
height: 24,
),
Text(
l10n.swipeHint,
style: Theme.of(context).textTheme.headline6,
),
const SizedBox(
height: 36,
),
SizedBox(
width: 160,
child: OutlinedButton(
onPressed: () async {
await PreferenceService.instance
.setHasShownCoachMark(true);
setState(() {});
},
child: Text(l10n.ok),
),
)
],
),
],
),
),
),
),
],
),
);
}
} }