diff --git a/lib/home_page.dart b/lib/home_page.dart index 6f35c1e..bb79f49 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -1,9 +1,14 @@ import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.dart'; +import 'package:yaru_widgets/widgets.dart'; import 'constants.dart'; +import 'plated_icon.dart'; +import 'repositories.dart'; import 'screen_message.dart'; import 'sub_page.dart'; +import 'package:universal_html/html.dart' as html; +import 'package:path/path.dart' as p; class HomePage extends StatelessWidget { const HomePage({super.key}); @@ -12,27 +17,60 @@ class HomePage extends StatelessWidget { Widget build(BuildContext context) { return SubPage( body: Center( - child: Padding( - padding: const EdgeInsets.all(50), - child: ScreenMessage( - title: Shimmer.fromColors( - loop: 1, - period: const Duration(seconds: 3), - baseColor: kBaseColor, - highlightColor: kHighlightColor, - child: const Text(kWelcomeTitle), + child: YaruCarousel( + navigationControls: false, + height: double.infinity, + width: double.infinity, + placeIndicator: false, + controller: YaruCarouselController( + viewportFraction: 1, + autoScroll: true, + autoScrollDuration: const Duration( + seconds: 6, ), - subTitle: Shimmer.fromColors( - baseColor: kBaseColor, - highlightColor: kHighlightColor, - child: InkWell( - borderRadius: BorderRadius.circular(5), - onTap: () => Navigator.of(context).pushNamed('/projects'), - child: const Text(kWelcomeButtonText), + scrollAnimationDuration: const Duration(seconds: 1), + ), + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 50), + child: ScreenMessage( + title: const Text(kWelcomeTitle), + subTitle: Shimmer.fromColors( + baseColor: kBaseColor, + highlightColor: kHighlightColor, + child: InkWell( + borderRadius: BorderRadius.circular(5), + onTap: () => Navigator.of(context).pushNamed('/projects'), + child: const Text(kWelcomeButtonText), + ), + ), + label: const Text(kAppTitle), ), ), - label: const Text(kAppTitle), - ), + ...repositories.map( + (e) { + void onTap() => + html.window.open(p.join(kGitHubPrefix, e.$1, e.$2), ''); + return ScreenMessage( + icon: PlatedIcon( + icon: e.$4, + onTap: onTap, + ), + title: Text(e.$2), + subTitle: Shimmer.fromColors( + baseColor: kBaseColor, + highlightColor: kHighlightColor, + child: InkWell( + borderRadius: BorderRadius.circular(5), + onTap: onTap, + child: const Text('GitHub'), + ), + ), + label: Text(e.$1), + ); + }, + ).toList(), + ], ), ), ); diff --git a/lib/screen_message.dart b/lib/screen_message.dart index 90f2976..5b8f560 100644 --- a/lib/screen_message.dart +++ b/lib/screen_message.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'build_context_x.dart'; -class ScreenMessage extends StatefulWidget { +class ScreenMessage extends StatelessWidget { const ScreenMessage({ super.key, required this.label, @@ -14,21 +14,6 @@ class ScreenMessage extends StatefulWidget { final Widget label, title, subTitle; final Widget? icon; - @override - State createState() => _ScreenMessageState(); -} - -class _ScreenMessageState extends State { - double _opacity = 0.0; - - @override - void initState() { - super.initState(); - Future.delayed(const Duration(milliseconds: 300), () { - setState(() => _opacity = 1); - }); - } - @override Widget build(BuildContext context) { final size = context.mq.size; @@ -45,28 +30,25 @@ class _ScreenMessageState extends State { : CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - if (widget.icon != null && smallWindow) + if (icon != null && smallWindow) Padding( padding: EdgeInsets.only( left: smallWindow ? 0 : 40, bottom: smallWindow ? 8 : 0, ), - child: widget.icon, + child: icon, ), if (!smallWindow) DefaultTextStyle( textAlign: smallWindow ? TextAlign.center : null, style: context.theme.textTheme.headlineSmall ?? const TextStyle(), - child: Padding( - padding: const EdgeInsets.only(left: 3, bottom: 5), - child: widget.label, - ), + child: label, ), DefaultTextStyle( textAlign: smallWindow ? TextAlign.center : null, style: context.theme.textTheme.headlineLarge ?? const TextStyle(), - child: widget.title, + child: title, ), DefaultTextStyle( textAlign: smallWindow ? TextAlign.center : null, @@ -75,35 +57,40 @@ class _ScreenMessageState extends State { const TextStyle(), child: Padding( padding: const EdgeInsets.only( - left: 3, top: 8, ), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 400), - child: widget.subTitle, + child: subTitle, ), ), ), ].map((e) => Flexible(child: e)).toList(), ), ), - if (widget.icon != null && !smallWindow) + if (icon != null && !smallWindow) Padding( padding: const EdgeInsets.only(left: 40), - child: widget.icon, + child: icon, ), ]; - return AnimatedOpacity( - opacity: _opacity, - duration: const Duration(seconds: 3), - child: Center( - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: children, - ), - ), + return TweenAnimationBuilder( + tween: Tween(begin: 0.0, end: 1.0), + curve: Curves.ease, + duration: const Duration(seconds: 2), + builder: (BuildContext context, double opacity, Widget? child) { + return Opacity( + opacity: opacity, + child: Center( + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: children, + ), + ), + ); + }, ); } }