component updates
This commit is contained in:
parent
17287f4b5f
commit
d29f6fa60e
|
|
@ -6,12 +6,14 @@ class BookmarkButton extends StatefulWidget {
|
|||
final bool value;
|
||||
final VoidCallback onMark;
|
||||
final VoidCallback onUnmark;
|
||||
const BookmarkButton(
|
||||
{Key? key,
|
||||
final bool bigGestureSize;
|
||||
const BookmarkButton({
|
||||
Key? key,
|
||||
required this.value,
|
||||
required this.onMark,
|
||||
required this.onUnmark})
|
||||
: super(key: key);
|
||||
required this.onUnmark,
|
||||
this.bigGestureSize = false,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<BookmarkButton> createState() => _BookmarkButtonState();
|
||||
|
|
@ -35,7 +37,7 @@ class _BookmarkButtonState extends State<BookmarkButton> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DidvanIconButton(
|
||||
gestureSize: 24,
|
||||
gestureSize: widget.bigGestureSize ? 32 : 24,
|
||||
icon: _value ? DidvanIcons.bookmark_solid : DidvanIcons.bookmark_regular,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
|
|
|
|||
|
|
@ -7,14 +7,18 @@ import 'package:flutter/material.dart';
|
|||
class DidvanButton extends StatelessWidget {
|
||||
final VoidCallback? onPressed;
|
||||
final String? title;
|
||||
final double? width;
|
||||
final ButtonStyleMode style;
|
||||
final bool enabled;
|
||||
final double? height;
|
||||
const DidvanButton({
|
||||
Key? key,
|
||||
this.onPressed,
|
||||
this.title,
|
||||
this.style = ButtonStyleMode.primary,
|
||||
this.enabled = true,
|
||||
this.width,
|
||||
this.height = 48,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -42,8 +46,8 @@ class DidvanButton extends StatelessWidget {
|
|||
default:
|
||||
}
|
||||
return SizedBox(
|
||||
height: 48,
|
||||
width: double.infinity,
|
||||
height: height,
|
||||
width: width ?? double.infinity,
|
||||
child: MaterialButton(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: DesignConfig.lowBorderRadius,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:didvan/widgets/ink_wrapper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DidvanChip extends StatelessWidget {
|
||||
final String label;
|
||||
final VoidCallback? onTap;
|
||||
const DidvanChip({
|
||||
Key? key,
|
||||
required this.label,
|
||||
this.onTap,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWrapper(
|
||||
borderRadius: DesignConfig.highBorderRadius,
|
||||
onPressed: onTap,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 8),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: DesignConfig.highBorderRadius,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
child: DidvanText(
|
||||
label,
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
color: Theme.of(context).colorScheme.white,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,19 @@
|
|||
import 'package:carousel_slider/carousel_slider.dart';
|
||||
import 'package:didvan/utils/date_time.dart';
|
||||
import 'package:didvan/widgets/didvan/card.dart';
|
||||
import 'package:didvan/widgets/didvan/divider.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:didvan/widgets/skeleton_image.dart';
|
||||
import 'package:didvan/widgets/tag_item.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
|
||||
class DidvanPageView extends StatefulWidget {
|
||||
final List items;
|
||||
final int initialIndex;
|
||||
final bool isRadar;
|
||||
final ScrollController? scrollController;
|
||||
|
||||
final void Function(int index) onPageChanged;
|
||||
const DidvanPageView({
|
||||
Key? key,
|
||||
|
|
@ -15,6 +21,7 @@ class DidvanPageView extends StatefulWidget {
|
|||
required this.items,
|
||||
this.scrollController,
|
||||
required this.onPageChanged,
|
||||
required this.isRadar,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -36,7 +43,9 @@ class _DidvanPageViewState extends State<DidvanPageView> {
|
|||
viewportFraction: 0.94,
|
||||
enableInfiniteScroll: false,
|
||||
),
|
||||
itemBuilder: (context, index, realIndex) => SizedBox(
|
||||
itemBuilder: (context, index, realIndex) => Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
child: SingleChildScrollView(
|
||||
controller: index == 1 ? widget.scrollController : null,
|
||||
|
|
@ -64,31 +73,42 @@ class _DidvanPageViewState extends State<DidvanPageView> {
|
|||
aspectRatio: 16 / 9,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: DidvanText(
|
||||
item.title,
|
||||
style: Theme.of(context).textTheme.subtitle1,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: _subtitle(item),
|
||||
),
|
||||
for (var i = 0; i < item.contents.length; i++)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 4,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
final content = item.contents[i];
|
||||
if (content.text != null) {
|
||||
return DidvanText(
|
||||
item.contents[i].text!,
|
||||
);
|
||||
}
|
||||
if (content.image != null) {
|
||||
return SkeletonImage(
|
||||
imageUrl: content.image!,
|
||||
aspectRatio: 16 / 9,
|
||||
);
|
||||
}
|
||||
return const SizedBox();
|
||||
},
|
||||
child: _contentBuilder(item, i),
|
||||
),
|
||||
if (item.tags.isNotEmpty) const SizedBox(height: 20),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
for (var i = 0; i < item.tags.length; i++)
|
||||
TagItem(label: item.tags[i].label),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||
child: DidvanDivider(),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
|
@ -97,6 +117,56 @@ class _DidvanPageViewState extends State<DidvanPageView> {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _contentBuilder(dynamic item, int index) {
|
||||
final content = item.contents[index];
|
||||
if (content.text != null) {
|
||||
return Html(data: item.contents[index].text!);
|
||||
}
|
||||
if (content.image != null) {
|
||||
return SkeletonImage(
|
||||
imageUrl: content.image!,
|
||||
aspectRatio: 16 / 9,
|
||||
);
|
||||
}
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
Widget _subtitle(dynamic item) {
|
||||
if (widget.isRadar) {
|
||||
return Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
children: [
|
||||
DidvanText(
|
||||
'رادار ',
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
),
|
||||
for (var i = 0; i < item.categories.length; i++)
|
||||
DidvanText(
|
||||
item.categories[i].label +
|
||||
' - ' +
|
||||
DateTimeUtils.momentGenerator(item.createdAt) +
|
||||
'${i != item.categories.length - 1 ? '،' : ''} ',
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Row(
|
||||
children: [
|
||||
DidvanText(
|
||||
item.reference,
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
),
|
||||
DidvanText(
|
||||
' - ' + DateTimeUtils.momentGenerator(item.createdAt),
|
||||
style: Theme.of(context).textTheme.caption,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,25 +7,29 @@ class DidvanScaffold extends StatelessWidget {
|
|||
final List<Widget>? children;
|
||||
final AppBarData appBarData;
|
||||
final EdgeInsets padding;
|
||||
final Color? backgroundColor;
|
||||
const DidvanScaffold({
|
||||
Key? key,
|
||||
this.slivers,
|
||||
required this.appBarData,
|
||||
this.children,
|
||||
this.padding = const EdgeInsets.symmetric(horizontal: 16),
|
||||
this.backgroundColor,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final double statusBarHeight = MediaQuery.of(context).padding.top;
|
||||
return Scaffold(
|
||||
backgroundColor: backgroundColor,
|
||||
body: Padding(
|
||||
padding: EdgeInsets.only(top: statusBarHeight),
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
toolbarHeight: kToolbarHeight,
|
||||
backgroundColor: Theme.of(context).backgroundColor,
|
||||
backgroundColor:
|
||||
backgroundColor ?? Theme.of(context).colorScheme.background,
|
||||
automaticallyImplyLeading: false,
|
||||
pinned: true,
|
||||
flexibleSpace: DidvanAppBar(appBarData: appBarData),
|
||||
|
|
@ -43,7 +47,12 @@ class DidvanScaffold extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (slivers != null) ...slivers!,
|
||||
if (slivers != null)
|
||||
for (var i = 0; i < slivers!.length; i++)
|
||||
SliverPadding(
|
||||
padding: padding,
|
||||
sliver: slivers![i],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ class DidvanText extends StatelessWidget {
|
|||
final TextAlign textAlign;
|
||||
final int? maxLines;
|
||||
final bool isEnglishFont;
|
||||
final TextOverflow? overflow;
|
||||
|
||||
const DidvanText(
|
||||
this.text, {
|
||||
|
|
@ -20,6 +21,7 @@ class DidvanText extends StatelessWidget {
|
|||
this.textAlign = TextAlign.right,
|
||||
this.maxLines,
|
||||
this.isEnglishFont = false,
|
||||
this.overflow,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -31,6 +33,7 @@ class DidvanText extends StatelessWidget {
|
|||
fontWeight: fontWeight,
|
||||
fontSize: fontSize,
|
||||
)).copyWith(fontFamily: isEnglishFont ? 'Dana' : null),
|
||||
overflow: overflow,
|
||||
textAlign: textAlign,
|
||||
maxLines: maxLines,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ import 'package:didvan/pages/home/settings/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/chip.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:didvan/widgets/item_title.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FloatingNavigationBar extends StatefulWidget {
|
||||
|
|
@ -116,6 +118,7 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
|||
value: _item.marked,
|
||||
onMark: widget.onMark,
|
||||
onUnmark: widget.onUnmark,
|
||||
bigGestureSize: true,
|
||||
),
|
||||
SizedBox(
|
||||
width: 48,
|
||||
|
|
@ -127,7 +130,6 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
|||
_item.comments.toString(),
|
||||
color: foregroundColor,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
DidvanIconButton(
|
||||
gestureSize: 32,
|
||||
onPressed: () => Navigator.of(context).pushNamed(
|
||||
|
|
@ -149,6 +151,7 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
|||
value: _item.marked,
|
||||
onMark: widget.onMark,
|
||||
onUnmark: widget.onUnmark,
|
||||
bigGestureSize: true,
|
||||
),
|
||||
if (_isRadar)
|
||||
DidvanIconButton(
|
||||
|
|
@ -166,16 +169,43 @@ class _FloatingNavigationBarState extends State<FloatingNavigationBar> {
|
|||
ActionSheetUtils.showBottomSheet(
|
||||
data: ActionSheetData(
|
||||
content: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
MenuItem(
|
||||
const ItemTitle(
|
||||
title: 'ارتباط با سردبیر',
|
||||
onTap: () {},
|
||||
icon: DidvanIcons.profile_regular,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
for (var i = 0; i < _item.categories.length; i++) ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 20),
|
||||
child: MenuItem(
|
||||
titleWidget: DidvanChip(label: _item.categories[i].label),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.direct,
|
||||
arguments: _item.categories[i].id,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
if (i != _item.categories.length - 1)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(right: 20),
|
||||
child: DidvanDivider(verticalPadding: 8),
|
||||
),
|
||||
],
|
||||
const DidvanDivider(),
|
||||
MenuItem(
|
||||
title: 'گزارش اشکال',
|
||||
onTap: () {},
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pushNamed(
|
||||
Routes.direct,
|
||||
arguments: 0,
|
||||
);
|
||||
},
|
||||
icon: DidvanIcons.description_regular,
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class InkWrapper extends StatelessWidget {
|
||||
|
|
@ -13,7 +14,7 @@ class InkWrapper extends StatelessWidget {
|
|||
this.highlightColor,
|
||||
required this.child,
|
||||
this.onPressed,
|
||||
this.borderRadius,
|
||||
this.borderRadius = DesignConfig.lowBorderRadius,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
|
|||
|
|
@ -6,12 +6,10 @@ 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;
|
||||
|
|
@ -110,16 +108,7 @@ class _SkeletonImageState extends State<SkeletonImage> {
|
|||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
const ShimmerPlaceholder(),
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
import 'package:didvan/config/design_config.dart';
|
||||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TagItem extends StatelessWidget {
|
||||
final String label;
|
||||
|
||||
const TagItem({
|
||||
Key? key,
|
||||
required this.label,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 4,
|
||||
horizontal: 8,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: DesignConfig.lowBorderRadius,
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
DidvanIcons.hashtag_regular,
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
),
|
||||
DidvanText(
|
||||
label,
|
||||
color: Theme.of(context).colorScheme.focusedBorder,
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue