D1APP-24 home page (static)
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 124 KiB |
|
|
@ -60,9 +60,28 @@ class DesignConfig {
|
||||||
static const BorderRadius lowBorderRadius = BorderRadius.all(
|
static const BorderRadius lowBorderRadius = BorderRadius.all(
|
||||||
Radius.circular(8),
|
Radius.circular(8),
|
||||||
);
|
);
|
||||||
|
static const BorderRadius mediumBorderRadius = BorderRadius.all(
|
||||||
|
Radius.circular(10),
|
||||||
|
);
|
||||||
|
static const BorderRadius highBorderRadius = BorderRadius.all(
|
||||||
|
Radius.circular(16),
|
||||||
|
);
|
||||||
static final Border lightBorder = Border.all(color: DesignConfig.greyColor4);
|
static final Border lightBorder = Border.all(color: DesignConfig.greyColor4);
|
||||||
|
static final BoxDecoration actionCardDecoration = BoxDecoration(
|
||||||
|
color: lightPrimaryColor3,
|
||||||
|
boxShadow: defaultShadow,
|
||||||
|
borderRadius: mediumBorderRadius,
|
||||||
|
);
|
||||||
|
static final List<BoxShadow> 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(
|
static final SystemUiOverlayStyle systemUIOverlayStyle = SystemUiOverlayStyle(
|
||||||
statusBarBrightness: Brightness.dark,
|
statusBarBrightness: Brightness.dark,
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,21 @@ class Assets {
|
||||||
static const String _baseAnimationsPath = _basePath + '/animations';
|
static const String _baseAnimationsPath = _basePath + '/animations';
|
||||||
|
|
||||||
static const String verticalLogoWithText =
|
static const String verticalLogoWithText =
|
||||||
_baseImagesPath + '/logo/logo-v-t.png';
|
_baseImagesPath + '/logos/logo-v-t.png';
|
||||||
static const String horizontalLogoWithText =
|
static const String horizontalLogoWithText =
|
||||||
_baseImagesPath + '/logo/logo-h-t.png';
|
_baseImagesPath + '/logos/logo-h-t.png';
|
||||||
|
|
||||||
static const String logoLoadingAnimation =
|
static const String logoLoadingAnimation =
|
||||||
_baseAnimationsPath + '/indicator.riv';
|
_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';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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});
|
||||||
|
}
|
||||||
|
|
@ -27,7 +27,7 @@ class _AuthenticationState extends State<Authentication> {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Consumer<AuthenticationState>(
|
body: Consumer<AuthenticationState>(
|
||||||
builder: (context, state, child) => AnimatedSwitcher(
|
builder: (context, state, child) => AnimatedSwitcher(
|
||||||
duration: DesignConfig.defaultAppDuration,
|
duration: DesignConfig.defaultAnimationDuration,
|
||||||
child: _pages[state.currentPageIndex],
|
child: _pages[state.currentPageIndex],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -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<Home> createState() => _HomeState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HomeState extends State<Home> {
|
||||||
|
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),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<RadarCategory> 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,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -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<HomeState>()
|
||||||
|
.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<HomeState>()
|
||||||
|
.categories
|
||||||
|
.sublist(3, 6)
|
||||||
|
.map(
|
||||||
|
(category) => Expanded(
|
||||||
|
child: CategoryItem(
|
||||||
|
title: category.title,
|
||||||
|
asset: category.asset,
|
||||||
|
isColapsed: isColapsed,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<HomeState>();
|
||||||
|
final List<RadarCategory> 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,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,7 @@ class _SplashState extends State<Splash> {
|
||||||
Future.delayed(
|
Future.delayed(
|
||||||
const Duration(seconds: 2),
|
const Duration(seconds: 2),
|
||||||
() => Navigator.of(context).pushReplacementNamed(
|
() => Navigator.of(context).pushReplacementNamed(
|
||||||
Routes.authenticaion,
|
Routes.home,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import 'package:didvan/pages/authentication/authentication.dart';
|
import 'package:didvan/pages/authentication/authentication.dart';
|
||||||
import 'package:didvan/pages/authentication/authentication_state.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.dart';
|
||||||
import 'package:didvan/pages/splash/splash_state.dart';
|
import 'package:didvan/pages/splash/splash_state.dart';
|
||||||
import 'package:didvan/routes/routes.dart';
|
import 'package:didvan/routes/routes.dart';
|
||||||
|
|
@ -11,18 +13,25 @@ class RouteGenerator {
|
||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
case Routes.splash:
|
case Routes.splash:
|
||||||
return _materialPageRouteGenerator(
|
return _materialPageRouteGenerator(
|
||||||
ChangeNotifierProvider(
|
ChangeNotifierProvider<SplashState>(
|
||||||
create: (context) => SplashState(),
|
create: (context) => SplashState(),
|
||||||
child: const Splash(),
|
child: const Splash(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
case Routes.authenticaion:
|
case Routes.authenticaion:
|
||||||
return _materialPageRouteGenerator(
|
return _materialPageRouteGenerator(
|
||||||
ChangeNotifierProvider(
|
ChangeNotifierProvider<AuthenticationState>(
|
||||||
create: (context) => AuthenticationState(),
|
create: (context) => AuthenticationState(),
|
||||||
child: const Authentication(),
|
child: const Authentication(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
case Routes.home:
|
||||||
|
return _materialPageRouteGenerator(
|
||||||
|
ChangeNotifierProvider<HomeState>(
|
||||||
|
create: (context) => HomeState(),
|
||||||
|
child: const Home(),
|
||||||
|
),
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return _errorRoute();
|
return _errorRoute();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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<AnimatedVisibility>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
late final AnimationController _sizeController;
|
||||||
|
late final Animation<double> _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),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ class DidvanText extends StatelessWidget {
|
||||||
final Color? color;
|
final Color? color;
|
||||||
final FontWeight? fontWeight;
|
final FontWeight? fontWeight;
|
||||||
final double? fontSize;
|
final double? fontSize;
|
||||||
|
final TextAlign textAlign;
|
||||||
|
|
||||||
const DidvanText(
|
const DidvanText(
|
||||||
this.text, {
|
this.text, {
|
||||||
|
|
@ -15,6 +16,7 @@ class DidvanText extends StatelessWidget {
|
||||||
this.color,
|
this.color,
|
||||||
this.fontSize,
|
this.fontSize,
|
||||||
this.fontWeight,
|
this.fontWeight,
|
||||||
|
this.textAlign = TextAlign.right,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -26,6 +28,7 @@ class DidvanText extends StatelessWidget {
|
||||||
fontWeight: fontWeight,
|
fontWeight: fontWeight,
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
),
|
),
|
||||||
|
textAlign: textAlign,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,5 +133,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String? _validator(String? value) {}
|
String? _validator(String? value) {
|
||||||
|
_hasError = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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: <Widget>[
|
||||||
|
child,
|
||||||
|
Positioned.fill(
|
||||||
|
child: Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
splashColor: splashColor,
|
||||||
|
highlightColor: highlightColor,
|
||||||
|
onTap: onPressed,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
pubspec.yaml
|
|
@ -64,8 +64,15 @@ flutter:
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
assets:
|
assets:
|
||||||
- lib/assets/images/logo/logo-v-t.png
|
- lib/assets/images/logos/logo-v-t.png
|
||||||
- lib/assets/images/logo/logo-h-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
|
- lib/assets/animations/indicator.riv
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||