component updates

This commit is contained in:
MohammadTaha Basiri 2022-01-15 15:57:21 +03:30
parent ca88dd1caf
commit 09eb21841a
8 changed files with 172 additions and 53 deletions

View File

@ -49,7 +49,7 @@ class _AudioVisualizerState extends State<AudioVisualizer> {
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).brightness == Brightness.dark
color: DesignConfig.isDark
? Theme.of(context).colorScheme.black
: Theme.of(context).colorScheme.background,
borderRadius: DesignConfig.mediumBorderRadius,

View File

@ -31,8 +31,13 @@ class DidvanButton extends StatelessWidget {
foregroundColor = Theme.of(context).colorScheme.text;
break;
case ButtonStyleMode.flat:
if (DesignConfig.isDark) {
backgroundColor = Theme.of(context).colorScheme.surface;
foregroundColor = Theme.of(context).colorScheme.white;
} else {
backgroundColor = Theme.of(context).colorScheme.surface;
foregroundColor = Theme.of(context).colorScheme.primary;
}
break;
default:
}

View File

@ -4,13 +4,15 @@ import 'package:flutter/material.dart';
class DidvanPageView extends StatelessWidget {
final List<Widget> pages;
const DidvanPageView({Key? key, required this.pages}) : super(key: key);
final ScrollController? scrollController;
const DidvanPageView({Key? key, required this.pages, this.scrollController})
: super(key: key);
@override
Widget build(BuildContext context) {
final double deviceTopPadding = MediaQuery.of(context).padding.top;
return CarouselSlider.builder(
itemCount: 5,
itemCount: pages.length,
options: CarouselOptions(
height: double.infinity,
initialPage: 2,
@ -20,16 +22,18 @@ class DidvanPageView extends StatelessWidget {
itemBuilder: (context, index, realIndex) => SizedBox(
height: MediaQuery.of(context).size.height,
child: SingleChildScrollView(
controller: scrollController,
physics: const BouncingScrollPhysics(),
padding: EdgeInsets.only(
left: 4,
right: 4,
top: 16 + deviceTopPadding,
bottom: 92,
),
child: DidvanCard(
padding: EdgeInsets.zero,
enableBorder: false,
child: pages[0],
child: pages[index],
),
),
),

View File

@ -8,6 +8,7 @@ import 'package:persian_number_utility/persian_number_utility.dart';
class DidvanTextField extends StatefulWidget {
final void Function(String value)? onChanged;
final void Function(String value)? onSubmitted;
final bool enabled;
final bool autoFocus;
final TextAlign textAlign;
@ -29,6 +30,7 @@ class DidvanTextField extends StatefulWidget {
this.textAlign = TextAlign.right,
this.obsecureText = false,
this.autoFocus = false,
this.onSubmitted,
}) : super(key: key);
@override
@ -83,10 +85,9 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
keyboardType: widget.textInputType,
focusNode: _focusNode,
controller: _controller,
onFieldSubmitted: widget.onSubmitted,
onChanged: _onChanged,
validator: (value) {
_validator(value);
},
validator: _validator,
obscuringCharacter: '*',
style: Theme.of(context).textTheme.bodyText1,
decoration: InputDecoration(
@ -144,7 +145,9 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
Color _fillColor() {
if (!widget.enabled) {
return Theme.of(context).colorScheme.disabledBackground;
return DesignConfig.isDark
? Theme.of(context).colorScheme.disabledBackground
: Theme.of(context).colorScheme.secondCTA;
}
if (_focusNode.hasFocus) {
return Theme.of(context).colorScheme.focused;
@ -183,14 +186,13 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
}
}
Future<String?> _validator(String? value) async {
String? _validator(String? value) {
if (widget.validator != null) {
final String? error = await widget.validator!(value!);
final String? error = widget.validator!(value!);
if (error != null) {
setState(() {
_error = error;
});
return '';
} else {
setState(() {
_error = null;

View File

@ -1,17 +1,58 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/news_details_data.dart';
import 'package:didvan/models/radar_details_data.dart';
import 'package:didvan/widgets/didvan/icon_button.dart';
import 'package:didvan/widgets/didvan/text.dart';
import 'package:flutter/material.dart';
class FloatingNavigationBar extends StatelessWidget {
final bool isRadar;
const FloatingNavigationBar({Key? key, required this.isRadar})
: super(key: key);
class FloatingNavigationBar extends StatefulWidget {
final RadarDetailsData? radar;
final NewsDetailsData? news;
final ScrollController scrollController;
final VoidCallback bookmarkCallback;
const FloatingNavigationBar({
Key? key,
this.radar,
this.news,
required this.scrollController,
required this.bookmarkCallback,
}) : super(key: key);
@override
State<FloatingNavigationBar> createState() => _FloatingNavigationBarState();
}
class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
bool _isMarked = false;
bool get _isRadar => widget.radar != null;
bool _isScrolled = false;
get _item => widget.radar ?? widget.news;
@override
void initState() {
_isMarked = _item.marked;
widget.scrollController.addListener(() {
final position = widget.scrollController.position.pixels;
if (position > 300 && !_isScrolled) {
setState(() {
_isScrolled = true;
});
} else if (position < 300 && _isScrolled) {
setState(() {
_isScrolled = false;
});
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
final Color foregroundColor =
Theme.of(context).brightness == Brightness.dark
final Color foregroundColor = DesignConfig.isDark
? Theme.of(context).colorScheme.focusedBorder
: Theme.of(context).colorScheme.focused;
return Container(
@ -35,20 +76,35 @@ class FloatingNavigationBar extends StatelessWidget {
child: Row(
children: [
IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(
Icons.arrow_back,
onPressed: () {
if (_isScrolled) {
widget.scrollController.animateTo(
0,
duration: DesignConfig.lowAnimationDuration,
curve: Curves.easeIn,
);
return;
}
Navigator.of(context).pop();
},
icon: Icon(
_isScrolled ? Icons.arrow_upward : Icons.arrow_back,
),
),
const Spacer(),
if (isRadar)
IconButton(
onPressed: () {},
icon: const Icon(
DidvanIcons.bookmark_regular,
if (_isRadar)
DidvanIconButton(
onPressed: () {
setState(() {
_isMarked = !_isMarked;
});
widget.bookmarkCallback();
},
icon: _isMarked
? DidvanIcons.bookmark_solid
: DidvanIcons.bookmark_regular,
),
),
if (isRadar)
if (_isRadar)
IconButton(
onPressed: () {},
icon: const Icon(
@ -66,19 +122,19 @@ class FloatingNavigationBar extends StatelessWidget {
),
const SizedBox(width: 4),
const Icon(
DidvanIcons.directs_regular,
DidvanIcons.chats_regular,
),
],
),
),
if (!isRadar)
if (!_isRadar)
IconButton(
onPressed: () {},
icon: const Icon(
DidvanIcons.bookmark_regular,
),
),
if (isRadar)
if (_isRadar)
IconButton(
onPressed: () {},
icon: const Icon(

View File

@ -6,7 +6,7 @@ import 'package:skeleton_text/skeleton_text.dart';
class ShimmerPlaceholder extends StatelessWidget {
final double? height;
final double? width;
final BorderRadius borderRadius;
final BorderRadius? borderRadius;
const ShimmerPlaceholder({
Key? key,
@ -18,14 +18,16 @@ class ShimmerPlaceholder extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SkeletonAnimation(
borderRadius: borderRadius,
borderRadius: borderRadius!,
shimmerColor: Theme.of(context).colorScheme.secondCTA,
gradientColor: Theme.of(context).colorScheme.cardBorder,
child: Container(
height: height,
width: width,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.disabledBackground,
color: DesignConfig.isDark
? Theme.of(context).colorScheme.focused
: Theme.of(context).colorScheme.disabledBackground,
borderRadius: borderRadius,
),
),

View File

@ -1,11 +1,17 @@
import 'dart:typed_data';
import 'package:didvan/widgets/shimmer_placeholder.dart';
import 'package:http/http.dart' as http;
import 'package:cached_network_image/cached_network_image.dart';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:skeleton_text/skeleton_text.dart';
class SkeletonImage extends StatelessWidget {
class SkeletonImage extends StatefulWidget {
final String imageUrl;
final double width;
final double height;
@ -15,19 +21,61 @@ class SkeletonImage extends StatelessWidget {
required this.imageUrl,
required this.width,
required this.height,
this.borderRadius,
this.borderRadius = DesignConfig.lowBorderRadius,
}) : super(key: key);
@override
State<SkeletonImage> createState() => _SkeletonImageState();
}
class _SkeletonImageState extends State<SkeletonImage> {
Uint8List? _bytes;
@override
void initState() {
if (kIsWeb) _getImage();
super.initState();
}
Future<void> _getImage() async {
_bytes = (await http.get(
Uri.parse(RequestHelper.baseUrl + widget.imageUrl),
headers: {'Authorization': 'Bearer ${RequestService.token}'},
))
.bodyBytes;
if (mounted) {
setState(() {});
}
}
@override
Widget build(BuildContext context) {
if (kIsWeb) {
if (_bytes == null || _bytes!.isEmpty) {
return ShimmerPlaceholder(
width: widget.width,
height: widget.height,
borderRadius: widget.borderRadius,
);
}
return ClipRRect(
borderRadius: widget.borderRadius,
child: Image.memory(
_bytes!,
width: widget.width,
height: widget.height,
fit: BoxFit.cover,
),
);
}
return CachedNetworkImage(
httpHeaders: {'Authorization': 'Bearer ${RequestService.token}'},
width: width,
height: height,
imageUrl: imageUrl,
width: widget.width,
height: widget.height,
imageUrl: RequestHelper.baseUrl + widget.imageUrl,
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
borderRadius: borderRadius ?? DesignConfig.lowBorderRadius,
borderRadius: widget.borderRadius ?? DesignConfig.lowBorderRadius,
image: DecorationImage(
image: imageProvider,
fit: BoxFit.cover,
@ -36,14 +84,14 @@ class SkeletonImage extends StatelessWidget {
),
progressIndicatorBuilder: (context, url, progress) => SkeletonAnimation(
shimmerColor: Theme.of(context).colorScheme.border,
borderRadius: borderRadius ?? DesignConfig.lowBorderRadius,
borderRadius: widget.borderRadius ?? DesignConfig.lowBorderRadius,
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.disabledBackground,
borderRadius: borderRadius,
borderRadius: widget.borderRadius,
),
height: height,
width: width,
height: widget.height,
width: widget.width,
),
),
);

View File

@ -1,26 +1,25 @@
import 'package:didvan/models/enums.dart';
import 'package:didvan/providers/core_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
class StateHandler<T extends CoreProvier> extends StatelessWidget {
final T state;
final Widget Function(BuildContext context, T state) builder;
final VoidCallback? onRefresh;
final bool enableCustomLoadingIndicator;
final Color? customLoadingIndicatorColor;
final bool enableEmptyState;
final Widget? placeholder;
final Widget? emptyState;
final double topPadding;
const StateHandler({
Key? key,
required this.builder,
this.emptyState,
this.enableCustomLoadingIndicator = false,
this.enableEmptyState = false,
this.onRefresh,
this.topPadding = 0,
this.customLoadingIndicatorColor,
required this.state,
this.placeholder,
}) : super(key: key);
@override
@ -38,9 +37,12 @@ class StateHandler<T extends CoreProvier> extends StatelessWidget {
case AppState.idle:
return builder(context, state);
case AppState.busy:
return const CircularProgressIndicator();
return placeholder ??
SpinKitSpinningLines(
color: Theme.of(context).colorScheme.primary,
);
case AppState.failed:
return enableCustomLoadingIndicator ? emptyState! : Container();
return Container();
default:
return Container();
}