From 5925e71beb5e2e54fd766fcc40af7250745a6487 Mon Sep 17 00:00:00 2001 From: MohammadTaha Basiri Date: Sun, 12 Dec 2021 15:41:04 +0330 Subject: [PATCH] D1APP-24 home page (static) --- lib/assets/images/categories/business.png | Bin 0 -> 7836 bytes lib/assets/images/categories/economic.png | Bin 0 -> 6727 bytes lib/assets/images/categories/enviromental.png | Bin 0 -> 4860 bytes lib/assets/images/categories/political.png | Bin 0 -> 5414 bytes lib/assets/images/categories/social.png | Bin 0 -> 7312 bytes lib/assets/images/categories/tech.png | Bin 0 -> 4720 bytes .../images/{logo => logos}/logo-h-t.png | Bin .../images/{logo => logos}/logo-v-t.png | Bin lib/config/design_config.dart | 21 +++- lib/constants/assets.dart | 15 ++- lib/models/radar_category.dart | 7 ++ lib/pages/authentication/authentication.dart | 2 +- lib/pages/home/home.dart | 99 ++++++++++++++++++ lib/pages/home/home_state.dart | 38 +++++++ lib/pages/home/widgets/categories_gird.dart | 76 ++++++++++++++ lib/pages/home/widgets/categories_list.dart | 76 ++++++++++++++ lib/pages/home/widgets/category_item.dart | 61 +++++++++++ lib/pages/home/widgets/search_field.dart | 47 +++++++++ lib/pages/splash/splash.dart | 2 +- lib/routes/route_generator.dart | 13 ++- lib/widgets/animated_visibility.dart | 90 ++++++++++++++++ lib/widgets/didvan/text.dart | 3 + lib/widgets/didvan/text_field.dart | 4 +- lib/widgets/ink_wrapper.dart | 38 +++++++ lib/widgets/logos/didvan_vertical_logo.dart | 11 ++ pubspec.yaml | 11 +- 26 files changed, 604 insertions(+), 10 deletions(-) create mode 100644 lib/assets/images/categories/business.png create mode 100644 lib/assets/images/categories/economic.png create mode 100644 lib/assets/images/categories/enviromental.png create mode 100644 lib/assets/images/categories/political.png create mode 100644 lib/assets/images/categories/social.png create mode 100644 lib/assets/images/categories/tech.png rename lib/assets/images/{logo => logos}/logo-h-t.png (100%) rename lib/assets/images/{logo => logos}/logo-v-t.png (100%) create mode 100644 lib/models/radar_category.dart create mode 100644 lib/pages/home/home.dart create mode 100644 lib/pages/home/home_state.dart create mode 100644 lib/pages/home/widgets/categories_gird.dart create mode 100644 lib/pages/home/widgets/categories_list.dart create mode 100644 lib/pages/home/widgets/category_item.dart create mode 100644 lib/pages/home/widgets/search_field.dart create mode 100644 lib/widgets/animated_visibility.dart create mode 100644 lib/widgets/ink_wrapper.dart diff --git a/lib/assets/images/categories/business.png b/lib/assets/images/categories/business.png new file mode 100644 index 0000000000000000000000000000000000000000..0470a949a66364c49727f37b6d6b09cbf0e92255 GIT binary patch literal 7836 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 literal 0 HcmV?d00001 diff --git a/lib/assets/images/categories/enviromental.png b/lib/assets/images/categories/enviromental.png new file mode 100644 index 0000000000000000000000000000000000000000..f56f648343fb7bc8fcf798a274e8fbb2a52593fe GIT binary patch literal 4860 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
L-Z%HVkX3WW`?NeuAjL8avoS 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 defaultShadow = [ + BoxShadow( + color: const Color(0XFF4D4D4D).withOpacity(0.25), + offset: const Offset(0, 4), + blurRadius: 8, + spreadRadius: 0, + ) + ]; - static const Duration defaultAppDuration = Duration(milliseconds: 400); + static const Duration defaultAnimationDuration = Duration(milliseconds: 600); static final SystemUiOverlayStyle systemUIOverlayStyle = SystemUiOverlayStyle( statusBarBrightness: Brightness.dark, diff --git a/lib/constants/assets.dart b/lib/constants/assets.dart index 029a236..59af3fe 100644 --- a/lib/constants/assets.dart +++ b/lib/constants/assets.dart @@ -4,10 +4,21 @@ class Assets { static const String _baseAnimationsPath = _basePath + '/animations'; static const String verticalLogoWithText = - _baseImagesPath + '/logo/logo-v-t.png'; + _baseImagesPath + '/logos/logo-v-t.png'; static const String horizontalLogoWithText = - _baseImagesPath + '/logo/logo-h-t.png'; + _baseImagesPath + '/logos/logo-h-t.png'; static const String logoLoadingAnimation = _baseAnimationsPath + '/indicator.riv'; + + static const businessCategoryIcon = + _baseImagesPath + '/categories/business.png'; + static const economicCategoryIcon = + _baseImagesPath + '/categories/economic.png'; + static const enviromentalCategoryIcon = + _baseImagesPath + '/categories/enviromental.png'; + static const politicalCategoryIcon = + _baseImagesPath + '/categories/political.png'; + static const socialCategoryIcon = _baseImagesPath + '/categories/social.png'; + static const techCategoryIcon = _baseImagesPath + '/categories/tech.png'; } diff --git a/lib/models/radar_category.dart b/lib/models/radar_category.dart new file mode 100644 index 0000000..4312d46 --- /dev/null +++ b/lib/models/radar_category.dart @@ -0,0 +1,7 @@ +class RadarCategory { + final int id; + final String title; + final String asset; + + RadarCategory({required this.id, required this.title, required this.asset}); +} diff --git a/lib/pages/authentication/authentication.dart b/lib/pages/authentication/authentication.dart index f4a94e2..ade5c92 100644 --- a/lib/pages/authentication/authentication.dart +++ b/lib/pages/authentication/authentication.dart @@ -27,7 +27,7 @@ class _AuthenticationState extends State { return Scaffold( body: Consumer( builder: (context, state, child) => AnimatedSwitcher( - duration: DesignConfig.defaultAppDuration, + duration: DesignConfig.defaultAnimationDuration, child: _pages[state.currentPageIndex], ), ), diff --git a/lib/pages/home/home.dart b/lib/pages/home/home.dart new file mode 100644 index 0000000..1baa948 --- /dev/null +++ b/lib/pages/home/home.dart @@ -0,0 +1,99 @@ +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/pages/home/widgets/categories_gird.dart'; +import 'package:didvan/pages/home/widgets/categories_list.dart'; +import 'package:didvan/pages/home/widgets/search_field.dart'; +import 'package:didvan/widgets/didvan/text.dart'; +import 'package:didvan/widgets/logos/didvan_vertical_logo.dart'; +import 'package:flutter/material.dart'; + +class Home extends StatefulWidget { + const Home({Key? key}) : super(key: key); + + @override + State createState() => _HomeState(); +} + +class _HomeState extends State { + final ScrollController _scrollController = ScrollController(); + + bool _isColapsed = false; + bool _isAnimating = false; + + @override + void initState() { + _scrollController.addListener(() async { + if (_isAnimating) return; + final double position = _scrollController.position.pixels; + if (position > 5 && !_isColapsed) { + _isColapsed = true; + setState(() {}); + _isAnimating = true; + await _scrollController.animateTo( + 380, + duration: DesignConfig.defaultAnimationDuration, + curve: Curves.ease, + ); + _isAnimating = false; + } else if (position < 380 && _isColapsed) { + _isColapsed = false; + setState(() {}); + _isAnimating = true; + await _scrollController.animateTo( + 0, + duration: DesignConfig.defaultAnimationDuration, + curve: Curves.ease, + ); + _isAnimating = false; + } + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + final d = MediaQuery.of(context); + return Scaffold( + body: Stack( + children: [ + CustomScrollView( + controller: _scrollController, + physics: const BouncingScrollPhysics(), + slivers: [ + SliverPadding( + padding: const EdgeInsets.all( + 20, + ).copyWith(top: d.padding.top + 20), + sliver: SliverToBoxAdapter( + child: Container( + alignment: Alignment.centerRight, + height: 76, + child: const DidvanHorizontalLogo(), + ), + ), + ), + const SliverPadding( + padding: EdgeInsets.symmetric(horizontal: 16), + sliver: SliverToBoxAdapter( + child: SearchField(), + ), + ), + SliverPadding( + padding: const EdgeInsets.only(top: 300, right: 16, bottom: 20), + sliver: SliverToBoxAdapter( + child: DidvanText( + 'آخرین رصد', + style: Theme.of(context).textTheme.subtitle1, + color: DesignConfig.darkPrimaryColor2, + ), + ), + ), + ], + ), + CategoriesRow1(isColapsed: _isColapsed), + CategoriesRow2(isColapsed: _isColapsed), + CategoriesList(isColapsed: _isColapsed), + ], + ), + ); + } +} diff --git a/lib/pages/home/home_state.dart b/lib/pages/home/home_state.dart new file mode 100644 index 0000000..95c5840 --- /dev/null +++ b/lib/pages/home/home_state.dart @@ -0,0 +1,38 @@ +import 'package:didvan/constants/assets.dart'; +import 'package:didvan/models/radar_category.dart'; +import 'package:didvan/providers/core_provider.dart'; + +class HomeState extends CoreProvier { + final List categories = [ + RadarCategory( + id: 1, + title: 'افتصادی', + asset: Assets.economicCategoryIcon, + ), + RadarCategory( + id: 2, + title: 'سیاسی', + asset: Assets.politicalCategoryIcon, + ), + RadarCategory( + id: 3, + title: 'فناوری', + asset: Assets.techCategoryIcon, + ), + RadarCategory( + id: 4, + title: 'کسب و کار', + asset: Assets.businessCategoryIcon, + ), + RadarCategory( + id: 5, + title: 'زیست محیطی', + asset: Assets.enviromentalCategoryIcon, + ), + RadarCategory( + id: 6, + title: 'اجتماعی', + asset: Assets.socialCategoryIcon, + ), + ]; +} diff --git a/lib/pages/home/widgets/categories_gird.dart b/lib/pages/home/widgets/categories_gird.dart new file mode 100644 index 0000000..fe7ae1b --- /dev/null +++ b/lib/pages/home/widgets/categories_gird.dart @@ -0,0 +1,76 @@ +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/pages/home/home_state.dart'; +import 'package:didvan/pages/home/widgets/category_item.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class CategoriesRow1 extends StatelessWidget { + final bool isColapsed; + const CategoriesRow1({Key? key, required this.isColapsed}) : super(key: key); + + @override + Widget build(BuildContext context) { + final MediaQueryData d = MediaQuery.of(context); + return AnimatedPositioned( + duration: DesignConfig.defaultAnimationDuration, + top: isColapsed ? 12 : 176 + d.padding.top, + left: isColapsed ? -d.size.width : 0, + right: isColapsed ? d.size.width : 0, + child: Row( + children: context + .read() + .categories + .sublist(0, 3) + .map( + (category) => Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 6), + child: CategoryItem( + title: category.title, + asset: category.asset, + isColapsed: isColapsed, + ), + ), + ), + ) + .toList(), + ), + ); + } +} + +class CategoriesRow2 extends StatelessWidget { + const CategoriesRow2({ + Key? key, + required this.isColapsed, + }) : super(key: key); + + final bool isColapsed; + + @override + Widget build(BuildContext context) { + final MediaQueryData d = MediaQuery.of(context); + return AnimatedPositioned( + duration: DesignConfig.defaultAnimationDuration, + top: isColapsed ? -60 : 300 + d.padding.top, + left: isColapsed ? -80 : 0, + right: isColapsed ? 124 : 0, + child: Row( + children: context + .read() + .categories + .sublist(3, 6) + .map( + (category) => Expanded( + child: CategoryItem( + title: category.title, + asset: category.asset, + isColapsed: isColapsed, + ), + ), + ) + .toList(), + ), + ); + } +} diff --git a/lib/pages/home/widgets/categories_list.dart b/lib/pages/home/widgets/categories_list.dart new file mode 100644 index 0000000..b57ddc3 --- /dev/null +++ b/lib/pages/home/widgets/categories_list.dart @@ -0,0 +1,76 @@ +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/models/radar_category.dart'; +import 'package:didvan/pages/home/home_state.dart'; +import 'package:didvan/widgets/animated_visibility.dart'; +import 'package:didvan/widgets/didvan/text.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class CategoriesList extends StatelessWidget { + final bool isColapsed; + const CategoriesList({Key? key, required this.isColapsed}) : super(key: key); + + @override + Widget build(BuildContext context) { + final MediaQueryData d = MediaQuery.of(context); + final HomeState state = context.read(); + final List categories = []; + categories.addAll(state.categories.sublist(3, 6)); + categories.addAll(state.categories.sublist(0, 3)); + return Positioned( + top: 0, + left: 0, + right: 0, + child: AnimatedCrossFade( + crossFadeState: + isColapsed ? CrossFadeState.showSecond : CrossFadeState.showFirst, + duration: DesignConfig.defaultAnimationDuration, + firstChild: const SizedBox(), + secondChild: Container( + height: 60 + d.padding.top, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + boxShadow: DesignConfig.defaultShadow, + ), + child: SingleChildScrollView( + physics: const BouncingScrollPhysics(), + scrollDirection: Axis.horizontal, + padding: EdgeInsets.only( + top: d.padding.top + 12, + bottom: 12, + right: 12, + ), + child: Row( + children: [ + AnimatedVisibility( + isVisible: isColapsed, + duration: DesignConfig.defaultAnimationDuration, + child: _itemBuilder( + RadarCategory(title: 'همه', asset: '', id: 0), + ), + ), + for (var category in categories) _itemBuilder(category), + ], + ), + ), + ), + ), + ); + } + + Widget _itemBuilder(RadarCategory category) { + return Container( + margin: const EdgeInsets.only(left: 12), + width: 100, + padding: const EdgeInsets.all(4), + alignment: Alignment.center, + child: DidvanText(category.title), + decoration: BoxDecoration( + border: Border.all( + color: DesignConfig.darkPrimaryColor2, + ), + borderRadius: DesignConfig.lowBorderRadius, + ), + ); + } +} diff --git a/lib/pages/home/widgets/category_item.dart b/lib/pages/home/widgets/category_item.dart new file mode 100644 index 0000000..48560ae --- /dev/null +++ b/lib/pages/home/widgets/category_item.dart @@ -0,0 +1,61 @@ +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/widgets/animated_visibility.dart'; +import 'package:didvan/widgets/didvan/text.dart'; +import 'package:flutter/material.dart'; + +class CategoryItem extends StatelessWidget { + final String title; + final String asset; + final bool isColapsed; + + const CategoryItem({ + Key? key, + required this.title, + required this.asset, + required this.isColapsed, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final Size ds = MediaQuery.of(context).size; + return Center( + child: AnimatedContainer( + duration: DesignConfig.defaultAnimationDuration, + padding: isColapsed ? const EdgeInsets.all(4) : EdgeInsets.zero, + width: isColapsed ? 100 : ds.width / 3, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: DesignConfig.lowBorderRadius, + border: isColapsed + ? Border.all(color: DesignConfig.darkPrimaryColor2) + : null, + ), + child: Column( + children: [ + AnimatedVisibility( + duration: DesignConfig.defaultAnimationDuration, + isVisible: !isColapsed, + child: Container( + width: ds.width / 5, + height: ds.width / 5, + decoration: DesignConfig.actionCardDecoration, + padding: const EdgeInsets.all(8), + child: Image.asset( + asset, + ), + ), + ), + const SizedBox( + height: 8, + ), + DidvanText( + title, + style: Theme.of(context).textTheme.subtitle2, + color: DesignConfig.darkPrimaryColor2, + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/home/widgets/search_field.dart b/lib/pages/home/widgets/search_field.dart new file mode 100644 index 0000000..f68d931 --- /dev/null +++ b/lib/pages/home/widgets/search_field.dart @@ -0,0 +1,47 @@ +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/constants/app_icons.dart'; +import 'package:flutter/material.dart'; + +class SearchField extends StatelessWidget { + const SearchField({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + height: 40, + width: double.infinity, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + ), + child: Row( + children: [ + const Icon( + DidvanIcons.search_regular, + ), + Expanded( + child: TextField( + style: Theme.of(context).textTheme.bodyText1, + textAlignVertical: TextAlignVertical.top, + onChanged: (value) {}, + keyboardType: TextInputType.text, + textInputAction: TextInputAction.search, + decoration: InputDecoration( + contentPadding: const EdgeInsets.only( + left: 12, + right: 12, + bottom: 8, + ), + border: InputBorder.none, + hintText: 'جستجو مطلب در رادار', + hintStyle: Theme.of(context) + .textTheme + .subtitle2! + .copyWith(color: DesignConfig.greyColor5), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/splash/splash.dart b/lib/pages/splash/splash.dart index da8d1aa..74195cc 100644 --- a/lib/pages/splash/splash.dart +++ b/lib/pages/splash/splash.dart @@ -16,7 +16,7 @@ class _SplashState extends State { Future.delayed( const Duration(seconds: 2), () => Navigator.of(context).pushReplacementNamed( - Routes.authenticaion, + Routes.home, ), ); super.initState(); diff --git a/lib/routes/route_generator.dart b/lib/routes/route_generator.dart index f55e042..2b5479f 100644 --- a/lib/routes/route_generator.dart +++ b/lib/routes/route_generator.dart @@ -1,5 +1,7 @@ import 'package:didvan/pages/authentication/authentication.dart'; import 'package:didvan/pages/authentication/authentication_state.dart'; +import 'package:didvan/pages/home/home.dart'; +import 'package:didvan/pages/home/home_state.dart'; import 'package:didvan/pages/splash/splash.dart'; import 'package:didvan/pages/splash/splash_state.dart'; import 'package:didvan/routes/routes.dart'; @@ -11,18 +13,25 @@ class RouteGenerator { switch (settings.name) { case Routes.splash: return _materialPageRouteGenerator( - ChangeNotifierProvider( + ChangeNotifierProvider( create: (context) => SplashState(), child: const Splash(), ), ); case Routes.authenticaion: return _materialPageRouteGenerator( - ChangeNotifierProvider( + ChangeNotifierProvider( create: (context) => AuthenticationState(), child: const Authentication(), ), ); + case Routes.home: + return _materialPageRouteGenerator( + ChangeNotifierProvider( + create: (context) => HomeState(), + child: const Home(), + ), + ); default: return _errorRoute(); } diff --git a/lib/widgets/animated_visibility.dart b/lib/widgets/animated_visibility.dart new file mode 100644 index 0000000..a6f3c12 --- /dev/null +++ b/lib/widgets/animated_visibility.dart @@ -0,0 +1,90 @@ +library animated_visibility; + +import 'package:flutter/material.dart'; + +enum FadeMode { + vertical, + horizontal, + both, +} + +class AnimatedVisibility extends StatefulWidget { + final bool isVisible; + final Duration duration; + final Widget child; + final Curve curve; + final FadeMode fadeMode; + + const AnimatedVisibility({ + Key? key, + required this.isVisible, + required this.duration, + required this.child, + this.fadeMode = FadeMode.both, + this.curve = Curves.easeIn, + }) : super(key: key); + + @override + _AnimatedVisibilityState createState() => _AnimatedVisibilityState(); +} + +class _AnimatedVisibilityState extends State + with SingleTickerProviderStateMixin { + late final AnimationController _sizeController; + late final Animation _animation; + + @override + void initState() { + super.initState(); + _setupAnimation(); + _runSizeCheck(); + } + + void _setupAnimation() { + _sizeController = + AnimationController(vsync: this, duration: widget.duration); + _animation = CurvedAnimation( + parent: _sizeController, + curve: widget.curve, + ); + } + + @override + void didUpdateWidget(covariant AnimatedVisibility oldWidget) { + _runSizeCheck(); + super.didUpdateWidget(oldWidget); + } + + void _runSizeCheck() { + if (widget.isVisible) { + _sizeController.forward(); + } else { + _sizeController.reverse(); + } + } + + @override + void dispose() { + _sizeController.dispose(); + super.dispose(); + } + + bool get _isVertical => + widget.fadeMode == FadeMode.vertical || widget.fadeMode == FadeMode.both; + bool get _isHorizontal => + widget.fadeMode == FadeMode.horizontal || + widget.fadeMode == FadeMode.both; + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: _animation, + child: widget.child, + builder: (context, child) => Align( + heightFactor: _isVertical ? _animation.value : null, + widthFactor: _isHorizontal ? _animation.value : null, + child: Opacity(opacity: _animation.value, child: child), + ), + ); + } +} diff --git a/lib/widgets/didvan/text.dart b/lib/widgets/didvan/text.dart index 0b05d6e..2192f4d 100644 --- a/lib/widgets/didvan/text.dart +++ b/lib/widgets/didvan/text.dart @@ -7,6 +7,7 @@ class DidvanText extends StatelessWidget { final Color? color; final FontWeight? fontWeight; final double? fontSize; + final TextAlign textAlign; const DidvanText( this.text, { @@ -15,6 +16,7 @@ class DidvanText extends StatelessWidget { this.color, this.fontSize, this.fontWeight, + this.textAlign = TextAlign.right, }) : super(key: key); @override @@ -26,6 +28,7 @@ class DidvanText extends StatelessWidget { fontWeight: fontWeight, fontSize: fontSize, ), + textAlign: textAlign, ); } } diff --git a/lib/widgets/didvan/text_field.dart b/lib/widgets/didvan/text_field.dart index 02e141e..9580aac 100644 --- a/lib/widgets/didvan/text_field.dart +++ b/lib/widgets/didvan/text_field.dart @@ -133,5 +133,7 @@ class _DidvanTextFieldState extends State { } } - String? _validator(String? value) {} + String? _validator(String? value) { + _hasError = false; + } } diff --git a/lib/widgets/ink_wrapper.dart b/lib/widgets/ink_wrapper.dart new file mode 100644 index 0000000..547709d --- /dev/null +++ b/lib/widgets/ink_wrapper.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; + +class InkWrapper extends StatelessWidget { + final Color? splashColor; + final Color? highlightColor; + final Widget child; + final VoidCallback? onPressed; + final BorderRadius? borderRadius; + + const InkWrapper({ + Key? key, + this.splashColor, + this.highlightColor, + required this.child, + this.onPressed, + this.borderRadius, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + child, + Positioned.fill( + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: borderRadius, + splashColor: splashColor, + highlightColor: highlightColor, + onTap: onPressed, + ), + ), + ), + ], + ); + } +} diff --git a/lib/widgets/logos/didvan_vertical_logo.dart b/lib/widgets/logos/didvan_vertical_logo.dart index e69de29..19e640e 100644 --- a/lib/widgets/logos/didvan_vertical_logo.dart +++ b/lib/widgets/logos/didvan_vertical_logo.dart @@ -0,0 +1,11 @@ +import 'package:didvan/constants/assets.dart'; +import 'package:flutter/material.dart'; + +class DidvanHorizontalLogo extends StatelessWidget { + const DidvanHorizontalLogo({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Image.asset(Assets.horizontalLogoWithText); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 9e56d39..596b680 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -64,8 +64,15 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - - lib/assets/images/logo/logo-v-t.png - - lib/assets/images/logo/logo-h-t.png + - lib/assets/images/logos/logo-v-t.png + - lib/assets/images/logos/logo-h-t.png + - lib/assets/images/categories/business.png + - lib/assets/images/categories/economic.png + - lib/assets/images/categories/enviromental.png + - lib/assets/images/categories/political.png + - lib/assets/images/categories/social.png + - lib/assets/images/categories/tech.png + - lib/assets/animations/indicator.riv - lib/assets/animations/indicator.riv