diff --git a/lib/assets/icons/calendar.svg b/lib/assets/icons/calendar.svg
new file mode 100644
index 0000000..332ce46
--- /dev/null
+++ b/lib/assets/icons/calendar.svg
@@ -0,0 +1,12 @@
+
diff --git a/lib/assets/icons/clock.svg b/lib/assets/icons/clock.svg
new file mode 100644
index 0000000..baf3724
--- /dev/null
+++ b/lib/assets/icons/clock.svg
@@ -0,0 +1,4 @@
+
diff --git a/lib/assets/icons/play-circle.svg b/lib/assets/icons/play-circle.svg
new file mode 100644
index 0000000..fb3569d
--- /dev/null
+++ b/lib/assets/icons/play-circle.svg
@@ -0,0 +1,4 @@
+
diff --git a/lib/assets/icons/timer.svg b/lib/assets/icons/timer.svg
new file mode 100644
index 0000000..fb89c0c
--- /dev/null
+++ b/lib/assets/icons/timer.svg
@@ -0,0 +1,4 @@
+
diff --git a/lib/routes/route_generator.dart b/lib/routes/route_generator.dart
index f8b2184..881f4f6 100644
--- a/lib/routes/route_generator.dart
+++ b/lib/routes/route_generator.dart
@@ -1,5 +1,3 @@
-// lib/routes/route_generator.dart
-
// ignore_for_file: avoid_print
import 'package:didvan/models/ai/ai_chat_args.dart';
@@ -30,6 +28,7 @@ import 'package:didvan/views/home/infography/infography_screen.dart';
import 'package:didvan/views/home/infography/infography_screen_state.dart';
import 'package:didvan/views/home/main/main_page_state.dart';
import 'package:didvan/views/home/home_state.dart';
+import 'package:didvan/views/home/media/media_page.dart';
import 'package:didvan/views/home/new_statistic/new_statistics_state.dart';
import 'package:didvan/views/home/new_statistic/statistics_details/stat_cats_general_screen.dart';
import 'package:didvan/views/home/new_statistic/statistics_details/stat_cats_general_state.dart';
@@ -43,6 +42,7 @@ import 'package:didvan/views/news/news_details/news_details_state.dart';
import 'package:didvan/views/news/news_state.dart';
import 'package:didvan/views/notification_time/notification_time_state.dart';
import 'package:didvan/views/podcasts/podcasts.dart';
+import 'package:didvan/views/podcasts/podcasts_state.dart';
import 'package:didvan/views/podcasts/studio_details/studio_details_state.dart';
import 'package:didvan/views/profile/profile.dart';
import 'package:didvan/views/radar/radar.dart';
@@ -496,6 +496,14 @@ class RouteGenerator {
return _errorRoute(
'Invalid arguments for ${settings.name}: Expected Map with stories and tappedIndex.');
+ case Routes.media:
+ return MaterialPageRoute(
+ builder: (_) => ChangeNotifierProvider(
+ create: (context) => PodcastsState(),
+ child: const MediaPage(),
+ ),
+ );
+
default:
return _errorRoute(settings.name ?? 'Unknown route');
}
diff --git a/lib/routes/routes.dart b/lib/routes/routes.dart
index 872d5af..09376e3 100644
--- a/lib/routes/routes.dart
+++ b/lib/routes/routes.dart
@@ -41,4 +41,5 @@ class Routes {
static const String newStatic = '/new-static';
static const String web = '/web';
static const String storyViewer = '/story-viewer';
+ static const String media = '/media';
}
\ No newline at end of file
diff --git a/lib/views/home/main/main_page.dart b/lib/views/home/main/main_page.dart
index 875a9ec..8cffada 100644
--- a/lib/views/home/main/main_page.dart
+++ b/lib/views/home/main/main_page.dart
@@ -65,48 +65,55 @@ class _MainPageState extends State {
onRetry: () => context.read().init(),
state: context.watch(),
builder: (context, state) {
- return ListView(
- padding: const EdgeInsets.only(top: 0, bottom: 16),
+ return Column(
children: [
const HomeAppBar(
showBackButton: false,
showSearchField: true,
),
- if (state.stories.isNotEmpty) ...[
- const TextDivider(text: 'دیدهبان')
- .animate()
- .fadeIn(delay: 400.ms, duration: 500.ms),
- const _DidvanSignalsTitle()
- .animate()
- .fadeIn(delay: 500.ms, duration: 500.ms),
- Padding(
- padding: const EdgeInsets.symmetric(horizontal: 8),
- child: StorySection(stories: state.stories),
- ).animate().fadeIn(delay: 600.ms, duration: 500.ms),
- ],
- const SizedBox(height: 12),
- const TextDivider(text: 'پیشخوان استراتژیک')
- .animate()
- .fadeIn(delay: 700.ms, duration: 500.ms),
- const Padding(
- padding: EdgeInsets.symmetric(horizontal: 16),
- child: MainPageMainContent(),
- ).animate().fadeIn(delay: 800.ms, duration: 500.ms),
- if (state.content != null && state.content!.lists.isNotEmpty) ...[
- const _ExploreLatestTitle()
- .animate()
- .fadeIn(delay: 900.ms, duration: 500.ms),
- _ExploreLatestSlider(
- lists: state.content!.lists,
- swotItems: state.swotItems,
- ).animate().fadeIn(delay: 1000.ms, duration: 500.ms),
- ],
- const _IndustryPulseTitle()
- .animate()
- .fadeIn(delay: 1100.ms, duration: 500.ms),
- const _IndustryPulseCards()
- .animate()
- .fadeIn(delay: 1200.ms, duration: 500.ms),
+ Expanded(
+ child: ListView(
+ padding: const EdgeInsets.only(top: 0, bottom: 16),
+ children: [
+ if (state.stories.isNotEmpty) ...[
+ const TextDivider(text: 'دیدهبان')
+ .animate()
+ .fadeIn(delay: 400.ms, duration: 500.ms),
+ const _DidvanSignalsTitle()
+ .animate()
+ .fadeIn(delay: 500.ms, duration: 500.ms),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8),
+ child: StorySection(stories: state.stories),
+ ).animate().fadeIn(delay: 600.ms, duration: 500.ms),
+ ],
+ const SizedBox(height: 12),
+ const TextDivider(text: 'پیشخوان استراتژیک')
+ .animate()
+ .fadeIn(delay: 700.ms, duration: 500.ms),
+ const Padding(
+ padding: EdgeInsets.symmetric(horizontal: 16),
+ child: MainPageMainContent(),
+ ).animate().fadeIn(delay: 800.ms, duration: 500.ms),
+ if (state.content != null &&
+ state.content!.lists.isNotEmpty) ...[
+ const _ExploreLatestTitle()
+ .animate()
+ .fadeIn(delay: 900.ms, duration: 500.ms),
+ _ExploreLatestSlider(
+ lists: state.content!.lists,
+ swotItems: state.swotItems,
+ ).animate().fadeIn(delay: 1000.ms, duration: 500.ms),
+ ],
+ const _IndustryPulseTitle()
+ .animate()
+ .fadeIn(delay: 1100.ms, duration: 500.ms),
+ const _IndustryPulseCards()
+ .animate()
+ .fadeIn(delay: 1200.ms, duration: 500.ms),
+ ],
+ ),
+ ),
],
);
},
@@ -510,4 +517,4 @@ class _IndustryPulseCard extends StatelessWidget {
void onMarkChanged(int id, bool value) {
UserProvider.changeStatisticMark(id, value);
}
-}
+}
\ No newline at end of file
diff --git a/lib/views/home/media/media_page.dart b/lib/views/home/media/media_page.dart
index 86e03fd..8bf0377 100644
--- a/lib/views/home/media/media_page.dart
+++ b/lib/views/home/media/media_page.dart
@@ -1,3 +1,5 @@
+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/widgets/home_app_bar.dart';
@@ -17,7 +19,7 @@ class _MediaPageState extends State {
final List _categories = [
'پادکست',
- 'ویدیوکست',
+ 'ویدیوکست',
'فولادینفو',
'اینفوگرافی',
];
@@ -66,7 +68,8 @@ class _MediaPageState extends State {
),
Container(
width: double.infinity,
- padding: const EdgeInsets.symmetric(horizontal: 7), // 10% فاصله از هر طرف برای 80%
+ padding:
+ const EdgeInsets.symmetric(horizontal: 7),
child: Container(
height: 2,
color: const Color.fromRGBO(184, 184, 184, 1),
@@ -81,44 +84,12 @@ class _MediaPageState extends State {
});
},
children: [
- // محتوای تب پادکستها
- Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(
- Icons.podcasts,
- size: 48,
- color: Theme.of(context).colorScheme.primary,
- ),
- const SizedBox(height: 8),
- DidvanText(
- 'صفحه پادکستها',
- style: Theme.of(context).textTheme.titleSmall,
- ),
- ],
- ),
- ),
- Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(
- Icons.video_library,
- size: 48,
- color: Theme.of(context).colorScheme.primary,
- ),
- const SizedBox(height: 8),
- DidvanText(
- 'صفحه ویدئوها',
- style: Theme.of(context).textTheme.titleSmall,
- ),
- ],
- ),
- ),
+ const PodcastTabPage(),
+ const VideoCastTabPage(),
const SingleChildScrollView(
child: Padding(
- padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0),
+ padding: EdgeInsets.symmetric(
+ horizontal: 16.0, vertical: 16.0),
child: MainPageBanner(isFirst: true),
),
),
diff --git a/lib/views/home/media/podcast_tab_page.dart b/lib/views/home/media/podcast_tab_page.dart
new file mode 100644
index 0000000..f8f5431
--- /dev/null
+++ b/lib/views/home/media/podcast_tab_page.dart
@@ -0,0 +1,66 @@
+import 'package:didvan/models/requests/studio.dart';
+import 'package:didvan/views/podcasts/podcasts_state.dart';
+import 'package:didvan/views/widgets/overview/podcast.dart';
+import 'package:didvan/views/widgets/state_handlers/empty_result.dart';
+import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+class PodcastTabPage extends StatefulWidget {
+ const PodcastTabPage({super.key});
+
+ @override
+ State createState() => _PodcastTabPageState();
+}
+
+class _PodcastTabPageState extends State {
+ @override
+ void initState() {
+ super.initState();
+ Future.microtask(() {
+ context.read().init(true);
+ context.read().getStudios(page: 1);
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final state = context.watch();
+
+ return StateHandler(
+ state: state,
+ emptyState: EmptyResult(
+ onNewSearch: () {},
+ ),
+ enableEmptyState: state.studios.isEmpty,
+ placeholder: PodcastOverview.placeholder,
+ builder: (context, state) {
+ return ListView.builder(
+ itemCount: state.studios.length,
+ itemBuilder: (context, index) {
+ final podcast = state.studios[index];
+ return Padding(
+ padding: const EdgeInsets.only(
+ bottom: 8,
+ left: 16,
+ right: 16,
+ ),
+ child: PodcastOverview(
+ podcast: podcast,
+ onMarkChanged: state.changeMark,
+ studioRequestArgs: StudioRequestArgs(
+ page: state.page,
+ order: state.order,
+ search: state.search,
+ type: state.type,
+ asc: state.selectedSortTypeIndex == 1,
+ ),
+ ),
+ );
+ },
+ );
+ },
+ onRetry: () => context.read().getStudios(page: 1),
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/views/home/media/videocast_tab_page.dart b/lib/views/home/media/videocast_tab_page.dart
new file mode 100644
index 0000000..988a8ec
--- /dev/null
+++ b/lib/views/home/media/videocast_tab_page.dart
@@ -0,0 +1,99 @@
+import 'package:didvan/routes/routes.dart';
+import 'package:didvan/views/home/media/widgets/featured_video_card.dart';
+import 'package:didvan/views/home/media/widgets/videocast_grid_card.dart';
+import 'package:didvan/views/podcasts/podcasts_state.dart';
+import 'package:didvan/views/widgets/overview/podcast.dart';
+import 'package:didvan/views/widgets/state_handlers/empty_result.dart';
+import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+class VideoCastTabPage extends StatefulWidget {
+ const VideoCastTabPage({super.key});
+
+ @override
+ State createState() => _VideoCastTabPageState();
+}
+
+class _VideoCastTabPageState extends State {
+ @override
+ void initState() {
+ super.initState();
+ Future.microtask(() {
+ context.read().init(false);
+ context.read().getStudios(page: 1);
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final state = context.watch();
+
+ return StateHandler(
+ state: state,
+ emptyState: EmptyResult(
+ onNewSearch: () {},
+ ),
+ enableEmptyState: state.studios.isEmpty,
+ placeholder: PodcastOverview.placeholder,
+ builder: (context, state) {
+ if (state.studios.isEmpty) {
+ return const SizedBox.shrink();
+ }
+
+ return SingleChildScrollView(
+ child: Column(
+ children: [
+ FeaturedVideoCard(
+ videocast: state.studios.first,
+ onTap: () {
+ Navigator.pushNamed(
+ context,
+ Routes.studioDetails,
+ arguments: {
+ 'id': state.studios.first.id,
+ 'type': state.studios.first.type,
+ },
+ );
+ },
+ ),
+
+ if (state.studios.length > 1)
+ Padding(
+ padding: const EdgeInsets.all(16),
+ child: GridView.builder(
+ shrinkWrap: true,
+ physics: const NeverScrollableScrollPhysics(),
+ gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 2,
+ crossAxisSpacing: 12,
+ mainAxisSpacing: 12,
+ childAspectRatio: 0.75,
+ ),
+ itemCount: state.studios.length - 1,
+ itemBuilder: (context, index) {
+ final videocast = state.studios[index + 1];
+ return VideocastGridCard(
+ videocast: videocast,
+ onTap: () {
+ Navigator.pushNamed(
+ context,
+ Routes.studioDetails,
+ arguments: {
+ 'id': videocast.id,
+ 'type': videocast.type,
+ },
+ );
+ },
+ );
+ },
+ ),
+ ),
+ ],
+ ),
+ );
+ },
+ onRetry: () => context.read().getStudios(page: 1),
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/views/home/media/widgets/featured_video_card.dart b/lib/views/home/media/widgets/featured_video_card.dart
new file mode 100644
index 0000000..d0cadf1
--- /dev/null
+++ b/lib/views/home/media/widgets/featured_video_card.dart
@@ -0,0 +1,189 @@
+import 'package:didvan/models/overview_data.dart';
+import 'package:didvan/views/widgets/didvan/text.dart';
+import 'package:didvan/views/widgets/skeleton_image.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:persian_number_utility/persian_number_utility.dart';
+
+class FeaturedVideoCard extends StatelessWidget {
+ final OverviewData videocast;
+ final VoidCallback onTap;
+
+ const FeaturedVideoCard({
+ super.key,
+ required this.videocast,
+ required this.onTap,
+ });
+
+ String _formatDuration(int? duration) {
+ if (duration == null) return '';
+ final minutes = duration ~/ 60;
+ final seconds = duration % 60;
+ return '”${seconds.toString().padLeft(2, '0')}:’${minutes.toString().padLeft(2, '0')}';
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: MediaQuery.of(context).size.height * 0.40,
+ margin: const EdgeInsets.all(16),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(16),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.black.withOpacity(0.1),
+ blurRadius: 10,
+ offset: const Offset(0, 4),
+ ),
+ ],
+ ),
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(16),
+ child: Stack(
+ children: [
+ Positioned.fill(
+ child: ColorFiltered(
+ colorFilter: 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: SkeletonImage(
+ imageUrl: videocast.image,
+ width: double.infinity,
+ height: double.infinity,
+ borderRadius: BorderRadius.circular(16),
+ ),
+ ),
+ ),
+
+ Positioned(
+ bottom: 0,
+ left: 0,
+ right: 0,
+ child: Container(
+ height: 200,
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ begin: Alignment.bottomCenter,
+ end: Alignment.topCenter,
+ colors: [
+ Colors.black.withOpacity(0.8),
+ Colors.black.withOpacity(0.4),
+ Colors.transparent,
+ ],
+ ),
+ ),
+ ),
+ ),
+
+ Positioned(
+ bottom: 16,
+ left: 16,
+ right: 16,
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ IntrinsicWidth(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.stretch,
+ children: [
+ DidvanText(
+ videocast.title,
+ style: Theme.of(context).textTheme.headlineSmall?.copyWith(
+ color: const Color.fromARGB(255, 200, 224, 244),
+ fontWeight: FontWeight.bold,
+ ),
+ maxLines: 2,
+ overflow: TextOverflow.ellipsis,
+ ),
+ const SizedBox(height: 8),
+ Container(
+ height: 2,
+ color: const Color.fromARGB(255, 200, 224, 244),
+ ),
+ ],
+ ),
+ ),
+
+ const SizedBox(height: 12),
+
+ DidvanText(
+ videocast.description,
+ style: Theme.of(context).textTheme.bodySmall?.copyWith(
+ color: Colors.white,
+ height: 1.4,
+ ),
+ maxLines: 4,
+ overflow: TextOverflow.ellipsis,
+ ),
+
+ const SizedBox(height: 5),
+
+ Align(
+ alignment: AlignmentDirectional.centerEnd,
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ SvgPicture.asset("lib/assets/icons/timer.svg"),
+ const SizedBox(width: 6),
+ DidvanText(
+ _formatDuration(videocast.duration).toPersianDigit(),
+ style: Theme.of(context).textTheme.bodyMedium?.copyWith(
+ color: Colors.white,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ ],
+ ),
+ ),
+
+ SizedBox(
+ width: double.infinity,
+ child: ElevatedButton.icon(
+ onPressed: onTap,
+ icon: SvgPicture.asset('lib/assets/icons/play-circle.svg'),
+ label: const DidvanText(
+ 'مشاهده ویدیو',
+ style: TextStyle(color: Colors.white),
+ ),
+ style: ElevatedButton.styleFrom(
+ backgroundColor: const Color.fromARGB(255, 178, 4, 54),
+ foregroundColor: Colors.white,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(12),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ const SizedBox(width: 16),
+ Padding(
+ padding: const EdgeInsets.only(bottom: 60.0),
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(12),
+ child: SkeletonImage(
+ imageUrl: videocast.image,
+ width: 115,
+ height: 155,
+ borderRadius: BorderRadius.circular(12),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/views/home/media/widgets/videocast_grid_card.dart b/lib/views/home/media/widgets/videocast_grid_card.dart
new file mode 100644
index 0000000..252d598
--- /dev/null
+++ b/lib/views/home/media/widgets/videocast_grid_card.dart
@@ -0,0 +1,132 @@
+import 'package:didvan/models/overview_data.dart';
+import 'package:didvan/views/widgets/didvan/text.dart';
+import 'package:didvan/views/widgets/skeleton_image.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:persian_number_utility/persian_number_utility.dart';
+
+class VideocastGridCard extends StatelessWidget {
+ final OverviewData videocast;
+ final VoidCallback onTap;
+
+ const VideocastGridCard({
+ super.key,
+ required this.videocast,
+ required this.onTap,
+ });
+
+ String _formatDuration(int? duration) {
+ if (duration == null) return '';
+ final minutes = duration ~/ 60;
+ final seconds = duration % 60;
+ return '”${seconds.toString().padLeft(2, '0')}:’${minutes.toString().padLeft(2, '0')}';
+ }
+
+ String _formatDate(String dateStr) {
+ try {
+ final date = DateTime.parse(dateStr);
+ return date.toPersianDateStr();
+ } catch (e) {
+ return dateStr;
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: onTap,
+ child: Container(
+ decoration: BoxDecoration(
+ color: const Color.fromRGBO(235, 235, 235, 1),
+ borderRadius: BorderRadius.circular(20),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.black.withOpacity(0.05),
+ blurRadius: 4,
+ offset: const Offset(0, 2),
+ ),
+ ],
+ ),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ // Video cover
+ Padding(
+ padding: const EdgeInsets.all(6.0),
+ child: AspectRatio(
+ aspectRatio: 17 / 14,
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(20),
+ child: SkeletonImage(
+ imageUrl: videocast.image,
+ width: double.infinity,
+ height: double.infinity,
+ borderRadius: BorderRadius.circular(20),
+ ),
+ ),
+ ),
+ ),
+
+ Expanded(
+ child: Padding(
+ padding: const EdgeInsets.fromLTRB(12, 4, 12, 8),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ DidvanText(
+ videocast.title,
+ style: Theme.of(context).textTheme.bodyMedium?.copyWith(
+ fontWeight: FontWeight.w600,
+ color: Colors.black87,
+ ),
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ ),
+ const SizedBox(height: 4),
+ Row(
+ children: [
+ SvgPicture.asset('lib/assets/icons/calendar.svg'),
+ const SizedBox(width: 4),
+ DidvanText(
+ _formatDate(videocast.createdAt),
+ style: Theme.of(context)
+ .textTheme
+ .bodySmall
+ ?.copyWith(
+ color: const Color.fromARGB(255, 102, 102, 102),
+ ),
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ ),
+ ],
+ ),
+ const SizedBox(height: 4),
+ Row(
+ children: [
+ SvgPicture.asset(
+ 'lib/assets/icons/clock.svg',
+ color: const Color.fromARGB(255, 102, 102, 102),
+ ),
+ const SizedBox(width: 4),
+ DidvanText(
+ _formatDuration(videocast.duration).toPersianDigit(),
+ style: Theme.of(context)
+ .textTheme
+ .bodySmall
+ ?.copyWith(
+ color: const Color.fromARGB(255, 102, 102, 102),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}