component updates
This commit is contained in:
parent
a6607fd5af
commit
61aea52161
|
|
@ -29,6 +29,7 @@ class _UsernameInputState extends State<UsernameInput> {
|
|||
title: 'نام کاربری یا شماره موبایل',
|
||||
hintText: 'نام کاربری یا شماره موبایل',
|
||||
textAlign: TextAlign.center,
|
||||
acceptSpace: false,
|
||||
onSubmitted: (value) => state.confirmUsername(),
|
||||
validator: (value) {
|
||||
if (value.contains(' ')) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/pages/authentication/authentication_state.dart';
|
||||
import 'package:didvan/widgets/didvan/icon_button.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
|
|
@ -15,7 +16,7 @@ class AuthenticationAppBar extends StatelessWidget {
|
|||
return Row(
|
||||
children: [
|
||||
DidvanIconButton(
|
||||
icon: Icons.arrow_back,
|
||||
icon: DidvanIcons.back_regular,
|
||||
onPressed: () {
|
||||
if (state.currentPageIndex == 0) {
|
||||
Navigator.of(context).pop();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/widgets/didvan/icon_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BookmarkButton extends StatefulWidget {
|
||||
final bool value;
|
||||
final VoidCallback onMark;
|
||||
final VoidCallback onUnmark;
|
||||
const BookmarkButton(
|
||||
{Key? key,
|
||||
required this.value,
|
||||
required this.onMark,
|
||||
required this.onUnmark})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<BookmarkButton> createState() => _BookmarkButtonState();
|
||||
}
|
||||
|
||||
class _BookmarkButtonState extends State<BookmarkButton> {
|
||||
bool _value = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_value = widget.value;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DidvanIconButton(
|
||||
gestureSize: 24,
|
||||
icon: _value ? DidvanIcons.bookmark_solid : DidvanIcons.bookmark_regular,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_value = !_value;
|
||||
});
|
||||
_value ? widget.onMark() : widget.onUnmark();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/models/view/app_bar_data.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -16,7 +17,7 @@ class DidvanAppBar extends StatelessWidget {
|
|||
IconButton(
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
color: Theme.of(context).colorScheme.title,
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
icon: const Icon(DidvanIcons.back_regular),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
|
|
|
|||
|
|
@ -5,8 +5,15 @@ import 'package:flutter/material.dart';
|
|||
class DidvanPageView extends StatelessWidget {
|
||||
final List<Widget> pages;
|
||||
final ScrollController? scrollController;
|
||||
const DidvanPageView({Key? key, required this.pages, this.scrollController})
|
||||
: super(key: key);
|
||||
final int initialPage;
|
||||
final void Function(int index) onPageChanged;
|
||||
const DidvanPageView({
|
||||
Key? key,
|
||||
required this.pages,
|
||||
this.scrollController,
|
||||
required this.onPageChanged,
|
||||
this.initialPage = 2,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -14,6 +21,7 @@ class DidvanPageView extends StatelessWidget {
|
|||
return CarouselSlider.builder(
|
||||
itemCount: pages.length,
|
||||
options: CarouselOptions(
|
||||
onPageChanged: (index, reason) => onPageChanged(index),
|
||||
height: double.infinity,
|
||||
initialPage: 2,
|
||||
viewportFraction: 0.94,
|
||||
|
|
@ -22,7 +30,7 @@ class DidvanPageView extends StatelessWidget {
|
|||
itemBuilder: (context, index, realIndex) => SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: SingleChildScrollView(
|
||||
controller: scrollController,
|
||||
controller: index == 2 ? scrollController : null,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: EdgeInsets.only(
|
||||
left: 4,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'package:didvan/constants/app_icons.dart';
|
|||
import 'package:didvan/widgets/animated_visibility.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:persian_number_utility/persian_number_utility.dart';
|
||||
|
||||
class DidvanTextField extends StatefulWidget {
|
||||
|
|
@ -16,6 +17,7 @@ class DidvanTextField extends StatefulWidget {
|
|||
final String? hintText;
|
||||
final dynamic initialValue;
|
||||
final bool obsecureText;
|
||||
final bool acceptSpace;
|
||||
final Function(String value)? validator;
|
||||
final TextInputType? textInputType;
|
||||
const DidvanTextField({
|
||||
|
|
@ -31,6 +33,7 @@ class DidvanTextField extends StatefulWidget {
|
|||
this.obsecureText = false,
|
||||
this.autoFocus = false,
|
||||
this.onSubmitted,
|
||||
this.acceptSpace = true,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -79,6 +82,10 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
|
|||
border: Border.all(color: _borderColor()),
|
||||
),
|
||||
child: TextFormField(
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
if (!widget.acceptSpace)
|
||||
FilteringTextInputFormatter.allow(RegExp("[0-9a-zA-Z]")),
|
||||
],
|
||||
autofocus: widget.autoFocus,
|
||||
obscureText: _hideContent,
|
||||
textAlign: widget.textAlign,
|
||||
|
|
@ -89,7 +96,10 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
|
|||
onChanged: _onChanged,
|
||||
validator: _validator,
|
||||
obscuringCharacter: '*',
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText2!
|
||||
.copyWith(fontFamily: 'Dana'),
|
||||
decoration: InputDecoration(
|
||||
suffixIcon: _suffixBuilder(),
|
||||
enabled: widget.enabled,
|
||||
|
|
@ -181,9 +191,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
|
|||
_error = null;
|
||||
});
|
||||
value = value.toEnglishDigit();
|
||||
if (widget.onChanged != null) {
|
||||
widget.onChanged!(value);
|
||||
}
|
||||
widget.onChanged?.call(value);
|
||||
}
|
||||
|
||||
String? _validator(String? value) {
|
||||
|
|
@ -193,6 +201,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
|
|||
setState(() {
|
||||
_error = error;
|
||||
});
|
||||
return '';
|
||||
} else {
|
||||
setState(() {
|
||||
_error = null;
|
||||
|
|
@ -200,4 +209,10 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@ 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/models/view/action_sheet_data.dart';
|
||||
import 'package:didvan/pages/home/profile/widgets/menu_item.dart';
|
||||
import 'package:didvan/routes/routes.dart';
|
||||
import 'package:didvan/utils/action_sheet.dart';
|
||||
import 'package:didvan/widgets/bookmark_button.dart';
|
||||
import 'package:didvan/widgets/didvan/divider.dart';
|
||||
import 'package:didvan/widgets/didvan/icon_button.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -11,13 +17,15 @@ class FloatingNavigationBar extends StatefulWidget {
|
|||
final RadarDetailsData? radar;
|
||||
final NewsDetailsData? news;
|
||||
final ScrollController scrollController;
|
||||
final VoidCallback bookmarkCallback;
|
||||
final VoidCallback onMark;
|
||||
final VoidCallback onUnmark;
|
||||
const FloatingNavigationBar({
|
||||
Key? key,
|
||||
this.radar,
|
||||
this.news,
|
||||
required this.scrollController,
|
||||
required this.bookmarkCallback,
|
||||
required this.onMark,
|
||||
required this.onUnmark,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -25,8 +33,6 @@ class FloatingNavigationBar extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
||||
bool _isMarked = false;
|
||||
|
||||
bool get _isRadar => widget.radar != null;
|
||||
bool _isScrolled = false;
|
||||
|
||||
|
|
@ -34,7 +40,6 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
_isMarked = _item.marked;
|
||||
widget.scrollController.addListener(() {
|
||||
final position = widget.scrollController.position.pixels;
|
||||
if (position > 300 && !_isScrolled) {
|
||||
|
|
@ -57,9 +62,9 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
|||
: Theme.of(context).colorScheme.focused;
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(left: 32, right: 32, bottom: 20),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
width: double.infinity,
|
||||
height: 48,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.navigation,
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
|
|
@ -75,7 +80,7 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
|||
),
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(
|
||||
DidvanIconButton(
|
||||
onPressed: () {
|
||||
if (_isScrolled) {
|
||||
widget.scrollController.animateTo(
|
||||
|
|
@ -87,63 +92,86 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
|||
}
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
icon: Icon(
|
||||
_isScrolled ? Icons.arrow_upward : Icons.arrow_back,
|
||||
),
|
||||
icon: _isScrolled
|
||||
? DidvanIcons.arrow_up_regular
|
||||
: DidvanIcons.back_regular,
|
||||
),
|
||||
const Spacer(),
|
||||
if (_isRadar)
|
||||
DidvanIconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_isMarked = !_isMarked;
|
||||
});
|
||||
widget.bookmarkCallback();
|
||||
},
|
||||
icon: _isMarked
|
||||
? DidvanIcons.bookmark_solid
|
||||
: DidvanIcons.bookmark_regular,
|
||||
),
|
||||
if (_isRadar)
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: const Icon(
|
||||
DidvanIcons.evaluation_regular,
|
||||
),
|
||||
BookmarkButton(
|
||||
value: _item.marked,
|
||||
onMark: widget.onMark,
|
||||
onUnmark: widget.onUnmark,
|
||||
),
|
||||
// if (_isRadar)
|
||||
// IconButton(
|
||||
// onPressed: () {},
|
||||
// icon: const Icon(
|
||||
// DidvanIcons.evaluation_regular,
|
||||
// ),
|
||||
// ),
|
||||
SizedBox(
|
||||
width: 48,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
DidvanText(
|
||||
'2',
|
||||
color: foregroundColor,
|
||||
),
|
||||
if (_item.comments != 0)
|
||||
DidvanText(
|
||||
_item.comments.toString(),
|
||||
color: foregroundColor,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
const Icon(
|
||||
DidvanIcons.chats_regular,
|
||||
DidvanIconButton(
|
||||
gestureSize: 32,
|
||||
onPressed: () => Navigator.of(context).pushNamed(
|
||||
Routes.comments,
|
||||
arguments: {'id': _item.id, 'isRadar': _isRadar},
|
||||
),
|
||||
icon: DidvanIcons.chats_regular,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (!_isRadar) const SizedBox(width: 12),
|
||||
if (!_isRadar)
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: const Icon(
|
||||
DidvanIcons.bookmark_regular,
|
||||
),
|
||||
BookmarkButton(
|
||||
value: _item.marked,
|
||||
onMark: widget.onMark,
|
||||
onUnmark: widget.onUnmark,
|
||||
),
|
||||
if (_isRadar)
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: const Icon(
|
||||
Icons.more_horiz,
|
||||
),
|
||||
DidvanIconButton(
|
||||
gestureSize: 32,
|
||||
onPressed: _showMoreOptions,
|
||||
icon: DidvanIcons.menu_regular,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showMoreOptions() {
|
||||
ActionSheetUtils.showBottomSheet(
|
||||
data: ActionSheetData(
|
||||
content: Column(
|
||||
children: [
|
||||
MenuItem(
|
||||
title: 'ارتباط با سردبیر',
|
||||
onTap: () {},
|
||||
icon: DidvanIcons.profile_regular,
|
||||
),
|
||||
const DidvanDivider(),
|
||||
MenuItem(
|
||||
title: 'گزارش اشکال',
|
||||
onTap: () {},
|
||||
icon: DidvanIcons.description_regular,
|
||||
),
|
||||
],
|
||||
),
|
||||
title: 'موارد بیشتر',
|
||||
withoutButtonMode: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class _SearchFieldState extends State<SearchField> {
|
|||
decoration: BoxDecoration(
|
||||
color: _fillColor(),
|
||||
),
|
||||
child: TextField(
|
||||
child: TextFormField(
|
||||
focusNode: _focusNode,
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
textAlignVertical: TextAlignVertical.center,
|
||||
|
|
@ -122,4 +122,10 @@ class _SearchFieldState extends State<SearchField> {
|
|||
}
|
||||
return Theme.of(context).colorScheme.surface;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:didvan/services/storage/storage.dart';
|
||||
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 StatefulWidget {
|
||||
final String imageUrl;
|
||||
final double width;
|
||||
final double height;
|
||||
final BorderRadius? borderRadius;
|
||||
final double? aspectRatio;
|
||||
const SkeletonImage({
|
||||
Key? key,
|
||||
required this.imageUrl,
|
||||
this.width = 300,
|
||||
this.height = 140,
|
||||
this.borderRadius = DesignConfig.lowBorderRadius,
|
||||
this.aspectRatio,
|
||||
}) : 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 {
|
||||
final url = RequestHelper.baseUrl + widget.imageUrl;
|
||||
final storage = StorageService.webStorage;
|
||||
String? imageCache = storage['image-cache'];
|
||||
final Map data = imageCache == null ? {} : jsonDecode(imageCache);
|
||||
if (data.containsKey(url)) {
|
||||
_bytes = Uint8List.fromList(
|
||||
List<int>.from(data[url]),
|
||||
);
|
||||
} else {
|
||||
_bytes = (await http.get(
|
||||
Uri.parse(url),
|
||||
headers: {'Authorization': 'Bearer ${RequestService.token}'},
|
||||
))
|
||||
.bodyBytes;
|
||||
addImageToStorage();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
void addImageToStorage() {
|
||||
final storage = StorageService.webStorage;
|
||||
String? imageCache = storage['image-cache'];
|
||||
final Map data = imageCache == null ? {} : Map.from(jsonDecode(imageCache));
|
||||
data.addAll({RequestHelper.baseUrl + widget.imageUrl: _bytes});
|
||||
StorageService.webStorage.addAll({'image-cache': jsonEncode(data)});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return _aspectRatioGenerator(
|
||||
child: Builder(builder: (context) {
|
||||
if (kIsWeb) {
|
||||
return Builder(
|
||||
builder: (context) {
|
||||
if (_bytes == null || _bytes!.isEmpty) {
|
||||
return ShimmerPlaceholder(
|
||||
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: widget.width,
|
||||
height: widget.height,
|
||||
imageUrl: RequestHelper.baseUrl + widget.imageUrl,
|
||||
imageBuilder: (context, imageProvider) => Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: widget.borderRadius ?? DesignConfig.lowBorderRadius,
|
||||
image: DecorationImage(
|
||||
image: imageProvider,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
progressIndicatorBuilder: (context, url, progress) =>
|
||||
SkeletonAnimation(
|
||||
shimmerColor: Theme.of(context).colorScheme.border,
|
||||
borderRadius: widget.borderRadius ?? DesignConfig.lowBorderRadius,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.disabledBackground,
|
||||
borderRadius: widget.borderRadius,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _aspectRatioGenerator({required Widget child}) =>
|
||||
widget.aspectRatio == null
|
||||
? SizedBox(child: child)
|
||||
: AspectRatio(
|
||||
aspectRatio: widget.aspectRatio!,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
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 StatefulWidget {
|
||||
final String imageUrl;
|
||||
final double width;
|
||||
final double height;
|
||||
final BorderRadius? borderRadius;
|
||||
const SkeletonImage({
|
||||
Key? key,
|
||||
required this.imageUrl,
|
||||
required this.width,
|
||||
required this.height,
|
||||
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: widget.width,
|
||||
height: widget.height,
|
||||
imageUrl: RequestHelper.baseUrl + widget.imageUrl,
|
||||
imageBuilder: (context, imageProvider) => Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: widget.borderRadius ?? DesignConfig.lowBorderRadius,
|
||||
image: DecorationImage(
|
||||
image: imageProvider,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
progressIndicatorBuilder: (context, url, progress) => SkeletonAnimation(
|
||||
shimmerColor: Theme.of(context).colorScheme.border,
|
||||
borderRadius: widget.borderRadius ?? DesignConfig.lowBorderRadius,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.disabledBackground,
|
||||
borderRadius: widget.borderRadius,
|
||||
),
|
||||
height: widget.height,
|
||||
width: widget.width,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue