Skip to content

Commit

Permalink
Reworked the transition between the splash screen and the login page.…
Browse files Browse the repository at this point in the history
… The animation in the logo now works flawlessly.
  • Loading branch information
pedroafmonteiro committed Dec 4, 2024
1 parent 7d610df commit 9205446
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 131 deletions.
35 changes: 7 additions & 28 deletions packages/uni_app/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ Future<void> main() async {
final savedTheme = PreferencesController.getThemeMode();
final savedLocale = PreferencesController.getLocale();

final route = await firstRoute();
const route = '/splash';

await SentryFlutter.init(
(options) {
Expand Down Expand Up @@ -193,7 +193,7 @@ Future<void> main() async {
create: (_) => ThemeNotifier(savedTheme),
),
],
child: Application(route),
child: const Application(route),
),
),
);
Expand All @@ -218,7 +218,6 @@ class Application extends StatefulWidget {
/// Manages the app depending on its current state
class ApplicationState extends State<Application> {
final navigatorObservers = <NavigatorObserver>[];
bool _showSplash = true;

@override
void initState() {
Expand All @@ -228,34 +227,10 @@ class ApplicationState extends State<Application> {
if (plausible != null) {
navigatorObservers.add(PlausibleNavigatorObserver(plausible));
}

_initializeApp();
}

void _initializeApp() {
Future.delayed(const Duration(milliseconds: 3500), () {
if (mounted) {
setState(() {
_showSplash = false;
});
}
});
}

@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);

if (_showSplash) {
return SplashScreenView(nextScreen: _buildMainApp());
}

return _buildMainApp();
}

Widget _buildMainApp() {
return Consumer2<ThemeNotifier, LocaleNotifier>(
builder: (context, themeNotifier, localeNotifier, _) => UpgradeAlert(
navigatorKey: Application.navigatorKey,
Expand All @@ -278,8 +253,12 @@ class ApplicationState extends State<Application> {
navigatorObservers: navigatorObservers,
onGenerateRoute: (settings) {
final transitions = {
'/splash': PageTransition.makePageTransition(
page: const SplashScreenView(),
settings: settings,
),
'/${NavigationItem.navLogin.route}':
PageTransition.makePageTransition(
PageTransition.splashTransitionRoute(
page: const LoginPageView(),
settings: settings,
),
Expand Down
11 changes: 11 additions & 0 deletions packages/uni_app/lib/view/common_widgets/page_transition.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ class PageTransition {
);
}

static Route<Widget> splashTransitionRoute({required Widget page, required RouteSettings settings, bool maintainState = true}) {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => page,
settings: settings,
maintainState: maintainState,
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return FadeTransition(opacity: animation, child: child);
},
);
}

static Future<void> requestTermsAndConditionsAcceptanceIfNeeded(
BuildContext context,
) async {
Expand Down
4 changes: 2 additions & 2 deletions packages/uni_app/lib/view/login/login.dart
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,9 @@ class LoginPageViewState extends State<LoginPageView>
) {
return ScaleTransition(
scale: animation.drive(
Tween(begin: 1, end: 1).chain(
Tween(begin: 1.0, end: 1.0).chain(
CurveTween(curve: Curves.easeInOut),
) as Animatable<double>,
),
),
child: SvgPicture.asset(
'assets/images/logo_dark.svg',
Expand Down
188 changes: 87 additions & 101 deletions packages/uni_app/lib/view/splash/splash.dart
Original file line number Diff line number Diff line change
@@ -1,123 +1,109 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:uni/main.dart';

class SplashScreenView extends StatefulWidget {
const SplashScreenView({super.key, required this.nextScreen});

final Widget nextScreen;
const SplashScreenView({super.key});

@override
_SplashScreenViewState createState() => _SplashScreenViewState();
}

class _SplashScreenViewState extends State<SplashScreenView> {
late Future<void> _loadNextScreen;

@override
void initState() {
super.initState();
_loadNextScreen = _initializeNextScreen();
}

Future<void> _initializeNextScreen() async {
await Future<void>.delayed(const Duration(milliseconds: 3500));
}

@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.ltr,
child: Scaffold(
extendBody: true,
extendBodyBehindAppBar: true,
backgroundColor: const Color(0xFF280709),
body: FutureBuilder<void>(
future: _loadNextScreen,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return widget.nextScreen;
} else {
return Stack(
children: [
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Hero(
tag: 'logo',
flightShuttleBuilder: (
flightContext,
animation,
flightDirection,
fromHeroContext,
toHeroContext,
) {
return ScaleTransition(
scale: animation.drive(
Tween(begin: 0, end: 1).chain(
CurveTween(curve: Curves.easeInOut),
) as Animatable<double>,
),
child: SvgPicture.asset(
'assets/images/logo_dark.svg',
colorFilter: const ColorFilter.mode(
Color(0xFFFFF5F3),
BlendMode.srcIn,
),
),
);
},
child: SvgPicture.asset(
'assets/images/logo_dark.svg',
colorFilter: const ColorFilter.mode(
Color(0xFFFFF5F3),
BlendMode.srcIn,
),
),
Future.delayed(
const Duration(milliseconds: 1500),
() async {
if (mounted) {
final route = await firstRoute();
if (context.mounted) {
await Navigator.pushReplacementNamed(context, route);
}
}
}
);
return Scaffold(
extendBody: true,
extendBodyBehindAppBar: true,
backgroundColor: const Color(0xFF280709),
body: Stack(
children: [
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Hero(
tag: 'logo',
flightShuttleBuilder: (
flightContext,
animation,
flightDirection,
fromHeroContext,
toHeroContext,
) {
return ScaleTransition(
scale: animation.drive(
Tween(begin: 0.0, end: 1.0).chain(
CurveTween(curve: Curves.easeInOut),
),
const SizedBox(height: 20),
const Text(
'by NIAEFEUP',
style: TextStyle(
color: Color(0xFFFFF5F3),
fontFamily: 'Roboto',
fontSize: 20,
fontWeight: FontWeight.w400,
),
),
child: SvgPicture.asset(
'assets/images/logo_dark.svg',
colorFilter: const ColorFilter.mode(
Color(0xFFFFF5F3),
BlendMode.srcIn,
),
],
),
),
Container(
decoration: const BoxDecoration(
gradient: RadialGradient(
center: Alignment(-0.95, -1),
colors: [
Color(0x705F171D),
Color(0x02511515),
],
stops: [0, 1],
),
);
},
child: SvgPicture.asset(
'assets/images/logo_dark.svg',
colorFilter: const ColorFilter.mode(
Color(0xFFFFF5F3),
BlendMode.srcIn,
),
),
Container(
decoration: const BoxDecoration(
gradient: RadialGradient(
center: Alignment(0.1, 0.95),
radius: 0.3,
colors: [
Color(0x705F171D),
Color(0x02511515),
],
stops: [0, 1],
),
),
),
const SizedBox(height: 20),
const Text(
'by NIAEFEUP',
style: TextStyle(
color: Color(0xFFFFF5F3),
fontFamily: 'Roboto',
fontSize: 20,
fontWeight: FontWeight.w400,
),
),
],
),
),
Container(
decoration: const BoxDecoration(
gradient: RadialGradient(
center: Alignment(-0.95, -1),
colors: [
Color(0x705F171D),
Color(0x02511515),
],
stops: [0, 1],
),
),
),
Container(
decoration: const BoxDecoration(
gradient: RadialGradient(
center: Alignment(0.1, 0.95),
radius: 0.3,
colors: [
Color(0x705F171D),
Color(0x02511515),
],
);
}
},
),
stops: [0, 1],
),
),
),
],
),
);
}
Expand Down

0 comments on commit 9205446

Please sign in to comment.