feat: make the transition when navigating to the introduction screen more fluent

This commit is contained in:
mike doornenbal 2025-02-18 16:18:33 +01:00
parent 25b3988aea
commit d3d76de017
7 changed files with 68 additions and 38 deletions

View file

@ -7,12 +7,18 @@ import "package:introduction_repository_interface/introduction_repository_interf
class FirebaseIntroductionRepository class FirebaseIntroductionRepository
implements IntroductionRepositoryInterface { implements IntroductionRepositoryInterface {
bool? _shouldShowIntroduction;
List<IntroductionPageData>? _introductionPages;
final _introductionCollection = FirebaseFirestore.instance final _introductionCollection = FirebaseFirestore.instance
.collection("flutter_introduction") .collection("flutter_introduction")
.doc("flutter_introduction"); .doc("flutter_introduction");
@override @override
Future<List<IntroductionPageData>> fetchIntroductionPages() async { Future<List<IntroductionPageData>> fetchIntroductionPages() async {
if (_introductionPages != null) {
return _introductionPages!;
}
try { try {
var introductionPagesData = await _introductionCollection var introductionPagesData = await _introductionCollection
.collection("pages") .collection("pages")
@ -27,6 +33,7 @@ class FirebaseIntroductionRepository
introductionPagesData.docs.map((e) => e.data()).toList(); introductionPagesData.docs.map((e) => e.data()).toList();
introductionPages.sort((a, b) => a.id.compareTo(b.id)); introductionPages.sort((a, b) => a.id.compareTo(b.id));
_introductionPages = introductionPages;
return introductionPages; return introductionPages;
} on Exception catch (_) { } on Exception catch (_) {
throw Exception(); throw Exception();
@ -51,6 +58,9 @@ class FirebaseIntroductionRepository
@override @override
Future<bool> shouldShow() async { Future<bool> shouldShow() async {
if (_shouldShowIntroduction != null) {
return _shouldShowIntroduction!;
}
try { try {
await FirebaseAuth.instance.signInAnonymously(); await FirebaseAuth.instance.signInAnonymously();
var deviceId = await _getDeviceId(); var deviceId = await _getDeviceId();
@ -64,8 +74,10 @@ class FirebaseIntroductionRepository
if (!introductionCompleted.exists) { if (!introductionCompleted.exists) {
return true; return true;
} }
_shouldShowIntroduction =
// ignore: avoid_dynamic_calls // ignore: avoid_dynamic_calls
return !introductionCompleted.data()!["introduction_completed"]; !introductionCompleted.data()!["introduction_completed"];
return _shouldShowIntroduction!;
} on Exception catch (_) { } on Exception catch (_) {
throw Exception(); throw Exception();
} }
@ -83,4 +95,10 @@ class FirebaseIntroductionRepository
} }
return null; return null;
} }
@override
Future<void> prefetchIntroduction() async {
await shouldShow();
await fetchIntroductionPages();
}
} }

View file

@ -17,16 +17,12 @@ class Button extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var theme = Theme.of(context); var theme = Theme.of(context);
return Expanded( return Expanded(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 180,
maxHeight: 32,
),
child: showButton child: showButton
? FilledButton( ? FilledButton(
style: ButtonStyle( style: ButtonStyle(
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
minimumSize: WidgetStateProperty.all(const Size(160, 32)),
backgroundColor: WidgetStateProperty.all( backgroundColor: WidgetStateProperty.all(
introductionTheme.buttonBackgroundColor, introductionTheme.buttonBackgroundColor,
), ),
@ -47,8 +43,7 @@ class Button extends StatelessWidget {
theme.textTheme.bodyMedium, theme.textTheme.bodyMedium,
), ),
) )
: const SizedBox(), : const SizedBox.shrink(),
),
); );
} }
} }

View file

@ -1,7 +1,5 @@
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:flutter_introduction/flutter_introduction.dart"; import "package:flutter_introduction/flutter_introduction.dart";
import "package:flutter_introduction/src/config/introduction_theme.dart";
import "package:flutter_introduction/src/enums/introduction_layout_style.dart";
class IntroductionPage extends StatelessWidget { class IntroductionPage extends StatelessWidget {
const IntroductionPage({ const IntroductionPage({

View file

@ -7,4 +7,6 @@ abstract class IntroductionRepositoryInterface {
Future<void> setCompleted({bool value = true}); Future<void> setCompleted({bool value = true});
Future<bool> shouldShow(); Future<bool> shouldShow();
Future<void> prefetchIntroduction();
} }

View file

@ -11,7 +11,11 @@ class LocalIntroductionRepository implements IntroductionRepositoryInterface {
Future<bool> shouldShow() async => !_completed; Future<bool> shouldShow() async => !_completed;
@override @override
Future<List<IntroductionPageData>> fetchIntroductionPages() { Future<List<IntroductionPageData>> fetchIntroductionPages() async => [];
throw Exception();
@override
Future<void> prefetchIntroduction() async {
await shouldShow();
await fetchIntroductionPages();
} }
} }

View file

@ -16,4 +16,7 @@ class IntroductionService {
Future<bool> shouldShow() async => Future<bool> shouldShow() async =>
introductionRepositoryInterface.shouldShow(); introductionRepositoryInterface.shouldShow();
Future<void> prefetchIntroduction() async =>
introductionRepositoryInterface.prefetchIntroduction();
} }

View file

@ -3,10 +3,10 @@ import "package:shared_preferences/shared_preferences.dart";
class SharedPreferencesIntroductionRepository class SharedPreferencesIntroductionRepository
implements IntroductionRepositoryInterface { implements IntroductionRepositoryInterface {
bool? _shouldShowIntroduction;
@override @override
Future<List<IntroductionPageData>> fetchIntroductionPages() async { Future<List<IntroductionPageData>> fetchIntroductionPages() async => [];
throw Exception();
}
@override @override
Future<void> setCompleted({bool value = true}) async { Future<void> setCompleted({bool value = true}) async {
@ -16,8 +16,18 @@ class SharedPreferencesIntroductionRepository
@override @override
Future<bool> shouldShow() async { Future<bool> shouldShow() async {
if (_shouldShowIntroduction != null) {
return !_shouldShowIntroduction!;
}
var sharedPrefs = await SharedPreferences.getInstance(); var sharedPrefs = await SharedPreferences.getInstance();
var shouldShow = sharedPrefs.getBool("_completedIntroduction") ?? true; var shouldShow = sharedPrefs.getBool("_completedIntroduction") ?? true;
return !shouldShow; _shouldShowIntroduction = shouldShow;
return !_shouldShowIntroduction!;
}
@override
Future<void> prefetchIntroduction() async {
await shouldShow();
await fetchIntroductionPages();
} }
} }