diff --git a/lib/assets/icons/archive-tick.svg b/lib/assets/icons/archive-tick.svg new file mode 100644 index 0000000..d1c6c07 --- /dev/null +++ b/lib/assets/icons/archive-tick.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/assets/icons/arrow-right.svg b/lib/assets/icons/arrow-right.svg new file mode 100644 index 0000000..1aec4ea --- /dev/null +++ b/lib/assets/icons/arrow-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/assets/icons/bookmark_fill.svg b/lib/assets/icons/bookmark_fill.svg new file mode 100644 index 0000000..6a55ac7 --- /dev/null +++ b/lib/assets/icons/bookmark_fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/assets/icons/element-plus.svg b/lib/assets/icons/element-plus.svg new file mode 100644 index 0000000..db4b982 --- /dev/null +++ b/lib/assets/icons/element-plus.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/lib/assets/icons/heart.svg b/lib/assets/icons/heart.svg new file mode 100644 index 0000000..2dd9197 --- /dev/null +++ b/lib/assets/icons/heart.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/assets/icons/heart_fill.svg b/lib/assets/icons/heart_fill.svg new file mode 100644 index 0000000..f2eb26f --- /dev/null +++ b/lib/assets/icons/heart_fill.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/assets/icons/more_loading.svg b/lib/assets/icons/more_loading.svg new file mode 100644 index 0000000..bbeba8a --- /dev/null +++ b/lib/assets/icons/more_loading.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/assets/icons/send-2.svg b/lib/assets/icons/send-2.svg new file mode 100644 index 0000000..45b3808 --- /dev/null +++ b/lib/assets/icons/send-2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/services/network/request_helper.dart b/lib/services/network/request_helper.dart index 604a8ee..48d8780 100644 --- a/lib/services/network/request_helper.dart +++ b/lib/services/network/request_helper.dart @@ -205,8 +205,8 @@ class RequestHelper { static String deleteComment(int id) => '$baseUrl/comment/$id'; static String reportComment(int id) => '$baseUrl/comment/$id/report'; static String widgetNews() => '$baseUrl/user/widget'; - static String aiChats() => '$baseUrl/ai/chat/v2'; - static String aiArchived() => '$baseUrl/ai/chat/v2${_urlConcatGenerator([ + static String aiChats() => '$baseUrl/ai/aichat'; + static String aiArchived() => '$baseUrl/ai/aichat${_urlConcatGenerator([ const MapEntry('archived', true), ])}'; static String aiBots() => '$baseUrl/ai/bot/v2'; diff --git a/lib/views/home/main/widgets/infography_item.dart b/lib/views/home/main/widgets/infography_item.dart index 027e757..bb6ef96 100644 --- a/lib/views/home/main/widgets/infography_item.dart +++ b/lib/views/home/main/widgets/infography_item.dart @@ -8,14 +8,13 @@ import 'package:didvan/routes/routes.dart'; import 'package:didvan/views/widgets/animated_visibility.dart'; import 'package:didvan/views/widgets/bookmark_button.dart'; import 'package:didvan/views/widgets/didvan/card.dart'; -import 'package:didvan/views/widgets/didvan/divider.dart'; -import 'package:didvan/views/widgets/didvan/icon_button.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/infography_tag.dart'; import 'package:didvan/views/widgets/ink_wrapper.dart'; import 'package:didvan/views/widgets/liked_button.dart'; import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; class _BackButton extends StatefulWidget { const _BackButton({Key? key}) : super(key: key); @@ -117,77 +116,106 @@ class InfographyItem extends StatelessWidget { overflow: TextOverflow.ellipsis, ), ), + const SizedBox( + height: 10, + ), Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), + padding: const EdgeInsets.symmetric(vertical: 0.0), child: GestureDetector( onTap: () => _openInteractiveViewer(context, image), child: SkeletonImage( - imageUrl: image, - aspectRatio: 16 / 9, - ), + imageUrl: image, + aspectRatio: 16 / 9, + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(0.0), + bottomRight: Radius.circular(0.0), + topLeft: Radius.circular(13.0), + topRight: Radius.circular(13.0), + )), ), ), + Container( + decoration: const BoxDecoration( + color: Color.fromARGB(255, 0, 69, 92), + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(13.0), + bottomLeft: Radius.circular(13.0)), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InfoCat( + category: category, + createdAt: createdAt, + ), + Row( + children: [ + GestureDetector( + onTap: () => Navigator.of(context).pushNamed( + Routes.mentions, + arguments: { + 'id': id, + 'type': 'banner', + 'title': title, + }, + ), + child: SvgPicture.asset( + 'lib/assets/icons/send-2.svg', + width: 25, + height: 25, + colorFilter: const ColorFilter.mode( + Colors.white, + BlendMode.srcIn, + ), + ), + ), + BookmarkButton( + itemId: id, + type: 'infography', + gestureSize: 22, + value: marked, + onMarkChanged: (value) => onMarkChanged(id, value, true), + svgIconOn: 'lib/assets/icons/bookmark_fill.svg', + svgIconOff: 'lib/assets/icons/archive-tick.svg', + ), + Padding( + padding: const EdgeInsets.only(left: 8), + child: LikedButton( + itemId: id, + type: 'infography', + gestureSize: 32, + value: liked, + onMarkChanged: (value) => onLikedChanged(id, value, true), + likes: likes, + ), + ), + ], + ), + ], + ), + ), + const SizedBox( + height: 10, + ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Wrap( - spacing: 4, - runSpacing: 4, - children: [ - for (var i = 0; i < tag.length; i++) - InfographyTag( - tag: tag[i], - onMarkChanged: onMarkChanged, - ), - ], + Expanded( + child: Wrap( + spacing: 4, + runSpacing: 4, + children: [ + for (var i = 0; i < tag.length; i++) + InfographyTag( + tag: tag[i], + onMarkChanged: onMarkChanged, + ), + ], + ), ), ], ), - const DidvanDivider(), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - InfoCat( - category: category, - createdAt: createdAt, - ), - Row( - children: [ - LikedButton( - itemId: id, - type: 'infography', - gestureSize: 32, - value: liked, - onMarkChanged: (value) => onLikedChanged(id, value, true), - likes: likes, - ), - const SizedBox( - width: 4.0, - ), - DidvanIconButton( - gestureSize: 32, - onPressed: () => Navigator.of(context).pushNamed( - Routes.mentions, - arguments: { - 'id': id, - 'type': 'banner', - 'title': title, - }, - ), - icon: DidvanIcons.mention_icon, - ), - BookmarkButton( - itemId: id, - type: 'infography', - gestureSize: 32, - value: marked, - onMarkChanged: (value) => onMarkChanged(id, value, true), - ), - ], - ), - ], - ) ], ), ); diff --git a/lib/views/home/media/media_page.dart b/lib/views/home/media/media_page.dart index 4aff354..eaa5879 100644 --- a/lib/views/home/media/media_page.dart +++ b/lib/views/home/media/media_page.dart @@ -1,12 +1,13 @@ import 'package:didvan/views/home/media/podcast_tab_page.dart'; import 'package:didvan/views/home/media/videocast_tab_page.dart'; -import 'package:didvan/views/widgets/didvan/text.dart'; -import 'package:didvan/views/home/main/widgets/banner.dart'; +import 'package:didvan/views/home/media/widgets/media_banner_with_thumbnails.dart'; +import 'package:didvan/views/home/media/widgets/banner_grid_view.dart'; import 'package:didvan/views/widgets/home_app_bar.dart'; import 'package:didvan/views/widgets/custom_media_tab_bar.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:didvan/views/podcasts/podcasts_state.dart'; +import 'package:didvan/views/home/infography/infography_screen_state.dart'; class MediaPage extends StatefulWidget { const MediaPage({super.key}); @@ -101,25 +102,18 @@ class _MediaPageState extends State { child: Padding( padding: EdgeInsets.symmetric( horizontal: 16.0, vertical: 16.0), - child: MainPageBanner(isFirst: true), + child: MediaBannerWithThumbnails(isFirst: true), ), ), - Center( - key: const ValueKey('InfographyPage'), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.photo_library, - size: 48, - color: Theme.of(context).colorScheme.primary, - ), - const SizedBox(height: 8), - DidvanText( - 'صفحه اینفوگرافی', - style: Theme.of(context).textTheme.titleSmall, - ), - ], + ChangeNotifierProvider( + create: (_) => InfographyScreenState(), + child: const SingleChildScrollView( + key: ValueKey('InfographyPage'), + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 8.0, vertical: 16.0), + child: BannerGridView(), + ), ), ), ], diff --git a/lib/views/home/media/widgets/banner_grid_view.dart b/lib/views/home/media/widgets/banner_grid_view.dart new file mode 100644 index 0000000..4ca1a2a --- /dev/null +++ b/lib/views/home/media/widgets/banner_grid_view.dart @@ -0,0 +1,264 @@ +import 'package:didvan/views/home/infography/infography_screen_state.dart'; +import 'package:didvan/views/home/main/widgets/infography_item.dart'; +import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; +import 'package:didvan/views/widgets/shimmer_placeholder.dart'; +import 'package:didvan/views/widgets/didvan/card.dart'; +import 'package:didvan/views/widgets/didvan/divider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; + +class BannerGridView extends StatefulWidget { + const BannerGridView({super.key}); + + @override + State createState() => _BannerGridViewState(); +} + +class _BannerGridViewState extends State { + int _visibleItemCount = 4; + final ScrollController _scrollController = ScrollController(); + int pageNumber = 1; + + @override + void initState() { + super.initState(); + Future.microtask(() { + context.read().init(); + }); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (context, state, child) { + return StateHandler( + placeholder: Column( + children: [ + _buildPlaceholder(), + const SizedBox(height: 8.0), + _buildPlaceholder(), + ], + ), + topPadding: 0, + onRetry: () => state.init(), + state: state, + builder: (context, state) { + final contents = state.contents; + + final itemsToShow = _visibleItemCount > contents.length + ? contents.length + : _visibleItemCount; + + final hasMoreItems = itemsToShow < contents.length; + + return Column( + children: [ + _buildCategoryFilters(state), + + const SizedBox(height: 16), + + ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.all(8.0), + itemCount: itemsToShow, + separatorBuilder: (context, index) => + const SizedBox(height: 8.0), + itemBuilder: (context, index) { + final item = contents[index]; + return InfographyItem( + id: item.id, + onMarkChanged: (id, value, _) => + state.changeMark(id, value), + image: item.image, + category: item.category, + createdAt: item.createdAt, + title: item.title, + tag: item.tags, + marked: item.marked, + liked: item.liked, + onLikedChanged: (id, value, _) => + state.changeLiked(id, value), + likes: item.likes, + ); + }, + ), + + if (hasMoreItems) + Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: GestureDetector( + onTap: () { + setState(() { + _visibleItemCount += 4; + }); + }, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 50.0, + vertical: 12.0, + ), + decoration: BoxDecoration( + color: const Color.fromARGB(255, 0, 126, 167), + borderRadius: BorderRadius.circular(15), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + SvgPicture.asset( + 'lib/assets/icons/element-plus.svg', + ), + const SizedBox(width: 8), + const Text( + 'بارگذاری بیشتر', + style: TextStyle( + color: Colors.white, + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + ), + ], + ); + }, + ); + }, + ); + } + + Widget _buildCategoryFilters(InfographyScreenState state) { + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: FilterChip( + label: const Padding( + padding: EdgeInsets.all(1.0), + child: Text('همه'), + ), + selected: state.selectedCats.isEmpty, + onSelected: (selected) { + if (selected) { + state.selectedCats.clear(); + state.getInfographyContent(page: 1); + setState(() { + _visibleItemCount = 4; + }); + } + }, + selectedColor: const Color.fromARGB(255, 200, 224, 244), + backgroundColor: state.selectedCats.isEmpty + ? const Color.fromARGB(255, 200, 224, 244) + : const Color.fromARGB(255, 224, 224, 224), + labelStyle: TextStyle( + color: state.selectedCats.isEmpty + ? const Color.fromARGB(255, 0, 115, 153) + : const Color.fromARGB(255, 102, 102, 102), + fontWeight: state.selectedCats.isEmpty + ? FontWeight.bold + : FontWeight.normal, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(24), + ), + showCheckmark: false, + ), + ), + + ...state.categories.map((category) { + final isSelected = state.selectedCats.contains(category); + + return Padding( + padding: const EdgeInsets.only(left: 8.0), + child: FilterChip( + label: Padding( + padding: const EdgeInsets.all(1.0), + child: Text(category.label), + ), + selected: isSelected, + onSelected: (selected) { + if (selected) { + state.selectedCats.add(category); + } else { + state.selectedCats.remove(category); + } + state.getInfographyContent(page: 1); + setState(() { + _visibleItemCount = 4; + }); + }, + selectedColor: const Color.fromARGB(255, 200, 224, 244), + backgroundColor: isSelected + ? const Color.fromARGB(255, 200, 224, 244) + : const Color.fromARGB(255, 224, 224, 224), + labelStyle: TextStyle( + color: isSelected + ? const Color.fromARGB(255, 0, 115, 153) + : const Color.fromARGB(255, 102, 102, 102), + fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(24), + ), + showCheckmark: false, + ), + ); + }).toList(), + ], + ), + ); + } + + Widget _buildPlaceholder() { + return const DidvanCard( + padding: EdgeInsets.all(8), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ShimmerPlaceholder( + height: 16, + width: 240, + ), + ], + ), + SizedBox(height: 12), + ShimmerPlaceholder(height: 200, width: 400), + SizedBox(height: 12), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ShimmerPlaceholder( + height: 32, + width: 100, + ), + ], + ), + DidvanDivider( + verticalPadding: 12, + ), + ShimmerPlaceholder( + height: 16, + width: double.infinity, + ), + ], + ), + ); + } +} diff --git a/lib/views/home/media/widgets/media_banner_with_thumbnails.dart b/lib/views/home/media/widgets/media_banner_with_thumbnails.dart new file mode 100644 index 0000000..60ce9f5 --- /dev/null +++ b/lib/views/home/media/widgets/media_banner_with_thumbnails.dart @@ -0,0 +1,235 @@ +import 'package:didvan/utils/action_sheet.dart'; +import 'package:didvan/views/home/main/main_page_state.dart'; +import 'package:didvan/views/widgets/skeleton_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:provider/provider.dart'; +import 'package:url_launcher/url_launcher_string.dart'; +import 'package:carousel_slider/carousel_slider.dart'; + +class MediaBannerWithThumbnails extends StatefulWidget { + final bool isFirst; + const MediaBannerWithThumbnails({super.key, required this.isFirst}); + + @override + State createState() => _MediaBannerWithThumbnailsState(); +} + +class _MediaBannerWithThumbnailsState extends State { + int _currentIndex = 0; + int _thumbnailStartIndex = 0; + final CarouselSliderController _carouselController = CarouselSliderController(); + + @override + Widget build(BuildContext context) { + final state = context.read(); + final banners = state.content!.banners[widget.isFirst ? 0 : 1]; + + return Column( + children: [ + CarouselSlider.builder( + carouselController: _carouselController, + itemCount: banners.length, + itemBuilder: (context, index, realIndex) { + final item = banners[index]; + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 5), + child: GestureDetector( + onTap: () => item.link == null || item.link!.isEmpty + ? ActionSheetUtils(context) + .openInteractiveViewer(context, item.image, false) + : launchUrlString(item.link!, mode: LaunchMode.inAppWebView), + child: ClipRRect( + borderRadius: BorderRadius.circular(16), + child: SkeletonImage( + imageUrl: item.image, + borderRadius: BorderRadius.circular(16), + ), + ), + ), + ); + }, + options: CarouselOptions( + height: (MediaQuery.of(context).size.width - 8) * 9.0 / 16.0, + viewportFraction: 1.0, + enableInfiniteScroll: true, + autoPlay: true, + autoPlayInterval: const Duration(seconds: 5), + onPageChanged: (index, reason) { + setState(() { + _currentIndex = index; + if (index >= _thumbnailStartIndex + 3) { + _thumbnailStartIndex = index - 2; + } else if (index < _thumbnailStartIndex) { + _thumbnailStartIndex = index; + } + }); + }, + ), + ), + + const SizedBox(height: 8), + + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: banners.asMap().entries.map((entry) { + return AnimatedContainer( + duration: const Duration(milliseconds: 300), + width: _currentIndex == entry.key ? 10 : 5, + height: _currentIndex == entry.key ? 10 : 5, + margin: const EdgeInsets.symmetric(horizontal: 4), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(300), + boxShadow: [ + BoxShadow( + color: _currentIndex == entry.key + ? const Color.fromARGB(100, 0, 126, 167) + : const Color.fromARGB(0, 0, 0, 0), + spreadRadius: 2.5, + offset: const Offset(0, 0), + ), + ], + color: _currentIndex == entry.key + ? const Color.fromARGB(255, 0, 126, 167) + : const Color.fromARGB(255, 200, 200, 200), + ), + ); + }).toList(), + ), + + const SizedBox(height: 16), + + Row( + children: [ + IconButton( + icon: SvgPicture.asset( + 'lib/assets/icons/arrow-right.svg', + width: 24, + height: 24, + colorFilter: ColorFilter.mode( + _thumbnailStartIndex > 0 + ? const Color.fromARGB(255, 0, 126, 167) + : const Color.fromARGB(255, 200, 200, 200), + BlendMode.srcIn, + ), + ), + onPressed: _thumbnailStartIndex > 0 + ? () { + setState(() { + _thumbnailStartIndex = (_thumbnailStartIndex - 1).clamp(0, banners.length - 3); + }); + } + : null, + ), + + Expanded( + child: SizedBox( + height: 60, + width: double.infinity, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: List.generate(3, (index) { + if (_thumbnailStartIndex + index >= banners.length) { + return const SizedBox(width: 0); + } + + final actualIndex = _thumbnailStartIndex + index; + final item = banners[actualIndex]; + final isSelected = actualIndex == _currentIndex; + + return Expanded( + child: GestureDetector( + onTap: () { + if (actualIndex == _currentIndex) return; + + _carouselController.animateToPage( + actualIndex, + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + + setState(() { + _currentIndex = actualIndex; + + if (actualIndex < _thumbnailStartIndex) { + _thumbnailStartIndex = actualIndex; + } else if (actualIndex >= _thumbnailStartIndex + 3) { + _thumbnailStartIndex = (actualIndex - 2).clamp(0, banners.length - 3); + } + }); + }, + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + margin: const EdgeInsets.symmetric(horizontal: 4), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: isSelected + ? const Color.fromARGB(255, 0, 126, 167) + : Colors.transparent, + width: 2, + ), + + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: AnimatedOpacity( + duration: const Duration(milliseconds: 200), + opacity: isSelected ? 1.0 : 0.6, + child: ColorFiltered( + colorFilter: isSelected + ? const ColorFilter.mode( + Colors.transparent, + BlendMode.multiply, + ) + : const ColorFilter.matrix([ + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0.2126, 0.7152, 0.0722, 0, 0, + 0, 0, 0, 1, 0, + ]), + child: AspectRatio( + aspectRatio: 19 / 13, + child: SkeletonImage( + imageUrl: item.image, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ), + ), + ), + ); + }), + ), + ), + ), + + // فلش چپ (برای رفتن به جلو) + IconButton( + icon: SvgPicture.asset( + 'lib/assets/icons/arrow-left.svg', + width: 24, + height: 24, + colorFilter: ColorFilter.mode( + _thumbnailStartIndex < banners.length - 3 + ? const Color.fromARGB(255, 0, 126, 167) + : const Color.fromARGB(255, 200, 200, 200), + BlendMode.srcIn, + ), + ), + onPressed: _thumbnailStartIndex < banners.length - 3 + ? () { + setState(() { + _thumbnailStartIndex = (_thumbnailStartIndex + 1).clamp(0, banners.length - 3); + }); + } + : null, + ), + ], + ), + ], + ); + } +} diff --git a/lib/views/widgets/bookmark_button.dart b/lib/views/widgets/bookmark_button.dart index 0578174..f671bac 100644 --- a/lib/views/widgets/bookmark_button.dart +++ b/lib/views/widgets/bookmark_button.dart @@ -1,4 +1,3 @@ -import 'package:didvan/config/design_config.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/models/view/action_sheet_data.dart'; import 'package:didvan/providers/user.dart'; @@ -78,6 +77,9 @@ class _BookmarkButtonState extends State { Widget build(BuildContext context) { print("BookmarkButton build - value: $_value"); + final iconOn = widget.svgIconOn ?? 'lib/assets/icons/bookmark_on.svg'; + final iconOff = widget.svgIconOff ?? 'lib/assets/icons/bookmark_off.svg'; + return IconButton( iconSize: widget.gestureSize, onPressed: _handleTap, @@ -87,7 +89,7 @@ class _BookmarkButtonState extends State { return ScaleTransition(scale: animation, child: child); }, child: SvgPicture.asset( - _value ? 'lib/assets/icons/bookmark_on.svg' : 'lib/assets/icons/bookmark_off.svg', + _value ? iconOn : iconOff, key: ValueKey('bookmark_$_value'), width: widget.gestureSize, height: widget.gestureSize, diff --git a/lib/views/widgets/didvan/bnb.dart b/lib/views/widgets/didvan/bnb.dart index a78c486..d74d584 100644 --- a/lib/views/widgets/didvan/bnb.dart +++ b/lib/views/widgets/didvan/bnb.dart @@ -5,8 +5,6 @@ import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import '../audio/player_navbar.dart'; - class DidvanBNB extends StatelessWidget { final int currentTabIndex; final void Function(int index) onTabChanged; @@ -17,28 +15,19 @@ class DidvanBNB extends StatelessWidget { @override Widget build(BuildContext context) { - return Stack( - children: [ - const PlayerNavBar( - inHome: true, + return Container( + height: 72, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: + const BorderRadius.vertical(top: Radius.circular(0)), + border: const Border( + top: BorderSide( + color: Color.fromARGB(255, 224, 224, 224), + width: 1.5, + ), ), - Positioned( - bottom: 0, - left: 0, - right: 0, - child: Container( - height: 72, - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surface, - borderRadius: - const BorderRadius.vertical(top: Radius.circular(0)), - border: const Border( - top: BorderSide( - color: Color.fromARGB(255, 224, 224, 224), - width: 1.5, - ), - ), - ), + ), padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ @@ -87,10 +76,7 @@ class DidvanBNB extends StatelessWidget { ), ], ), - ), - ), - ], - ); + ); } } @@ -229,7 +215,6 @@ class _NavBarItemState extends State<_NavBarItem> child: Stack( alignment: Alignment.center, children: [ - // Ripple effect background AnimatedBuilder( animation: _rippleAnimation, builder: (context, child) { @@ -245,7 +230,6 @@ class _NavBarItemState extends State<_NavBarItem> ); }, ), - // Main content Column( children: [ const SizedBox(height: 4), @@ -261,7 +245,6 @@ class _NavBarItemState extends State<_NavBarItem> padding: EdgeInsets.all(widget.isHomeButton ? 8 : 4), duration: DesignConfig.lowAnimationDuration, - //shadow decoration: BoxDecoration( shape: BoxShape.circle, @@ -302,7 +285,6 @@ class _NavBarItemState extends State<_NavBarItem> ); }, ), - // Animated text with fade and slide AnimatedSwitcher( duration: const Duration(milliseconds: 200), child: (!widget.isHomeButton && !widget.isSelected) diff --git a/lib/views/widgets/didvan/scaffold.dart b/lib/views/widgets/didvan/scaffold.dart index ca06b25..7e9067a 100644 --- a/lib/views/widgets/didvan/scaffold.dart +++ b/lib/views/widgets/didvan/scaffold.dart @@ -2,8 +2,6 @@ import 'package:didvan/models/view/app_bar_data.dart'; import 'package:didvan/views/widgets/didvan/app_bar.dart'; import 'package:flutter/material.dart'; -import '../audio/player_navbar.dart'; - class DidvanScaffold extends StatefulWidget { final List? slivers; final List? children; @@ -137,19 +135,6 @@ class _DidvanScaffoldState extends State { appBarData: widget.appBarData!, scrollController: _scrollController, ), - if (!widget.hidePlayer) - const Positioned( - bottom: 16, - left: 16, - right: 16, - child: SizedBox( - child: Center( - child: PlayerNavBar( - inHome: false, - ), - ), - ), - ), ], ), ), diff --git a/lib/views/widgets/didvan/slider.dart b/lib/views/widgets/didvan/slider.dart index 93fa533..39d8681 100644 --- a/lib/views/widgets/didvan/slider.dart +++ b/lib/views/widgets/didvan/slider.dart @@ -72,18 +72,22 @@ class _CarouselIndicator extends StatelessWidget { children: [ for (int i = 0; i < count; i++) Container( - width: 8, - height: 8, + width: 7, + height: 7, margin: const EdgeInsets.symmetric(horizontal: 2), decoration: BoxDecoration( shape: BoxShape.circle, - border: Border.all( - width: 1, - color: Theme.of(context).colorScheme.primary, - ), + boxShadow: [ + BoxShadow( + color: currentIndex == i ? const Color.fromARGB(255, 176, 215, 228) : Colors.transparent, + blurRadius: 0, + spreadRadius: 2.5, + offset: const Offset(0, 0), + ), + ], color: currentIndex == i - ? Theme.of(context).colorScheme.primary - : Colors.transparent, + ? const Color.fromARGB(255, 0, 126, 167) + : const Color.fromARGB(255, 173, 173, 173), ), ) ], diff --git a/lib/views/widgets/infography_tag.dart b/lib/views/widgets/infography_tag.dart index f61c80f..afefa91 100644 --- a/lib/views/widgets/infography_tag.dart +++ b/lib/views/widgets/infography_tag.dart @@ -1,11 +1,11 @@ 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/tag.dart'; import 'package:didvan/routes/routes.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/ink_wrapper.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:persian_number_utility/persian_number_utility.dart'; class InfographyTag extends StatelessWidget { @@ -34,23 +34,26 @@ class InfographyTag extends StatelessWidget { horizontal: 4, ), decoration: BoxDecoration( - borderRadius: DesignConfig.lowBorderRadius, + borderRadius: DesignConfig.mediumBorderRadius, border: Border.all( - color: Theme.of(context).colorScheme.focusedBorder, + color: const Color.fromARGB(255, 184, 184, 184), ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ - Icon( + const Icon( DidvanIcons.hashtag_regular, - color: Theme.of(context).colorScheme.focusedBorder, + color: Color.fromARGB(255, 102, 102, 102), size: 16, ), - DidvanText( - tag.label, - color: Theme.of(context).colorScheme.focusedBorder, - style: Theme.of(context).textTheme.labelLarge, + Padding( + padding: const EdgeInsets.all(2.0), + child: DidvanText( + tag.label, + color: const Color.fromARGB(255, 102, 102, 102), + style: Theme.of(context).textTheme.labelMedium, + ), ), ], ), @@ -73,13 +76,16 @@ class InfoCat extends StatelessWidget { Widget build(BuildContext context) { return Row( children: [ + const SizedBox(width: 15,), + SvgPicture.asset('lib/assets/icons/calendar.svg',color: Colors.white,height: 22,), + const SizedBox(width: 5,), + // DidvanText( + // category, + // style: Theme.of(context).textTheme.bodySmall, + // ), DidvanText( - category, - style: Theme.of(context).textTheme.bodySmall, - ), - DidvanText( - ' / ${DateTime.parse(createdAt).toPersianDateStr()}', - style: Theme.of(context).textTheme.bodySmall, + DateTime.parse(createdAt).toPersianDateStr(), + style: const TextStyle(color: Colors.white), ), ], ); diff --git a/lib/views/widgets/liked_button.dart b/lib/views/widgets/liked_button.dart index 6bcf942..b42b3ed 100644 --- a/lib/views/widgets/liked_button.dart +++ b/lib/views/widgets/liked_button.dart @@ -3,8 +3,8 @@ import 'package:didvan/models/view/action_sheet_data.dart'; import 'package:didvan/providers/user.dart'; import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; class LikedButton extends StatefulWidget { final bool value; @@ -59,6 +59,7 @@ class _LikedButtonState extends State { child: DidvanText( likes.toString(), fontSize: 14, + color: Colors.white, ), ), InkWell( @@ -90,11 +91,11 @@ class _LikedButtonState extends State { UserProvider.changeItemLiked(widget.type, widget.itemId, _value); } }, - child: Icon( - _value ? CupertinoIcons.heart_fill : CupertinoIcons.heart, - size: 24, + child: SvgPicture.asset( + _value ? 'lib/assets/icons/heart_fill.svg':'lib/assets/icons/heart.svg', + height: 24, color: widget.color ?? - (!_value ? null : Theme.of(context).colorScheme.error), + (!_value ? Colors.white : Theme.of(context).colorScheme.error), ), ), ],