diff --git a/lib/assets/icons/Sort Regular.svg b/lib/assets/icons/Sort Regular.svg new file mode 100644 index 0000000..50d8bf0 --- /dev/null +++ b/lib/assets/icons/Sort Regular.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/assets/icons/pen.svg b/lib/assets/icons/pen.svg new file mode 100644 index 0000000..6e43b59 --- /dev/null +++ b/lib/assets/icons/pen.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/assets/images/empty_states/Image1_fx.jpg b/lib/assets/images/empty_states/Image1_fx.jpg new file mode 100644 index 0000000..6a2d427 Binary files /dev/null and b/lib/assets/images/empty_states/Image1_fx.jpg differ diff --git a/lib/assets/images/empty_states/Image1_fx.png b/lib/assets/images/empty_states/Image1_fx.png new file mode 100644 index 0000000..5f1d379 Binary files /dev/null and b/lib/assets/images/empty_states/Image1_fx.png differ diff --git a/lib/config/theme_data.dart b/lib/config/theme_data.dart index e65c908..57ce4d5 100644 --- a/lib/config/theme_data.dart +++ b/lib/config/theme_data.dart @@ -226,4 +226,4 @@ extension DidvanColorScheme on ColorScheme { Color get success => brightness == Brightness.dark ? const Color(0xFF2FC250) : const Color(0xFF2BB24A); -} \ No newline at end of file +} diff --git a/lib/models/didvan_plus_model.dart b/lib/models/didvan_plus_model.dart new file mode 100644 index 0000000..5ece430 --- /dev/null +++ b/lib/models/didvan_plus_model.dart @@ -0,0 +1,22 @@ +class DidvanPlusModel { + final int id; + final String image; + final String file; + final String publishedAt; + + DidvanPlusModel({ + required this.id, + required this.image, + required this.file, + required this.publishedAt, + }); + + factory DidvanPlusModel.fromJson(Map json) { + return DidvanPlusModel( + id: json['id'], + image: json['image'], + file: json['file'], + publishedAt: json['publishedAt'], + ); + } +} diff --git a/lib/services/network/request_helper.dart b/lib/services/network/request_helper.dart index 0c031fc..d4cd53f 100644 --- a/lib/services/network/request_helper.dart +++ b/lib/services/network/request_helper.dart @@ -23,6 +23,8 @@ class RequestHelper { static const String checkHasPassword = '$_baseUserUrl/checkHasPassword'; static const String mainPageContent = _baseHomeUrl; + static const String didvanPlus = '$baseUrl/didvanPlus'; + static String searchAll({ required int page, String? startDate, diff --git a/lib/utils/extension.dart b/lib/utils/extension.dart index 7e1e27c..b2e7b7f 100644 --- a/lib/utils/extension.dart +++ b/lib/utils/extension.dart @@ -90,4 +90,15 @@ extension StringUrl on String { char; // Replace with English number if exists, else keep original char }).join(''); } + + String convertToPersianDigits() { + const english = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; + const farsi = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']; + + String text = this; + for (int i = 0; i < english.length; i++) { + text = text.replaceAll(english[i], farsi[i]); + } + return text; + } } diff --git a/lib/views/ai/ai_chat_page.dart b/lib/views/ai/ai_chat_page.dart index 0d98c9a..ddcddb6 100644 --- a/lib/views/ai/ai_chat_page.dart +++ b/lib/views/ai/ai_chat_page.dart @@ -425,10 +425,12 @@ class _AiChatPageState extends State with TickerProviderStateMixin { ), ); }, - child: const Text( + child: Text( 'چطور می‌تونم کمکت کنم؟', style: TextStyle( - color: Color.fromARGB(255, 0, 53, 70), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70), fontSize: 16, fontWeight: FontWeight.bold, ), diff --git a/lib/views/ai/history_ai_chat_page.dart b/lib/views/ai/history_ai_chat_page.dart index 85efcfd..8a08d47 100644 --- a/lib/views/ai/history_ai_chat_page.dart +++ b/lib/views/ai/history_ai_chat_page.dart @@ -94,13 +94,13 @@ class _HistoryAiChatPageState extends State { mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Padding( + Padding( padding: EdgeInsets.all(8.0), child: Text('فهرست آرشیوشده‌ها', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, - color: Color.fromARGB(255, 0, 53, 70))), + color: DesignConfig.isDark? const Color.fromARGB(255, 0, 90, 119) : const Color.fromARGB(255, 0, 53, 70))), ), // SearchField( // title: 'گفت‌و‌گو‌ها', diff --git a/lib/views/ai/info_page.dart b/lib/views/ai/info_page.dart index 09f8bdb..0ca2600 100644 --- a/lib/views/ai/info_page.dart +++ b/lib/views/ai/info_page.dart @@ -173,9 +173,9 @@ class _InfoPageState extends State { children: [ Container( margin: const EdgeInsets.only(left: 8), - decoration: const ShapeDecoration( + decoration: ShapeDecoration( shape: CircleBorder( - side: BorderSide(width: 3, color: Colors.black)), + side: BorderSide(width: 3, color: DesignConfig.isDark? Colors.white : Colors.black)), ), ), DidvanText( diff --git a/lib/views/ai/widgets/ai_message_bar.dart b/lib/views/ai/widgets/ai_message_bar.dart index 2cb222c..48e45c2 100644 --- a/lib/views/ai/widgets/ai_message_bar.dart +++ b/lib/views/ai/widgets/ai_message_bar.dart @@ -251,6 +251,7 @@ class _AiMessageBarState extends State { Widget build(BuildContext context) { return Consumer(builder: (context, state, child) { final theme = Theme.of(context); + final isDark = theme.brightness == Brightness.dark; return Container( padding: const EdgeInsets.fromLTRB(12, 24, 12, 0).copyWith( @@ -266,7 +267,9 @@ class _AiMessageBarState extends State { children: [ Container( decoration: BoxDecoration( - color: const Color.fromARGB(255, 245, 245, 245), + color: isDark + ? const Color.fromARGB(255, 50, 50, 50) + : const Color.fromARGB(255, 245, 245, 245), border: Border.all( color: const Color.fromARGB(255, 0, 126, 167), width: 1.5), @@ -357,6 +360,10 @@ class _AiMessageBarState extends State { SvgPicture.asset( 'lib/assets/icons/ChatGPT-Logo.svg', height: 17, + color: DesignConfig.isDark + ? const Color.fromARGB( + 255, 195, 195, 196) + : null, ), const SizedBox(width: 12.0), const DidvanText( @@ -388,6 +395,10 @@ class _AiMessageBarState extends State { children: [ SvgPicture.asset( 'lib/assets/icons/grok.svg', + color: DesignConfig.isDark + ? const Color.fromARGB( + 255, 195, 195, 196) + : null, height: 17, ), const SizedBox(width: 12.0), @@ -411,14 +422,21 @@ class _AiMessageBarState extends State { children: [ SvgPicture.asset( icon, + color: DesignConfig.isDark + ? const Color.fromARGB( + 255, 195, 195, 196) + : null, height: 17, ), const SizedBox(width: 8.0), DidvanText( label, fontSize: 14, - color: const Color.fromARGB( - 255, 61, 61, 61), + color: DesignConfig.isDark + ? const Color.fromARGB( + 255, 195, 195, 196) + : const Color.fromARGB( + 255, 61, 61, 61), ), const SizedBox(width: 4.0), Center( @@ -470,11 +488,11 @@ class _AiMessageBarState extends State { height: 25, ), const SizedBox(width: 8.0), - const DidvanText( + DidvanText( 'جستجو در وب', fontSize: 14, - color: Color.fromARGB( - 255, 61, 61, 61), + color: + theme.colorScheme.inputText, ), ], ), @@ -634,9 +652,13 @@ class _AiMessageBarState extends State { } TextFormField edittext(BuildContext context, AiChatState state) { + final isDark = Theme.of(context).brightness == Brightness.dark; + return TextFormField( textInputAction: TextInputAction.newline, - style: Theme.of(context).textTheme.bodyMedium, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: isDark ? const Color.fromARGB(255, 30, 30, 30) : null, + ), minLines: 1, maxLines: 6, keyboardType: TextInputType.multiline, diff --git a/lib/views/ai_section/ai_section_page.dart b/lib/views/ai_section/ai_section_page.dart index efa9fea..40fa0e6 100644 --- a/lib/views/ai_section/ai_section_page.dart +++ b/lib/views/ai_section/ai_section_page.dart @@ -1,3 +1,4 @@ +import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/models/ai/ai_chat_args.dart'; import 'package:didvan/models/ai/bots_model.dart'; @@ -11,7 +12,6 @@ import 'package:provider/provider.dart'; import 'package:didvan/views/ai/history_ai_chat_state.dart'; import 'package:didvan/views/ai/ai_state.dart'; - class AiSectionPage extends StatefulWidget { const AiSectionPage({super.key}); @@ -33,7 +33,8 @@ class _AiSectionGridItem { }); } -class _AiSectionPageState extends State with TickerProviderStateMixin { +class _AiSectionPageState extends State + with TickerProviderStateMixin { late final List<_AiSectionGridItem> _gridItems; late AnimationController _fadeController; late AnimationController _slideController; @@ -43,22 +44,22 @@ class _AiSectionPageState extends State with TickerProviderStateM @override void initState() { super.initState(); - + _fadeController = AnimationController( duration: const Duration(milliseconds: 800), vsync: this, ); - + _fadeAnimation = CurvedAnimation( parent: _fadeController, curve: Curves.easeIn, ); - + _slideController = AnimationController( duration: const Duration(milliseconds: 1000), vsync: this, ); - + _slideAnimation = Tween( begin: const Offset(0, 0.3), end: Offset.zero, @@ -66,7 +67,7 @@ class _AiSectionPageState extends State with TickerProviderStateM parent: _slideController, curve: Curves.easeOutCubic, )); - + _fadeController.forward(); _slideController.forward(); WidgetsBinding.instance.addPostFrameCallback((_) { @@ -77,11 +78,11 @@ class _AiSectionPageState extends State with TickerProviderStateM final aiState = context.read(); final aiChatState = context.read(); - + aiState.onClearChatCallback = () async { await aiChatState.clearChat(); }; - + aiState.endChat(); if (aiState.tools == null) { aiState.getTools(); @@ -134,7 +135,7 @@ class _AiSectionPageState extends State with TickerProviderStateM onTap: (context) { final aiState = context.read(); aiState.endChat(); - + final aisummeryBot = BotsModel( id: 100, name: 'Aisummery', @@ -142,7 +143,7 @@ class _AiSectionPageState extends State with TickerProviderStateM attachmentType: ['pdf', 'image', 'audio'], attachment: 1, ); - + aiState.startChat(AiChatArgs(bot: aisummeryBot)); }, ), @@ -153,7 +154,7 @@ class _AiSectionPageState extends State with TickerProviderStateM onTap: (context) { final aiState = context.read(); aiState.endChat(); - + final textToSpeechBot = BotsModel( id: 101, name: 'aiaudio', @@ -161,7 +162,7 @@ class _AiSectionPageState extends State with TickerProviderStateM attachmentType: [], attachment: 0, ); - + aiState.startChat(AiChatArgs(bot: textToSpeechBot)); }, ), @@ -172,7 +173,7 @@ class _AiSectionPageState extends State with TickerProviderStateM onTap: (context) { final aiState = context.read(); aiState.endChat(); - + final chartAnalysisBot = BotsModel( id: 27, name: 'chart-analysis', @@ -180,7 +181,7 @@ class _AiSectionPageState extends State with TickerProviderStateM attachmentType: ['image', 'pdf'], attachment: 1, ); - + aiState.startChat(AiChatArgs(bot: chartAnalysisBot)); }, ), @@ -191,7 +192,7 @@ class _AiSectionPageState extends State with TickerProviderStateM onTap: (context) { final aiState = context.read(); aiState.endChat(); - + final aiVideoBot = BotsModel( id: 102, name: 'aivideo', @@ -199,7 +200,7 @@ class _AiSectionPageState extends State with TickerProviderStateM attachmentType: [], attachment: 0, ); - + aiState.startChat(AiChatArgs(bot: aiVideoBot)); }, ), @@ -219,8 +220,7 @@ class _AiSectionPageState extends State with TickerProviderStateM return Column( children: [ - if (!aiState.isChatting) - const HoshanHomeAppBar(), + if (!aiState.isChatting) const HoshanHomeAppBar(), Expanded( child: aiState.isChatting ? AiChatPage(args: aiState.currentChatArgs!) @@ -235,8 +235,11 @@ class _AiSectionPageState extends State with TickerProviderStateM padding: const EdgeInsets.all(20), child: Row( children: [ - SvgPicture.asset('lib/assets/icons/clarity_tools-line.svg'), - const SizedBox(width: 8,), + SvgPicture.asset( + 'lib/assets/icons/clarity_tools-line.svg'), + const SizedBox( + width: 8, + ), DidvanText( 'جعبه ابزار استراتژیک هوشان', style: Theme.of(context).textTheme.titleMedium, @@ -307,14 +310,16 @@ class _AiSectionPageState extends State with TickerProviderStateM child: SizedBox( width: 180, height: 160, - child: _buildGridItemCard(context, _gridItems[columnIndex * 2]), + child: _buildGridItemCard( + context, _gridItems[columnIndex * 2]), ), ), if (columnIndex * 2 + 1 < _gridItems.length) Padding( padding: const EdgeInsets.only(top: 16.0), child: TweenAnimationBuilder( - duration: Duration(milliseconds: 700 + (columnIndex * 100)), + duration: + Duration(milliseconds: 700 + (columnIndex * 100)), tween: Tween(begin: 0.0, end: 1.0), curve: Curves.easeOut, builder: (context, value, child) { @@ -329,7 +334,8 @@ class _AiSectionPageState extends State with TickerProviderStateM child: SizedBox( width: 180, height: 160, - child: _buildGridItemCard(context, _gridItems[columnIndex * 2 + 1]), + child: _buildGridItemCard( + context, _gridItems[columnIndex * 2 + 1]), ), ), ), @@ -381,10 +387,12 @@ class _AnimatedGridCardState extends State<_AnimatedGridCard> { transform: Matrix4.identity() ..translate(0.0, _isHovered ? -8.0 : 0.0), decoration: BoxDecoration( - color: const Color.fromARGB(255, 245, 245, 245), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 78, 82, 84) + : const Color.fromARGB(255, 245, 245, 245), borderRadius: BorderRadius.circular(20), border: Border.all( - color: _isHovered + color: _isHovered ? const Color.fromARGB(255, 0, 126, 167) : const Color.fromARGB(255, 184, 184, 184), width: _isHovered ? 2 : 1, @@ -426,7 +434,7 @@ class _AnimatedGridCardState extends State<_AnimatedGridCard> { ), ), ), - const SizedBox(height: 8), + const SizedBox(height: 8), DidvanText( widget.item.title, style: Theme.of(context).textTheme.titleSmall, @@ -452,4 +460,4 @@ class _AnimatedGridCardState extends State<_AnimatedGridCard> { ), ); } -} \ No newline at end of file +} diff --git a/lib/views/authentication/screens/password.dart b/lib/views/authentication/screens/password.dart index 366b218..fca1350 100644 --- a/lib/views/authentication/screens/password.dart +++ b/lib/views/authentication/screens/password.dart @@ -33,7 +33,8 @@ class _PasswordInputState extends State { onSubmitted: (value) => _onLogin(context), autoFocus: true, title: 'کلمه عبور', - hintText: 'کلمه عبور', + hintText: 'رمز عبور خود را وارد کنید.', + prefixSvgPath: 'lib/assets/icons/key.svg', obsecureText: true, validator: (value) => value.length < 8 ? 'کلمه عبور نمی‌تواند از 8 کاراکتر کمتر باشد' diff --git a/lib/views/authentication/screens/reset_password.dart b/lib/views/authentication/screens/reset_password.dart index 4a655c0..81690c7 100644 --- a/lib/views/authentication/screens/reset_password.dart +++ b/lib/views/authentication/screens/reset_password.dart @@ -35,6 +35,7 @@ class _ResetPasswordState extends State { : null, hintText: 'کلمه عبور جدید', obsecureText: true, + prefixSvgPath: 'lib/assets/icons/key.svg', ), const SizedBox( height: 16, @@ -47,6 +48,7 @@ class _ResetPasswordState extends State { : null, hintText: 'تکرار کلمه عبور جدید', obsecureText: true, + prefixSvgPath: 'lib/assets/icons/key.svg', ), const Spacer(), DidvanButton( diff --git a/lib/views/authentication/screens/username.dart b/lib/views/authentication/screens/username.dart index 3f21d04..70b7023 100644 --- a/lib/views/authentication/screens/username.dart +++ b/lib/views/authentication/screens/username.dart @@ -33,6 +33,7 @@ class _UsernameInputState extends State { title: 'نام کاربری یا شماره موبایل', hintText: 'نام کاربری یا شماره موبایل', textAlign: TextAlign.center, + prefixSvgPath: 'lib/assets/icons/mobile.svg', acceptSpace: false, onSubmitted: (value) => state.confirmUsername(), validator: (value) { @@ -57,7 +58,7 @@ class _UsernameInputState extends State { ), ), DidvanButton( - title: 'ورود', + title: 'ادامه', onPressed: () { if (_formKey.currentState!.validate()) { state.confirmUsername(); @@ -72,7 +73,7 @@ class _UsernameInputState extends State { text: TextSpan( style: Theme.of(context).textTheme.bodySmall, children: [ - const TextSpan(text: 'با ورود به دیدوان،'), + const TextSpan(text: 'با ورود به اپلیکیشن دیدوان،'), TextSpan( text: ' شرایط ', style: Theme.of(context) diff --git a/lib/views/authentication/screens/verification.dart b/lib/views/authentication/screens/verification.dart index 6d0ec09..aaf69e0 100644 --- a/lib/views/authentication/screens/verification.dart +++ b/lib/views/authentication/screens/verification.dart @@ -2,9 +2,16 @@ import 'dart:async'; +// START: Added Imports +import 'package:flutter/gestures.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:url_launcher/url_launcher_string.dart'; +// END: Added Imports + import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/providers/user.dart'; +import 'package:didvan/utils/extension.dart'; import 'package:didvan/views/authentication/authentication_state.dart'; import 'package:didvan/views/authentication/widgets/authentication_layout.dart'; import 'package:didvan/views/widgets/didvan/button.dart'; @@ -27,6 +34,12 @@ class _VerificationState extends State { int _secondsRemaining = 119; bool _isResendButtonEnabled = false; + bool _isConfirmButtonEnabled = false; + String _completedCode = ""; + + // START: Added state for error + bool _hasError = false; + // END: Added state @override void initState() { @@ -43,7 +56,7 @@ class _VerificationState extends State { super.initState(); _listenForSms(); } - + Future _listenForSms() async { if (kDebugMode) { print("<<<<< در حال تلاش برای دریافت امضای برنامه >>>>>"); @@ -56,39 +69,84 @@ class _VerificationState extends State { } await SmsAutoFill().listenForCode(); -} - + } @override Widget build(BuildContext context) { final AuthenticationState state = context.read(); + + // START: Define colors for PinTheme + final errorColor = Theme.of(context).colorScheme.error; + final primaryColor = Theme.of(context).colorScheme.primary; + final borderColor = Theme.of(context).colorScheme.border; + final textColor = Theme.of(context).colorScheme.text; + // END: Define colors + return WillPopScope( onWillPop: () async { _timer?.cancel(); - return true; + + // منطق بازگشت هماهنگ با authentication.dart + if (state.currentPageIndex == 0) { + return true; + } + if (state.currentPageIndex == 2 && !state.hasPassword) { + state.currentPageIndex = 0; // برگرد به صفحه نام کاربری + return false; + } + state.currentPageIndex--; // در غیر این صورت یکی برگرد + return false; }, child: AuthenticationLayout( appBarTitle: 'تغییر رمز عبور', children: [ - DidvanText( - 'کد 6 رقمی ارسال شده به موبایل', - style: Theme.of(context).textTheme.titleSmall, - fontWeight: FontWeight.normal, + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + children: [ + DidvanText('کد تایید پنج رقمی به شماره ', + style: Theme.of(context).textTheme.titleSmall, + fontWeight: FontWeight.normal, + color: Theme.of(context).colorScheme.caption), + DidvanText( + state.username.toString().convertToPersianDigits(), + style: Theme.of(context).textTheme.titleMedium?.copyWith( + fontWeight: FontWeight.normal, + fontSize: 15, + color: Theme.of(context).colorScheme.caption), + ), + DidvanText(' ارسال شد.', + style: Theme.of(context).textTheme.titleSmall, + fontWeight: FontWeight.normal, + color: Theme.of(context).colorScheme.caption), + ], ), - const SizedBox( - height: 8, - ), - DidvanText( - state.username, - style: Theme.of(context).textTheme.titleMedium, - ), - const SizedBox( - height: 8, - ), - DidvanText( - 'را وارد کنید:', - style: Theme.of(context).textTheme.titleSmall, - fontWeight: FontWeight.normal, + const SizedBox(height: 8), + InkWell( + onTap: () { + _timer?.cancel(); // لغو تایمر + state.currentPageIndex = 0; // بازگشت به صفحه ورود شماره + }, + borderRadius: DesignConfig.lowBorderRadius, + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0), + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset('lib/assets/icons/pen.svg',height: 20,), + const SizedBox(width: 8), + DidvanText( + 'شماره همراه', + style: Theme.of(context).textTheme.titleSmall, + fontWeight: FontWeight.normal, + color: primaryColor, + ), + ], + ), + ), ), const SizedBox( height: 24, @@ -98,43 +156,154 @@ class _VerificationState extends State { child: PinCodeTextField( keyboardType: TextInputType.number, animationType: AnimationType.scale, - cursorColor: Theme.of(context).colorScheme.text, + cursorColor: textColor, + // START: Added textStyle for error color + textStyle: TextStyle( + fontSize: 20, // اندازه فونت را متناسب تنظیم کنید + color: _hasError ? const Color.fromARGB(255, 178, 4, 54) : textColor, + ), + // END: Added textStyle pinTheme: PinTheme( - fieldHeight: 48, - fieldWidth: 48, - selectedColor: Theme.of(context).colorScheme.primary, - inactiveColor: Theme.of(context).colorScheme.border, - activeFillColor: Theme.of(context).colorScheme.primary, - activeColor: Theme.of(context).colorScheme.primary, + fieldHeight: 58, + fieldWidth: 58, + // START: Dynamic border/bg colors + selectedColor: _hasError ? const Color.fromARGB(255, 178, 4, 54) : primaryColor, + inactiveColor: _hasError ? const Color.fromARGB(255, 178, 4, 54) : borderColor, + activeFillColor: _hasError ? const Color.fromARGB(255, 178, 4, 54) : primaryColor, // بستگی به طراحی شما دارد + activeColor: _hasError ? const Color.fromARGB(255, 178, 4, 54) : primaryColor, + // END: Dynamic colors borderRadius: DesignConfig.lowBorderRadius, borderWidth: 1, shape: PinCodeFieldShape.box, ), appContext: context, length: 6, + // START: Modified onCompleted onCompleted: (value) async { final result = await state.verifyOtpToken(value); if (result) { _timer?.cancel(); } }, - onChanged: (value) {}, + // END: Modified onCompleted + // START: Modified onChanged + onChanged: (value) { + setState(() { + _completedCode = value; + _isConfirmButtonEnabled = value.length == 6; + if (_hasError) { + _hasError = false; // پاک کردن خطا با شروع تایپ + } + }); + }, + // END: Modified onChanged ), ), - const Spacer(), + + // ویجت ارسال مجدد کد + const SizedBox( + height: 24, + ), + _isResendButtonEnabled + ? InkWell( + onTap: () { + _handleTimer(); // ری‌استارت تایمر + state.sendOtpToken(); // ارسال مجدد کد + }, + borderRadius: DesignConfig.lowBorderRadius, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0, vertical: 4.0), + child: DidvanText( + 'دریافت مجدد کد', + style: Theme.of(context).textTheme.titleSmall, + fontWeight: FontWeight.normal, + color: const Color.fromARGB(255, 0 ,126, 167), + ), + ), + ) + : Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset('lib/assets/icons/clock.svg',color: const Color.fromARGB(255, 0 ,126, 167) ,), + const SizedBox(width: 5,), + DidvanText( + '$_secondsRemaining ثانیه', + style: Theme.of(context).textTheme.titleSmall?.copyWith( + fontWeight: FontWeight.normal, + color: const Color.fromARGB(255, 0 ,126, 167), + ), + ), + DidvanText( + ' تا دریافت مجدد کد', + style: Theme.of(context).textTheme.titleSmall, + fontWeight: FontWeight.normal, + color: const Color.fromARGB(255, 0 ,126, 167), + ), + ], + ), + + const Spacer(), // دکمه را به پایین صفحه می‌چسباند DidvanButton( - enabled: _isResendButtonEnabled, - onPressed: () { - _handleTimer(); - state.sendOtpToken(); + enabled: _isConfirmButtonEnabled, + // START: Modified onPressed + onPressed: () async { + if (_completedCode.length == 6) { + final result = await state.verifyOtpToken(_completedCode); + if (!result) { + if (mounted) setState(() => _hasError = true); + } + // در صورت موفقیت، onCompleted خودش کار را انجام می‌دهد + } }, - title: !_isResendButtonEnabled - ? '$_secondsRemaining ثانیه دیگر' - : 'ارسال مجدد کد', + // END: Modified onPressed + title: 'تایید کد', + ), + + // START: Added Terms and Conditions RichText + const SizedBox( + height: 24, // فاصله بین دکمه و متن قوانین + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 60), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + style: Theme.of(context).textTheme.bodySmall, + children: [ + const TextSpan(text: 'با ورود به اپلیکیشن دیدوان،'), + TextSpan( + text: ' شرایط ', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Theme.of(context).colorScheme.primary), + recognizer: TapGestureRecognizer() + ..onTap = () => launchUrlString( + 'https://didvan.com/terms-of-use#conditions', + mode: LaunchMode.inAppWebView), + ), + const TextSpan(text: 'و\n'), + TextSpan( + text: ' قوانین حریم خصوصی ', + style: Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Theme.of(context).colorScheme.primary), + recognizer: TapGestureRecognizer() + ..onTap = () => launchUrlString( + 'https://didvan.com/terms-of-use#privacy', + mode: LaunchMode.inAppWebView), + ), + const TextSpan(text: 'را می‌پذیرم'), + ], + ), + ), ), const SizedBox( - height: 48, + height: 24, // پدینگ نهایی پایین صفحه ), + // END: Added RichText ], ), ); @@ -159,4 +328,4 @@ class _VerificationState extends State { }); setState(() {}); } -} +} \ No newline at end of file diff --git a/lib/views/comments/comments.dart b/lib/views/comments/comments.dart index 3f9af75..ad036cc 100644 --- a/lib/views/comments/comments.dart +++ b/lib/views/comments/comments.dart @@ -1,3 +1,5 @@ +// ignore_for_file: deprecated_member_use + import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/assets.dart'; @@ -192,7 +194,7 @@ class _CommentMessageBoxState extends State { Container( padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), decoration: BoxDecoration( - color: const Color.fromARGB(255, 243, 243, 243), + color: Theme.of(context).colorScheme.focused, border: Border.all(color: Theme.of(context).colorScheme.border), borderRadius: BorderRadius.circular(32), ), @@ -210,10 +212,9 @@ class _CommentMessageBoxState extends State { decoration: InputDecoration( border: InputBorder.none, hintText: 'دیدگاه‌های خود را بنویسید...', - hintStyle: Theme.of(context) - .textTheme - .bodySmall! - .copyWith(color: Colors.black), + hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( + color: + DesignConfig.isDark ? Colors.white : Colors.black), ), onChanged: (value) => state.text = value, ), diff --git a/lib/views/comments/widgets/comment.dart b/lib/views/comments/widgets/comment.dart index 2bb3ea7..e87a62c 100644 --- a/lib/views/comments/widgets/comment.dart +++ b/lib/views/comments/widgets/comment.dart @@ -94,10 +94,10 @@ class CommentState extends State { children: [ DidvanText( comment.user.fullName, - style: const TextStyle( + style: TextStyle( fontSize: 16, fontWeight: FontWeight.normal, - color: Color.fromARGB(255, 102, 102, 102)), + color: Theme.of(context).colorScheme.caption), ), const SizedBox(height: 4), DidvanText( @@ -122,7 +122,7 @@ class CommentState extends State { const SizedBox(height: 8), DidvanText( comment.text, - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), const SizedBox(height: 8), if (comment.status == 2) @@ -180,7 +180,7 @@ class CommentState extends State { child: DidvanText( 'پاسخ', style: Theme.of(context).textTheme.bodySmall, - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ], diff --git a/lib/views/direct/direct.dart b/lib/views/direct/direct.dart index da5fea5..d815824 100644 --- a/lib/views/direct/direct.dart +++ b/lib/views/direct/direct.dart @@ -1,5 +1,7 @@ // ignore_for_file: deprecated_member_use +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/models/enums.dart'; @@ -137,7 +139,7 @@ class _DirectState extends State { .textTheme .headlineSmall ?.copyWith( - color: const Color.fromARGB(255, 0, 53, 70), + color: DesignConfig.isDark? const Color.fromARGB(255, 0, 90, 119) : const Color.fromARGB(255, 0, 53, 70), fontWeight: FontWeight.bold, fontSize: 19), ), @@ -148,8 +150,8 @@ class _DirectState extends State { 'lib/assets/icons/arrow-left.svg', width: 30, height: 30, - colorFilter: const ColorFilter.mode( - Color.fromARGB(255, 102, 102, 102), + colorFilter: ColorFilter.mode( + Theme.of(context).colorScheme.caption, BlendMode.srcIn), ), ), diff --git a/lib/views/direct/widgets/audio_widget.dart b/lib/views/direct/widgets/audio_widget.dart index 3c92884..2bdb385 100644 --- a/lib/views/direct/widgets/audio_widget.dart +++ b/lib/views/direct/widgets/audio_widget.dart @@ -84,9 +84,9 @@ class AudioWidget extends StatelessWidget { width: 45, child: Text( _formatDuration(totalDuration), - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: Color.fromARGB(255, 102, 102, 102)), + color: Theme.of(context).colorScheme.caption), textAlign: TextAlign.center, ), ), @@ -111,9 +111,9 @@ class AudioWidget extends StatelessWidget { width: 45, child: Text( _formatDuration(currentPosition), - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: Color.fromARGB(255, 102, 102, 102)), + color: Theme.of(context).colorScheme.caption), textAlign: TextAlign.center, ), ), diff --git a/lib/views/direct/widgets/message.dart b/lib/views/direct/widgets/message.dart index ff329ea..844636c 100644 --- a/lib/views/direct/widgets/message.dart +++ b/lib/views/direct/widgets/message.dart @@ -107,8 +107,8 @@ class _MessageState extends State with SingleTickerProviderStateMixin { child: Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(4), - decoration: const BoxDecoration( - color: Color.fromARGB(255, 200, 224, 244), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.splash, borderRadius: DesignConfig.mediumBorderRadius, ), child: Padding( @@ -189,6 +189,9 @@ class _MessageState extends State with SingleTickerProviderStateMixin { 'lib/assets/icons/Didvan.svg', width: 12, height: 12, + color: DesignConfig.isDark + ? Colors.white + : null, ), ), )) @@ -226,10 +229,12 @@ class _MessageState extends State with SingleTickerProviderStateMixin { width: 1, ), ), - child: const Icon( + child: Icon( Icons.person_rounded, size: 12, - color: Colors.black, + color: DesignConfig.isDark + ? Colors.white + : Colors.black, ), ); }, @@ -247,10 +252,12 @@ class _MessageState extends State with SingleTickerProviderStateMixin { width: 1, ), ), - child: const Icon( + child: Icon( Icons.person_rounded, size: 12, - color: Colors.black, + color: DesignConfig.isDark + ? Colors.white + : Colors.black, ), ), ), diff --git a/lib/views/direct/widgets/message_box.dart b/lib/views/direct/widgets/message_box.dart index 738bdbe..f155861 100644 --- a/lib/views/direct/widgets/message_box.dart +++ b/lib/views/direct/widgets/message_box.dart @@ -126,6 +126,8 @@ class _TypingState extends State<_Typing> { @override Widget build(BuildContext context) { final state = context.watch(); + final isDark = Theme.of(context).brightness == Brightness.dark; + return Row( children: [ Expanded( @@ -134,10 +136,16 @@ class _TypingState extends State<_Typing> { child: TextFormField( controller: state.textController, textInputAction: TextInputAction.send, - style: Theme.of(context).textTheme.bodyMedium, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: isDark + ? const Color.fromARGB(255, 230, 230, 230) + : null, + ), decoration: InputDecoration( filled: true, - fillColor: const Color.fromARGB(255, 234, 235, 235), + fillColor: isDark + ? const Color.fromARGB(255, 50, 50, 50) + : const Color.fromARGB(255, 234, 235, 235), border: OutlineInputBorder( borderRadius: BorderRadius.circular(32.0), borderSide: BorderSide.none, @@ -154,7 +162,7 @@ class _TypingState extends State<_Typing> { hintStyle: Theme.of(context) .textTheme .bodySmall! - .copyWith(color: const Color.fromARGB(255, 102, 102, 102)), + .copyWith(color: Theme.of(context).colorScheme.caption), contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), prefixIcon: Padding( diff --git a/lib/views/home/bookmarks/bookmarks.dart b/lib/views/home/bookmarks/bookmarks.dart index a719ca7..1750e2a 100644 --- a/lib/views/home/bookmarks/bookmarks.dart +++ b/lib/views/home/bookmarks/bookmarks.dart @@ -1,4 +1,4 @@ -// ignore_for_file: unused_element_parameter +// ignore_for_file: unused_element_parameter, deprecated_member_use import 'dart:async'; @@ -210,8 +210,7 @@ class _BookmarksState extends State { 'lib/assets/icons/New_Profile.svg', width: 30, height: 30, - color: - const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ), @@ -226,8 +225,7 @@ class _BookmarksState extends State { 'lib/assets/icons/arrow-left.svg', width: 25, height: 25, - color: - const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ), @@ -274,7 +272,7 @@ class _BookmarksState extends State { color: Theme.of(context).colorScheme.surface, borderRadius: BorderRadius.circular(16), border: Border.all( - color: const Color.fromARGB(255, 224, 224, 224), + color: Theme.of(context).colorScheme.focused, width: 1, ), boxShadow: [ @@ -292,7 +290,7 @@ class _BookmarksState extends State { width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( - color: const Color.fromARGB(255, 230, 243, 250), + color: Theme.of(context).colorScheme.focused, borderRadius: BorderRadius.circular(16), ), child: Center( @@ -302,7 +300,9 @@ class _BookmarksState extends State { .textTheme .titleMedium ?.copyWith( - color: Colors.black, + color: DesignConfig.isDark + ? Colors.white + : Colors.black, fontWeight: FontWeight.normal, fontSize: 15), ), @@ -317,9 +317,10 @@ class _BookmarksState extends State { "lib/assets/icons/Stratzhic Radar.svg", width: 20, ), - titleWidget: const DidvanText('رادارهای استراتژیک', + titleWidget: DidvanText('رادارهای استراتژیک', style: TextStyle( - color: Color.fromARGB(255, 102, 102, 102))), + color: + Theme.of(context).colorScheme.caption)), ), ), const _FadeInSlide( @@ -334,9 +335,10 @@ class _BookmarksState extends State { "lib/assets/icons/Donye_Foolad.svg", width: 20, ), - titleWidget: const DidvanText('دنیای فولاد', + titleWidget: DidvanText('دنیای فولاد', style: TextStyle( - color: Color.fromARGB(255, 102, 102, 102))), + color: + Theme.of(context).colorScheme.caption)), ), ), const _FadeInSlide( @@ -351,9 +353,10 @@ class _BookmarksState extends State { "lib/assets/icons/Pouyesh_Ofogh_New.svg", width: 20, ), - titleWidget: const DidvanText('پویش افق', + titleWidget: DidvanText('پویش افق', style: TextStyle( - color: Color.fromARGB(255, 102, 102, 102))), + color: + Theme.of(context).colorScheme.caption)), ), ), const _FadeInSlide( @@ -369,9 +372,10 @@ class _BookmarksState extends State { color: const Color.fromARGB(255, 0, 126, 167), width: 20, ), - titleWidget: const DidvanText('ویدیو‌کست', + titleWidget: DidvanText('ویدیو‌کست', style: TextStyle( - color: Color.fromARGB(255, 102, 102, 102))), + color: + Theme.of(context).colorScheme.caption)), ), ), const _FadeInSlide( @@ -387,9 +391,10 @@ class _BookmarksState extends State { color: const Color.fromARGB(255, 0, 126, 167), width: 20, ), - titleWidget: const DidvanText('پادکست', + titleWidget: DidvanText('پادکست', style: TextStyle( - color: Color.fromARGB(255, 102, 102, 102))), + color: + Theme.of(context).colorScheme.caption)), ), ), const _FadeInSlide( @@ -404,9 +409,10 @@ class _BookmarksState extends State { "lib/assets/icons/Saha.svg", width: 20, ), - titleWidget: const DidvanText('سها', + titleWidget: DidvanText('سها', style: TextStyle( - color: Color.fromARGB(255, 102, 102, 102))), + color: + Theme.of(context).colorScheme.caption)), ), ), const _FadeInSlide( @@ -422,9 +428,10 @@ class _BookmarksState extends State { color: const Color.fromARGB(255, 0, 126, 167), width: 20, ), - titleWidget: const DidvanText('اینفوگرافی', + titleWidget: DidvanText('اینفوگرافی', style: TextStyle( - color: Color.fromARGB(255, 102, 102, 102))), + color: + Theme.of(context).colorScheme.caption)), ), ), const _FadeInSlide( @@ -435,10 +442,10 @@ class _BookmarksState extends State { delay: const Duration(milliseconds: 800), child: MenuOption( onTap: () => _onCategorySelected(8), - titleWidget: const DidvanText( - 'ماژول بایدها و نبایدها', + titleWidget: DidvanText('ماژول بایدها و نبایدها', style: TextStyle( - color: Color.fromARGB(255, 102, 102, 102))), + color: + Theme.of(context).colorScheme.caption)), iconWidget: SvgPicture.asset( "lib/assets/icons/Swot_New.svg", width: 24), @@ -453,9 +460,10 @@ class _BookmarksState extends State { delay: const Duration(milliseconds: 900), child: MenuOption( onTap: () => _onCategorySelected(9), - titleWidget: const DidvanText('ماهنامه تحلیلی', + titleWidget: DidvanText('ماهنامه تحلیلی', style: TextStyle( - color: Color.fromARGB(255, 102, 102, 102))), + color: + Theme.of(context).colorScheme.caption)), iconWidget: SvgPicture.asset( "lib/assets/icons/Monthly.svg", width: 24), @@ -633,7 +641,7 @@ class _FadeInSlide extends StatefulWidget { this.delay = Duration.zero, // ignore: unused_element_parameter this.duration = const Duration(milliseconds: 400), - this.slideOffset = 50.0, // میزانی که ویجت از پایین به بالا حرکت می‌کند + this.slideOffset = 50.0, }) : super(key: key); @override diff --git a/lib/views/home/explore/explore.dart b/lib/views/home/explore/explore.dart index 9a17b4f..7c36593 100644 --- a/lib/views/home/explore/explore.dart +++ b/lib/views/home/explore/explore.dart @@ -1,3 +1,5 @@ +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/main.dart'; import 'package:didvan/models/home_page_content/home_page_list.dart'; import 'package:didvan/models/home_page_content/swot.dart'; @@ -281,7 +283,9 @@ class SwotSection extends StatelessWidget { DidvanText( "ماژول بایدها و نبایدها", style: Theme.of(context).textTheme.titleSmall, - color: const Color.fromARGB(255, 0, 89, 119), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 125, 166) + : const Color.fromARGB(255, 0, 89, 119), ), ], ), @@ -493,7 +497,9 @@ class MainPageSection extends StatelessWidget { headerText, style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w500), - color: const Color.fromARGB(255, 0, 89, 119), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 125, 166) + : const Color.fromARGB(255, 0, 89, 119), ), ], ), @@ -562,7 +568,6 @@ class MainPageSection extends StatelessWidget { print('======================='); } - // Open PDF viewer directly Navigator.of(context).pushNamed( Routes.pdfViewer, arguments: { @@ -579,7 +584,9 @@ class MainPageSection extends StatelessWidget { margin: const EdgeInsets.symmetric(vertical: 3, horizontal: 5), decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 36, 36, 36) + : Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: const Color.fromARGB(255, 184, 184, 184), @@ -609,8 +616,10 @@ class MainPageSection extends StatelessWidget { children: [ Text( item.title, - style: const TextStyle( - color: Colors.black, + style: TextStyle( + color: DesignConfig.isDark + ? Colors.white + : Colors.black, fontWeight: FontWeight.bold, fontSize: 15), maxLines: 3, @@ -683,7 +692,9 @@ class MainPageSection extends StatelessWidget { child: Container( margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 36, 36, 36) + : Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: const Color.fromARGB(255, 184, 184, 184), @@ -711,8 +722,10 @@ class MainPageSection extends StatelessWidget { Text( item.title, textAlign: TextAlign.start, - style: const TextStyle( - color: Colors.black, + style: TextStyle( + color: DesignConfig.isDark + ? Colors.white + : Colors.black, fontWeight: FontWeight.bold), maxLines: 1, overflow: TextOverflow.ellipsis, @@ -731,8 +744,9 @@ class MainPageSection extends StatelessWidget { Text( DateTime.parse(item.subtitles.first) .toPersianDateStr(), - style: const TextStyle( - color: Color.fromARGB(255, 102, 102, 102), + style: TextStyle( + color: + Theme.of(context).colorScheme.caption, fontSize: 12), ), ], @@ -760,7 +774,9 @@ class MainPageSection extends StatelessWidget { child: Container( margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 36, 36, 36) + : Colors.white, borderRadius: BorderRadius.circular(20), border: Border.all( color: const Color.fromARGB(255, 184, 184, 184))), @@ -783,8 +799,10 @@ class MainPageSection extends StatelessWidget { child: Text( item.title, textAlign: TextAlign.start, - style: const TextStyle( - color: Colors.black, + style: TextStyle( + color: DesignConfig.isDark + ? Colors.white + : Colors.black, fontWeight: FontWeight.bold), maxLines: 1, overflow: TextOverflow.ellipsis, @@ -806,8 +824,9 @@ class MainPageSection extends StatelessWidget { Text( DateTime.parse(item.subtitles.first) .toPersianDateStr(), - style: const TextStyle( - color: Color.fromARGB(255, 102, 102, 102), + style: TextStyle( + color: + Theme.of(context).colorScheme.caption, fontSize: 12), ), ], @@ -854,7 +873,9 @@ class MainPageSection extends StatelessWidget { child: Container( margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 36, 36, 36) + : Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: const Color.fromARGB(255, 184, 184, 184), @@ -874,8 +895,10 @@ class MainPageSection extends StatelessWidget { Text( item.title, textAlign: TextAlign.start, - style: const TextStyle( - color: Colors.black, + style: TextStyle( + color: DesignConfig.isDark + ? Colors.white + : Colors.black, fontWeight: FontWeight.bold), maxLines: 3, overflow: TextOverflow.ellipsis, @@ -892,9 +915,10 @@ class MainPageSection extends StatelessWidget { ), Text( item.subtitles.last, - style: const TextStyle( - color: - Color.fromARGB(255, 102, 102, 102)), + style: TextStyle( + color: Theme.of(context) + .colorScheme + .caption), ), ], ) @@ -943,7 +967,9 @@ class MainPageSection extends StatelessWidget { child: Container( margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 36, 36, 36) + : Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: const Color.fromARGB(255, 184, 184, 184), @@ -971,8 +997,10 @@ class MainPageSection extends StatelessWidget { Text( item.title, textAlign: TextAlign.start, - style: const TextStyle( - color: Colors.black, + style: TextStyle( + color: DesignConfig.isDark + ? Colors.white + : Colors.black, fontWeight: FontWeight.bold), maxLines: 1, overflow: TextOverflow.ellipsis, @@ -1023,7 +1051,9 @@ class MainPageSection extends StatelessWidget { child: Container( margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 36, 36, 36) + : Colors.white, borderRadius: BorderRadius.circular(20), border: Border.all( color: const Color.fromARGB(255, 184, 184, 184))), @@ -1041,8 +1071,10 @@ class MainPageSection extends StatelessWidget { child: Text( item.title, textAlign: TextAlign.start, - style: const TextStyle( - color: Colors.black, + style: TextStyle( + color: DesignConfig.isDark + ? Colors.white + : Colors.black, fontWeight: FontWeight.bold), maxLines: 1, overflow: TextOverflow.ellipsis, @@ -1105,7 +1137,9 @@ class MainPageSection extends StatelessWidget { child: Container( margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 36, 36, 36) + : Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: const Color.fromARGB(255, 184, 184, 184), @@ -1138,8 +1172,10 @@ class MainPageSection extends StatelessWidget { Text( item.title, textAlign: TextAlign.start, - style: const TextStyle( - color: Colors.black, + style: TextStyle( + color: DesignConfig.isDark + ? Colors.white + : Colors.black, fontWeight: FontWeight.bold), maxLines: 3, overflow: TextOverflow.ellipsis, @@ -1171,10 +1207,14 @@ class MainPageSection extends StatelessWidget { height: 10, ), Container( - decoration: const BoxDecoration( - color: Color.fromARGB(255, 235, 235, 235), - borderRadius: - BorderRadius.all(Radius.circular(8)), + decoration: BoxDecoration( + color: DesignConfig.isDark + ? const Color.fromARGB( + 255, 188, 188, 188) + : const Color.fromARGB( + 255, 235, 235, 235), + borderRadius: const BorderRadius.all( + Radius.circular(8)), ), child: Padding( padding: const EdgeInsets.all(8.0), @@ -1224,7 +1264,7 @@ class MainPageSection extends StatelessWidget { child: Container( margin: const EdgeInsets.symmetric(horizontal: 4), decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark ? Colors.black : Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: const Color.fromARGB(255, 184, 184, 184), @@ -1252,8 +1292,10 @@ class MainPageSection extends StatelessWidget { Text( item.title, textAlign: TextAlign.start, - style: const TextStyle( - color: Colors.black, + style: TextStyle( + color: DesignConfig.isDark + ? Colors.white + : Colors.black, fontWeight: FontWeight.bold), maxLines: 2, overflow: TextOverflow.ellipsis, diff --git a/lib/views/home/home.dart b/lib/views/home/home.dart index d593f76..d968502 100644 --- a/lib/views/home/home.dart +++ b/lib/views/home/home.dart @@ -75,9 +75,11 @@ class _HomeState extends State Widget build(BuildContext context) { return Scaffold( key: homeScaffKey, + // ignore: deprecated_member_use backgroundColor: Theme.of(context).colorScheme.background, resizeToAvoidBottomInset: false, drawer: null, + // ignore: deprecated_member_use body: WillPopScope( onWillPop: () async { if (context.read().tabController.index == 0) { diff --git a/lib/views/home/main/main_page.dart b/lib/views/home/main/main_page.dart index f025ec5..626a05e 100644 --- a/lib/views/home/main/main_page.dart +++ b/lib/views/home/main/main_page.dart @@ -1,11 +1,16 @@ +import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; +import 'package:didvan/models/home_page_content/content.dart'; import 'package:didvan/models/home_page_content/home_page_list.dart'; import 'package:didvan/models/home_page_content/swot.dart'; +import 'package:didvan/services/app_initalizer.dart'; +import 'package:didvan/services/network/request.dart'; import 'package:didvan/views/home/explore/explore.dart'; import 'package:didvan/views/home/main/main_page_state.dart'; import 'package:didvan/views/home/main/widgets/main_content.dart'; import 'package:didvan/views/home/main/widgets/story_section.dart'; import 'package:didvan/views/home/main/widgets/simple_explore_card.dart'; +import 'package:didvan/views/home/main/widgets/didvan_plus_section.dart'; import 'package:didvan/views/home/new_statistic/new_statistics_state.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; @@ -18,6 +23,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; import 'package:flutter_animate/flutter_animate.dart'; +import 'package:url_launcher/url_launcher_string.dart'; import 'package:flutter/foundation.dart' show kIsWeb, defaultTargetPlatform; @@ -74,14 +80,20 @@ class _MainPageState extends State { const TextDivider(text: 'دیده‌بان') .animate() .fadeIn(delay: 400.ms, duration: 500.ms), - // const _DidvanSignalsTitle() - // .animate() - // .fadeIn(delay: 500.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), ], + if (state.didvanPlus != null) ...[ + const SizedBox(height: 16), + DidvanPlusSection(didvanPlus: state.didvanPlus!) + .animate() + .fadeIn(delay: 650.ms, duration: 500.ms), + ], const SizedBox(height: 12), const TextDivider(text: 'پیشخوان استراتژیک') .animate() @@ -120,38 +132,38 @@ class _MainPageState extends State { } } -// class _DidvanSignalsTitle extends StatelessWidget { -// const _DidvanSignalsTitle(); +class _DidvanSignalsTitle extends StatelessWidget { + const _DidvanSignalsTitle(); -// @override -// Widget build(BuildContext context) { -// return Padding( -// padding: const EdgeInsets.only( -// left: 16, -// right: 16, -// bottom: 16, -// top: 0, -// ), -// child: Row( -// children: [ -// SvgPicture.asset( -// 'lib/assets/icons/voice-square.svg', -// color: Theme.of(context).colorScheme.title, -// width: 30, -// height: 30, -// ), -// const SizedBox(width: 5), -// DidvanText( -// "سیگنال‌های دیدوان", -// style: Theme.of(context).textTheme.titleMedium, -// color: const Color.fromARGB(255, 0, 89, 119), -// fontSize: 13, -// ), -// ], -// ), -// ); -// } -// } + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only( + left: 16, + right: 16, + bottom: 16, + top: 0, + ), + child: Row( + children: [ + SvgPicture.asset( + 'lib/assets/icons/voice-square.svg', + color: Theme.of(context).colorScheme.title, + width: 30, + height: 30, + ), + const SizedBox(width: 5), + DidvanText( + "سیگنال‌های دیدوان", + style: Theme.of(context).textTheme.titleMedium, + color: const Color.fromARGB(255, 0, 89, 119), + fontSize: 13, + ), + ], + ), + ); + } +} class _ExploreLatestTitle extends StatelessWidget { const _ExploreLatestTitle(); @@ -180,7 +192,7 @@ class _ExploreLatestTitle extends StatelessWidget { DidvanText( "تازه‌ترین‌های کاوش", style: Theme.of(context).textTheme.titleMedium, - color: const Color.fromARGB(255, 0, 89, 119), + color: DesignConfig.isDark ? const Color.fromARGB(255, 0, 125, 166) : const Color.fromARGB(255, 0, 89, 119), fontSize: 13, ), ], @@ -215,6 +227,8 @@ class _ExploreLatestSlider extends StatelessWidget { @override Widget build(BuildContext context) { final List items = []; + final List<({String type, MainPageContentType? content, SwotItem? swotItem})> itemsData = []; + for (var list in lists) { if (list.type == 'video' || list.type == 'podcast' || @@ -233,6 +247,7 @@ class _ExploreLatestSlider extends StatelessWidget { ), ), ); + itemsData.add((type: list.type, content: newestContent, swotItem: null)); } } @@ -245,6 +260,7 @@ class _ExploreLatestSlider extends StatelessWidget { ), ), ); + itemsData.add((type: 'swot', content: null, swotItem: swotItems.first)); } if (items.isEmpty) { @@ -259,6 +275,23 @@ class _ExploreLatestSlider extends StatelessWidget { onItemChanged: (index) { // Optional: Handle item change if needed }, + onItemTap: (index) { + final data = itemsData[index]; + if (data.swotItem != null) { + AppInitializer.openWebLink( + context, + 'http://opportunity-threat.didvan.com/posts/${data.swotItem!.id}/?accessToken=${RequestService.token}', + mode: LaunchMode.inAppWebView, + ); + } else if (data.content != null) { + context.read().navigationHandler( + data.type, + data.content!.id, + data.content!.link, + description: data.content!.title, + ); + } + }, ); } } diff --git a/lib/views/home/main/main_page_state.dart b/lib/views/home/main/main_page_state.dart index 89ec7ef..82b2ca9 100644 --- a/lib/views/home/main/main_page_state.dart +++ b/lib/views/home/main/main_page_state.dart @@ -1,4 +1,5 @@ import 'package:didvan/main.dart'; +import 'package:didvan/models/didvan_plus_model.dart'; import 'package:didvan/models/enums.dart'; import 'package:didvan/models/home_page_content/content.dart'; import 'package:didvan/models/home_page_content/home_page_content.dart'; @@ -22,6 +23,7 @@ class MainPageState extends CoreProvier { int unread = 0; List stories = []; List swotItems = []; + DidvanPlusModel? didvanPlus; Future _getMainPageContent() async { final service = RequestService(RequestHelper.mainPageContent); @@ -49,6 +51,29 @@ class MainPageState extends CoreProvier { } } + Future _getDidvanPlus() async { + debugPrint('🎬 Fetching Didvan Plus data...'); + try { + final service = RequestService(RequestHelper.didvanPlus); + await service.httpGet(); + debugPrint('🎬 Didvan Plus response: ${service.isSuccess}'); + debugPrint('🎬 Didvan Plus result: ${service.result}'); + + if (service.isSuccess) { + final data = service.result['result'] ?? service.result; + didvanPlus = DidvanPlusModel.fromJson(data); + debugPrint('✅ Didvan Plus loaded: ${didvanPlus?.id}'); + debugPrint('✅ Video file: ${didvanPlus?.file}'); + debugPrint('✅ Image: ${didvanPlus?.image}'); + notifyListeners(); + } else { + debugPrint('⚠️ Didvan Plus: No result in response'); + } + } catch (e) { + debugPrint('❌ Failed to load Didvan Plus: $e'); + } + } + Future _fetchStories() async { try { stories = await StoryService.getStories(); @@ -60,7 +85,7 @@ class MainPageState extends CoreProvier { } void init() { - print("DEBUG: MainPageState init called"); + debugPrint("🏠 MainPageState init called"); Future.delayed(Duration.zero, () async { appState = AppState.busy; try { @@ -68,9 +93,12 @@ class MainPageState extends CoreProvier { _getMainPageContent(), _fetchStories(), _getSwotItems(), + _getDidvanPlus(), ]); + debugPrint("✅ All main page data loaded"); appState = AppState.idle; } catch (e) { + debugPrint("❌ Main page init failed: $e"); appState = AppState.failed; } }); @@ -139,6 +167,17 @@ class MainPageState extends CoreProvier { }; break; } + case 'monthly': + { + Navigator.of(navigatorKey.currentContext!).pushNamed( + Routes.pdfViewer, + arguments: { + 'pdfUrl': link, + 'title': description ?? 'ماهنامه تحلیلی دیدوان', + }, + ); + return; + } } if (link == '') { return; diff --git a/lib/views/home/main/widgets/didvan_plus_section.dart b/lib/views/home/main/widgets/didvan_plus_section.dart new file mode 100644 index 0000000..228f3d6 --- /dev/null +++ b/lib/views/home/main/widgets/didvan_plus_section.dart @@ -0,0 +1,163 @@ +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; +import 'package:didvan/models/didvan_plus_model.dart'; +import 'package:didvan/services/network/request_helper.dart'; +import 'package:didvan/services/network/request.dart'; +import 'package:didvan/views/widgets/didvan/text.dart'; +import 'package:didvan/views/widgets/video/primary_controls.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:persian_number_utility/persian_number_utility.dart'; +import 'package:video_player/video_player.dart'; +import 'package:chewie/chewie.dart'; + +class DidvanPlusSection extends StatefulWidget { + final DidvanPlusModel didvanPlus; + + const DidvanPlusSection({ + super.key, + required this.didvanPlus, + }); + + @override + State createState() => _DidvanPlusSectionState(); +} + +class _DidvanPlusSectionState extends State { + late VideoPlayerController _videoController; + ChewieController? _chewieController; + bool _isInitialized = false; + + @override + void initState() { + super.initState(); + _initializeVideo(); + } + + void _initializeVideo() { + final videoUrl = '${RequestHelper.baseUrl}${widget.didvanPlus.file}'; + final fullUrl = '$videoUrl?accessToken=${RequestService.token}'; + + debugPrint('🎥 Didvan Plus Video URL: $fullUrl'); + debugPrint('🎥 Video file path: ${widget.didvanPlus.file}'); + debugPrint('🎥 Base URL: ${RequestHelper.baseUrl}'); + debugPrint( + '🎥 Token exists: ${RequestService.token != null && RequestService.token!.isNotEmpty}'); + + _videoController = VideoPlayerController.networkUrl( + Uri.parse(fullUrl), + httpHeaders: { + 'Authorization': 'Bearer ${RequestService.token}', + }, + )..initialize().then((_) { + debugPrint('✅ Video initialized successfully'); + setState(() { + _chewieController = ChewieController( + videoPlayerController: _videoController, + autoPlay: false, + looping: false, + allowFullScreen: true, + allowMuting: true, + showControls: true, + customControls: const PrimaryControls(), + materialProgressColors: ChewieProgressColors( + playedColor: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 125, 166) + : const Color.fromARGB(255, 0, 89, 119), + handleColor: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 125, 166) + : const Color.fromARGB(255, 0, 89, 119), + backgroundColor: Colors.grey, + bufferedColor: Colors.grey.shade300, + ), + placeholder: Container( + color: Colors.black, + child: Center( + child: Image.network( + '${RequestHelper.baseUrl}${widget.didvanPlus.image}', + fit: BoxFit.cover, + ), + ), + ), + ); + _isInitialized = true; + }); + }).catchError((error) { + debugPrint('❌ Video initialization error: $error'); + }); + } + + @override + void dispose() { + _videoController.dispose(); + _chewieController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final publishedDate = DateTime.parse(widget.didvanPlus.publishedAt); + + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + SvgPicture.asset( + 'lib/assets/icons/voice-square.svg', + color: Theme.of(context).colorScheme.title, + width: 30, + height: 30, + ), + const SizedBox(width: 5), + DidvanText( + 'دیدوان پلاس', + style: Theme.of(context).textTheme.titleMedium, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 125, 166) + : const Color.fromARGB(255, 0, 89, 119), + fontSize: 13, + ), + ], + ), + DidvanText( + publishedDate.toPersianDateStr(), + fontSize: 13, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 125, 166) + : const Color.fromARGB(255, 0, 89, 119), + ), + ], + ), + const SizedBox(height: 12), + ClipRRect( + borderRadius: BorderRadius.circular(12), + child: AspectRatio( + aspectRatio: 16 / 9, + child: _isInitialized && _chewieController != null + ? Chewie(controller: _chewieController!) + : Container( + color: Colors.black, + child: Center( + child: Image.network( + '${RequestHelper.baseUrl}${widget.didvanPlus.image}', + fit: BoxFit.cover, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return const CircularProgressIndicator(); + }, + ), + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/views/home/main/widgets/simple_explore_card.dart b/lib/views/home/main/widgets/simple_explore_card.dart index b675b4e..d2ec2e2 100644 --- a/lib/views/home/main/widgets/simple_explore_card.dart +++ b/lib/views/home/main/widgets/simple_explore_card.dart @@ -31,34 +31,35 @@ class SimpleExploreCard extends StatelessWidget { String _getCategoryIcon(String? contentType, bool isSwot) { if (isSwot) { - // For SWOT items (فرصت تهدید) - return 'lib/assets/icons/swot.svg'; + return 'lib/assets/icons/Swot_New.svg'; } - + switch (contentType?.toLowerCase()) { case 'startup': - return 'lib/assets/icons/bi_rocket-fill.svg'; + return 'lib/assets/icons/Startup.svg'; case 'radar': - return 'lib/assets/icons/solar_graph-new-bold.svg'; // General radar fallback + return 'lib/assets/icons/Pouyesh_Ofogh_New.svg'; case 'trend': // رادار روند case 'trends': - return 'lib/assets/icons/solar_graph-new-bold.svg'; + return 'lib/assets/icons/Ravand.svg'; case 'technology': // رادار تکنولوزی/فناوری case 'tech': - return 'lib/assets/icons/cpu-charge.svg'; + return 'lib/assets/icons/Technology.svg'; case 'risk': // رادار ریسک - return 'lib/assets/icons/risk radar.svg'; + return 'lib/assets/icons/risk-radar.svg'; case 'survey': - case 'delphi': // دولفی - return 'lib/assets/icons/icon-park-solid_thinking-problem.svg'; + case 'delphi': + return 'lib/assets/icons/Saha.svg'; + case 'monthly': + return 'lib/assets/icons/Monthly.svg'; case 'news': - return 'lib/assets/icons/news-icon.svg'; // You can replace with actual icon + return 'lib/assets/icons/news-icon.svg'; case 'infography': - return 'lib/assets/icons/infography-icon.svg'; // You can replace with actual icon + return 'lib/assets/icons/infography-icon.svg'; case 'video': - return 'lib/assets/icons/video-icon.svg'; // You can replace with actual icon + return 'lib/assets/icons/video-icon.svg'; case 'podcast': - return 'lib/assets/icons/podcast-icon.svg'; // You can replace with actual icon + return 'lib/assets/icons/podcast-icon.svg'; default: return 'lib/assets/icons/bi_rocket-fill.svg'; // Default fallback } @@ -121,17 +122,19 @@ class SimpleExploreCard extends StatelessWidget { .onSurface .withValues(alpha: 0.1), ), - child: const Icon(Icons.image_not_supported_outlined), + child: + const Icon(Icons.image_not_supported_outlined), ); }, fit: BoxFit.cover, - imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet, + imageRenderMethodForWeb: + ImageRenderMethodForWeb.HttpGet, httpHeaders: { 'Authorization': 'Bearer ${RequestService.token}' }, width: double.infinity, imageUrl: imageUrl, - placeholder: (context, _) => ShimmerPlaceholder( + placeholder: (context, _) => const ShimmerPlaceholder( width: double.infinity, height: double.infinity, ), @@ -153,7 +156,8 @@ class SimpleExploreCard extends StatelessWidget { ), ), child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + padding: + const EdgeInsets.symmetric(horizontal: 12, vertical: 8), child: Row( children: [ SvgPicture.asset( @@ -186,4 +190,4 @@ class SimpleExploreCard extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/lib/views/home/main/widgets/story_section.dart b/lib/views/home/main/widgets/story_section.dart index 49d75c5..bbfbb65 100644 --- a/lib/views/home/main/widgets/story_section.dart +++ b/lib/views/home/main/widgets/story_section.dart @@ -1,3 +1,4 @@ +import 'package:didvan/config/design_config.dart'; import 'package:didvan/models/story_model.dart'; import 'package:didvan/routes/routes.dart'; import 'package:flutter/material.dart'; @@ -104,6 +105,7 @@ class _StoryCircle extends StatelessWidget { child: Image.asset( userStories.user .profileImageUrl, + color: DesignConfig.isDark ? Colors.grey : null, fit: BoxFit.cover, width: 50.0, height: 50.0, diff --git a/lib/views/home/main/widgets/swot_item_card.dart b/lib/views/home/main/widgets/swot_item_card.dart index 2cada35..f81f48b 100644 --- a/lib/views/home/main/widgets/swot_item_card.dart +++ b/lib/views/home/main/widgets/swot_item_card.dart @@ -1,5 +1,6 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/models/home_page_content/swot.dart'; import 'package:didvan/services/app_initalizer.dart'; @@ -156,17 +157,17 @@ class _SwotItemCardState extends State { // دسته‌بندی Row( children: [ - const Icon( + Icon( DidvanIcons.puzzle_light, size: 23, - color: Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), const SizedBox(width: 6), Expanded( child: Text( _getCategoryName(widget.item.category), style: theme.textTheme.bodySmall?.copyWith( - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), maxLines: 1, overflow: TextOverflow.ellipsis, diff --git a/lib/views/home/media/podcast_tab_page.dart b/lib/views/home/media/podcast_tab_page.dart index e83c9d9..6954717 100644 --- a/lib/views/home/media/podcast_tab_page.dart +++ b/lib/views/home/media/podcast_tab_page.dart @@ -1,12 +1,14 @@ +// ignore_for_file: deprecated_member_use + import 'dart:async'; +import 'package:didvan/config/design_config.dart'; import 'package:didvan/models/requests/studio.dart'; import 'package:didvan/routes/routes.dart'; import 'package:didvan/services/media/media.dart'; import 'package:didvan/views/home/media/widgets/featured_podcast_card.dart'; -import 'package:didvan/views/home/media/widgets/podcast_list_card.dart'; +import 'package:didvan/views/home/media/widgets/podcast_list_card.dart'; import 'package:didvan/views/podcasts/podcasts_state.dart'; import 'package:didvan/views/widgets/item_title.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'; @@ -56,16 +58,50 @@ class _PodcastTabPageState extends State { void _showSortDialog() { final state = context.read(); showModalBottomSheet( - backgroundColor: Colors.white, + backgroundColor: DesignConfig.isDark + ? const Color.fromARGB(255, 30, 30, 30) + : Colors.white, context: context, builder: (context) { return Container( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ + Padding( + padding: + const EdgeInsets.only(bottom: 8.0, right: 16.0, top: 8.0), + child: Row( + children: [ + SvgPicture.asset('lib/assets/icons/Sort Regular.svg'), + const SizedBox( + width: 5, + ), + Text( + 'مرتب‌سازی', + style: Theme.of(context) + .textTheme + .titleMedium + ?.copyWith(fontWeight: FontWeight.bold), + ), + ], + ), + ), ListTile( - title: const Text('تازه‌ترین‌ها'), + title: const Text('جدیدترین‌ها'), + leading: Radio( + value: 0, + groupValue: state.selectedSortTypeIndex, + onChanged: (int? value) { + if (value != null) { + state.selectedSortTypeIndex = value; + state.getStudios(page: 1); + Navigator.pop(context); + } + }, + activeColor: const Color.fromARGB(255, 178, 4, 54), + ), onTap: () { state.selectedSortTypeIndex = 0; state.getStudios(page: 1); @@ -74,6 +110,18 @@ class _PodcastTabPageState extends State { ), ListTile( title: const Text('قدیمی‌ترین‌ها'), + leading: Radio( + value: 1, + groupValue: state.selectedSortTypeIndex, + onChanged: (int? value) { + if (value != null) { + state.selectedSortTypeIndex = value; + state.getStudios(page: 1); + Navigator.pop(context); + } + }, + activeColor: const Color.fromARGB(255, 178, 4, 54), + ), onTap: () { state.selectedSortTypeIndex = 1; state.getStudios(page: 1); @@ -82,6 +130,18 @@ class _PodcastTabPageState extends State { ), ListTile( title: const Text('پربازدیدترین‌ها'), + leading: Radio( + value: 2, + groupValue: state.selectedSortTypeIndex, + onChanged: (int? value) { + if (value != null) { + state.selectedSortTypeIndex = value; + state.getStudios(page: 1); + Navigator.pop(context); + } + }, + activeColor: const Color.fromARGB(255, 178, 4, 54), + ), onTap: () { state.selectedSortTypeIndex = 2; state.getStudios(page: 1); @@ -90,6 +150,18 @@ class _PodcastTabPageState extends State { ), ListTile( title: const Text('پربحث‌ترین‌ها'), + leading: Radio( + value: 3, + groupValue: state.selectedSortTypeIndex, + onChanged: (int? value) { + if (value != null) { + state.selectedSortTypeIndex = value; + state.getStudios(page: 1); + Navigator.pop(context); + } + }, + activeColor: const Color.fromARGB(255, 178, 4, 54), + ), onTap: () { state.selectedSortTypeIndex = 3; state.getStudios(page: 1); @@ -129,11 +201,11 @@ class _PodcastTabPageState extends State { ); } - @override void dispose() { _rotationTimer?.cancel(); - if (MediaService.isPlayingFromFeaturedCard && MediaService.audioPlayer.playing) { + if (MediaService.isPlayingFromFeaturedCard && + MediaService.audioPlayer.playing) { MediaService.audioPlayer.pause(); } super.dispose(); @@ -175,7 +247,6 @@ class _PodcastTabPageState extends State { onPlayStateChanged: _onPlayStateChanged, ), ), - if (state.studios.length > 1) Padding( padding: @@ -183,10 +254,12 @@ class _PodcastTabPageState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const ItemTitle( + ItemTitle( title: 'همه پادکست‌ها', - color: Color.fromARGB(255, 0, 53, 70), - style: TextStyle( + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70), + style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 18), ), Row( @@ -195,19 +268,23 @@ class _PodcastTabPageState extends State { onTap: _showSortDialog, child: Text( state.orderString, - style: const TextStyle( - color: Color.fromARGB(255, 0, 53, 70)), + style: TextStyle( + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70)), )), IconButton( onPressed: _showSortDialog, icon: SvgPicture.asset( - 'lib/assets/icons/sort2.svg')), + 'lib/assets/icons/sort2.svg', + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : null)), ], ), ], ), ), - if (state.studios.length > 1) ListView.builder( itemCount: state.studios.length, @@ -215,7 +292,7 @@ class _PodcastTabPageState extends State { physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) { final podcast = state.studios[index]; - + return PodcastListCard( podcast: podcast, onTap: () => _navigateToDetails(index), @@ -229,4 +306,4 @@ class _PodcastTabPageState extends State { onRetry: () => context.read().getStudios(page: 1), ); } -} \ No newline at end of file +} diff --git a/lib/views/home/media/video_details_page.dart b/lib/views/home/media/video_details_page.dart index 5fb5cfd..666265f 100644 --- a/lib/views/home/media/video_details_page.dart +++ b/lib/views/home/media/video_details_page.dart @@ -1,6 +1,7 @@ // ignore_for_file: use_build_context_synchronously, deprecated_member_use import 'package:chewie/chewie.dart'; +import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/assets.dart'; @@ -170,7 +171,7 @@ class _VideoDetailsPageState extends State appBar: PreferredSize( preferredSize: const Size.fromHeight(90.0), child: AppBar( - backgroundColor: Colors.white, + backgroundColor: Theme.of(context).colorScheme.surface, elevation: 0, automaticallyImplyLeading: false, flexibleSpace: SafeArea( @@ -189,8 +190,7 @@ class _VideoDetailsPageState extends State IconButton( icon: SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', - color: - const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, height: 24, ), onPressed: () { @@ -283,17 +283,19 @@ class _VideoDetailsPageState extends State padding: const EdgeInsets.all(8.0), child: Text( state.studio.title, - style: const TextStyle( + style: TextStyle( fontSize: 17, fontWeight: FontWeight.bold, - color: Color.fromARGB(255, 0, 53, 70)), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70)), ), ), Container( decoration: BoxDecoration( borderRadius: BorderRadius.vertical( - bottom: Radius.circular( - _isDescriptionExpanded ? 0 : 16.0), + bottom: + Radius.circular(_isDescriptionExpanded ? 0 : 16.0), ), boxShadow: _isDescriptionExpanded ? null @@ -396,8 +398,8 @@ class _VideoDetailsPageState extends State children: [ Container( padding: const EdgeInsets.all(4.0), - decoration: const BoxDecoration( - color: Color.fromARGB(255, 230, 243, 250), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.focused, shape: BoxShape.circle, ), child: SvgPicture.asset( @@ -489,14 +491,18 @@ class _VideoDetailsPageState extends State children: [ CircleAvatar( radius: 20, - backgroundColor: Colors.white, + backgroundColor: DesignConfig.isDark + ? Colors.transparent + : Colors.white, backgroundImage: hasProfileImage ? NetworkImage(user.photo!) : null, child: !hasProfileImage - ? const Icon( + ? Icon( DidvanIcons.avatar_light, size: 50, - color: Colors.black, + color: DesignConfig.isDark + ? Colors.white + : Colors.black, ) : null, ), @@ -509,12 +515,14 @@ class _VideoDetailsPageState extends State }, ), const SizedBox(height: 16), - const SizedBox( + SizedBox( width: double.infinity, child: DidvanText( 'نظرات کاربران:', style: TextStyle( - color: Color.fromARGB(255, 0, 53, 70), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70), fontSize: 18, fontWeight: FontWeight.bold, ), @@ -547,13 +555,15 @@ class _VideoDetailsPageState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Padding( - padding: EdgeInsets.all(8.0), + Padding( + padding: const EdgeInsets.all(8.0), child: Text( "مطالب مرتبط:", style: TextStyle( fontSize: 18, - color: Color.fromARGB(255, 0, 53, 70), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70), fontWeight: FontWeight.bold), ), ), diff --git a/lib/views/home/media/videocast_tab_page.dart b/lib/views/home/media/videocast_tab_page.dart index 99bbc17..7d05ba8 100644 --- a/lib/views/home/media/videocast_tab_page.dart +++ b/lib/views/home/media/videocast_tab_page.dart @@ -1,4 +1,7 @@ +// ignore_for_file: deprecated_member_use + import 'dart:async'; +import 'package:didvan/config/design_config.dart'; 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'; @@ -47,16 +50,50 @@ class _VideoCastTabPageState extends State { void _showSortDialog() { final state = context.read(); showModalBottomSheet( - backgroundColor: Colors.white, + backgroundColor: DesignConfig.isDark + ? const Color.fromARGB(255, 30, 30, 30) + : Colors.white, context: context, builder: (context) { return Container( padding: const EdgeInsets.all(16), child: Column( mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ + Padding( + padding: + const EdgeInsets.only(bottom: 8.0, right: 16.0, top: 8.0), + child: Row( + children: [ + SvgPicture.asset('lib/assets/icons/Sort Regular.svg'), + const SizedBox( + width: 5, + ), + Text( + 'مرتب‌سازی', + style: Theme.of(context) + .textTheme + .titleMedium + ?.copyWith(fontWeight: FontWeight.bold), + ), + ], + ), + ), ListTile( - title: const Text('تازه‌ترین‌ها'), + title: const Text('جدیدترین‌ها'), + leading: Radio( + value: 0, + groupValue: state.selectedSortTypeIndex, + onChanged: (int? value) { + if (value != null) { + state.selectedSortTypeIndex = value; + state.getStudios(page: 1); + Navigator.pop(context); + } + }, + activeColor: const Color.fromARGB(255, 178, 4, 54), + ), onTap: () { state.selectedSortTypeIndex = 0; state.getStudios(page: 1); @@ -65,6 +102,18 @@ class _VideoCastTabPageState extends State { ), ListTile( title: const Text('قدیمی‌ترین‌ها'), + leading: Radio( + value: 1, + groupValue: state.selectedSortTypeIndex, + onChanged: (int? value) { + if (value != null) { + state.selectedSortTypeIndex = value; + state.getStudios(page: 1); + Navigator.pop(context); + } + }, + activeColor: const Color.fromARGB(255, 178, 4, 54), + ), onTap: () { state.selectedSortTypeIndex = 1; state.getStudios(page: 1); @@ -73,6 +122,18 @@ class _VideoCastTabPageState extends State { ), ListTile( title: const Text('پربازدیدترین‌ها'), + leading: Radio( + value: 2, + groupValue: state.selectedSortTypeIndex, + onChanged: (int? value) { + if (value != null) { + state.selectedSortTypeIndex = value; + state.getStudios(page: 1); + Navigator.pop(context); + } + }, + activeColor: const Color.fromARGB(255, 178, 4, 54), + ), onTap: () { state.selectedSortTypeIndex = 2; state.getStudios(page: 1); @@ -81,6 +142,18 @@ class _VideoCastTabPageState extends State { ), ListTile( title: const Text('پربحث‌ترین‌ها'), + leading: Radio( + value: 3, + groupValue: state.selectedSortTypeIndex, + onChanged: (int? value) { + if (value != null) { + state.selectedSortTypeIndex = value; + state.getStudios(page: 1); + Navigator.pop(context); + } + }, + activeColor: const Color.fromARGB(255, 178, 4, 54), + ), onTap: () { state.selectedSortTypeIndex = 3; state.getStudios(page: 1); @@ -145,7 +218,6 @@ class _VideoCastTabPageState extends State { }, ), ), - if (state.studios.length > 1) Padding( padding: @@ -153,10 +225,13 @@ class _VideoCastTabPageState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const ItemTitle( + ItemTitle( title: 'همه ویدیوکست‌ها', - color: Color.fromARGB(255, 0, 53, 70), - style: TextStyle(fontWeight: FontWeight.bold,fontSize: 18), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70), + style: const TextStyle( + fontWeight: FontWeight.bold, fontSize: 18), ), Row( children: [ @@ -164,19 +239,24 @@ class _VideoCastTabPageState extends State { onTap: _showSortDialog, child: Text( state.orderString, - style: const TextStyle( - color: Color.fromARGB(255, 0, 53, 70)), + style: TextStyle( + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70)), )), IconButton( onPressed: _showSortDialog, icon: SvgPicture.asset( - 'lib/assets/icons/sort2.svg')), + 'lib/assets/icons/sort2.svg', + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70), + )), ], ), ], ), ), - if (state.studios.length > 1) Padding( padding: const EdgeInsets.all(16), @@ -216,4 +296,4 @@ class _VideoCastTabPageState extends State { onRetry: () => context.read().getStudios(page: 1), ); } -} \ No newline at end of file +} diff --git a/lib/views/home/media/widgets/banner_grid_view.dart b/lib/views/home/media/widgets/banner_grid_view.dart index 4ca1a2a..d11d474 100644 --- a/lib/views/home/media/widgets/banner_grid_view.dart +++ b/lib/views/home/media/widgets/banner_grid_view.dart @@ -1,3 +1,5 @@ +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; 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'; @@ -61,9 +63,7 @@ class _BannerGridViewState extends State { return Column( children: [ _buildCategoryFilters(state), - const SizedBox(height: 16), - ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), @@ -90,7 +90,6 @@ class _BannerGridViewState extends State { ); }, ), - if (hasMoreItems) Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), @@ -162,12 +161,16 @@ class _BannerGridViewState extends State { }, 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), + ? DesignConfig.isDark + ? const Color.fromARGB(255, 30, 30, 30) + : const Color.fromARGB(255, 200, 224, 244) + : DesignConfig.isDark + ? const Color.fromARGB(255, 61, 61, 61) + : 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), + : Theme.of(context).colorScheme.caption, fontWeight: state.selectedCats.isEmpty ? FontWeight.bold : FontWeight.normal, @@ -178,7 +181,6 @@ class _BannerGridViewState extends State { showCheckmark: false, ), ), - ...state.categories.map((category) { final isSelected = state.selectedCats.contains(category); @@ -203,12 +205,16 @@ class _BannerGridViewState extends State { }, selectedColor: const Color.fromARGB(255, 200, 224, 244), backgroundColor: isSelected - ? const Color.fromARGB(255, 200, 224, 244) - : const Color.fromARGB(255, 224, 224, 224), + ? DesignConfig.isDark + ? const Color.fromARGB(255, 30, 30, 30) + : const Color.fromARGB(255, 200, 224, 244) + : DesignConfig.isDark + ? const Color.fromARGB(255, 61, 61, 61) + : 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), + : Theme.of(context).colorScheme.caption, fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, ), shape: RoundedRectangleBorder( diff --git a/lib/views/home/media/widgets/featured_podcast_card.dart b/lib/views/home/media/widgets/featured_podcast_card.dart index ba2948e..c546411 100644 --- a/lib/views/home/media/widgets/featured_podcast_card.dart +++ b/lib/views/home/media/widgets/featured_podcast_card.dart @@ -1,3 +1,7 @@ +// ignore_for_file: deprecated_member_use + +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/models/overview_data.dart'; import 'package:didvan/models/studio_details_data.dart'; import 'package:didvan/services/media/media.dart'; @@ -31,6 +35,7 @@ class _FeaturedPodcastCardState extends State Duration _currentPosition = Duration.zero; Duration _totalDuration = Duration.zero; + // ignore: prefer_final_fields var _subscriptions = []; @override @@ -217,7 +222,9 @@ class _FeaturedPodcastCardState extends State return Container( margin: const EdgeInsets.all(16), decoration: BoxDecoration( - color: const Color(0xFFEBEBEB), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 62, 62, 62) + : const Color.fromARGB(255, 235, 235, 235), borderRadius: BorderRadius.circular(16), ), child: Column( @@ -245,10 +252,10 @@ class _FeaturedPodcastCardState extends State children: [ DidvanText( widget.podcast.title, - style: const TextStyle( + style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, - color: Colors.black, + color: DesignConfig.isDark ? Colors.white : Colors.black, ), maxLines: 2, overflow: TextOverflow.ellipsis, @@ -260,9 +267,9 @@ class _FeaturedPodcastCardState extends State width: 45, child: Text( _formatDuration(_totalDuration), - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: Color.fromARGB(255, 102, 102, 102)), + color: Theme.of(context).colorScheme.caption), textAlign: TextAlign.left, ), ), @@ -289,9 +296,9 @@ class _FeaturedPodcastCardState extends State width: 45, child: Text( _formatDuration(_currentPosition), - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: Color.fromARGB(255, 102, 102, 102)), + color: Theme.of(context).colorScheme.caption), textAlign: TextAlign.right, ), ), @@ -304,10 +311,12 @@ class _FeaturedPodcastCardState extends State IconButton( onPressed: isCurrentlyPlaying ? _seekForward : null, icon: SvgPicture.asset( - 'lib/assets/icons/forward-10-seconds.svg', - width: 30, - height: 30, - ), + 'lib/assets/icons/forward-10-seconds.svg', + width: 30, + height: 30, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 117, 117, 117) + : null), ), const SizedBox(width: 15), GestureDetector( @@ -348,10 +357,12 @@ class _FeaturedPodcastCardState extends State IconButton( onPressed: isCurrentlyPlaying ? _seekBackward : null, icon: SvgPicture.asset( - 'lib/assets/icons/backward-5-seconds.svg', - width: 30, - height: 30, - ), + 'lib/assets/icons/backward-5-seconds.svg', + width: 30, + height: 30, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 117, 117, 117) + : null), ), ], ), diff --git a/lib/views/home/media/widgets/podcast_list_card.dart b/lib/views/home/media/widgets/podcast_list_card.dart index 89a6312..6c1c654 100644 --- a/lib/views/home/media/widgets/podcast_list_card.dart +++ b/lib/views/home/media/widgets/podcast_list_card.dart @@ -1,3 +1,7 @@ +// ignore_for_file: deprecated_member_use + +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/models/overview_data.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/skeleton_image.dart'; @@ -73,7 +77,9 @@ class PodcastListCard extends StatelessWidget { child: Padding( padding: const EdgeInsets.fromLTRB(12, 3, 12, 10), child: Container( - color: Colors.white, + color: DesignConfig.isDark + ? Colors.transparent + : Colors.white, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, @@ -82,7 +88,9 @@ class PodcastListCard extends StatelessWidget { podcast.title, style: textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w600, - color: Colors.black87, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 206, 206, 206) + : Colors.black87, ), maxLines: 2, overflow: TextOverflow.ellipsis, @@ -91,13 +99,15 @@ class PodcastListCard extends StatelessWidget { Row( children: [ SvgPicture.asset( - 'lib/assets/icons/calendar.svg'), + 'lib/assets/icons/calendar.svg', + color: Theme.of(context).colorScheme.caption, + ), const SizedBox(width: 4), DidvanText( _formatDate(podcast.createdAt), style: textTheme.bodySmall?.copyWith( - color: const Color.fromARGB( - 255, 102, 102, 102), + color: + Theme.of(context).colorScheme.caption, ), maxLines: 1, overflow: TextOverflow.ellipsis, @@ -109,16 +119,15 @@ class PodcastListCard extends StatelessWidget { children: [ SvgPicture.asset( 'lib/assets/icons/clock.svg', - color: - const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), const SizedBox(width: 4), DidvanText( _formatDuration(podcast.duration) .toPersianDigit(), style: textTheme.bodySmall?.copyWith( - color: const Color.fromARGB( - 255, 102, 102, 102), + color: + Theme.of(context).colorScheme.caption, ), ), ], diff --git a/lib/views/home/media/widgets/videocast_grid_card.dart b/lib/views/home/media/widgets/videocast_grid_card.dart index 252d598..10087e3 100644 --- a/lib/views/home/media/widgets/videocast_grid_card.dart +++ b/lib/views/home/media/widgets/videocast_grid_card.dart @@ -1,3 +1,7 @@ +// ignore_for_file: deprecated_member_use + +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/models/overview_data.dart'; import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/skeleton_image.dart'; @@ -37,7 +41,9 @@ class VideocastGridCard extends StatelessWidget { onTap: onTap, child: Container( decoration: BoxDecoration( - color: const Color.fromRGBO(235, 235, 235, 1), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 63, 63, 63) + : const Color.fromRGBO(235, 235, 235, 1), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( @@ -50,7 +56,6 @@ class VideocastGridCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Video cover Padding( padding: const EdgeInsets.all(6.0), child: AspectRatio( @@ -66,7 +71,6 @@ class VideocastGridCard extends StatelessWidget { ), ), ), - Expanded( child: Padding( padding: const EdgeInsets.fromLTRB(12, 4, 12, 8), @@ -78,7 +82,9 @@ class VideocastGridCard extends StatelessWidget { videocast.title, style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w600, - color: Colors.black87, + color: DesignConfig.isDark + ? Colors.white70 + : Colors.black87, ), maxLines: 1, overflow: TextOverflow.ellipsis, @@ -94,7 +100,7 @@ class VideocastGridCard extends StatelessWidget { .textTheme .bodySmall ?.copyWith( - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), maxLines: 1, overflow: TextOverflow.ellipsis, @@ -106,7 +112,7 @@ class VideocastGridCard extends StatelessWidget { children: [ SvgPicture.asset( 'lib/assets/icons/clock.svg', - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), const SizedBox(width: 4), DidvanText( @@ -115,7 +121,7 @@ class VideocastGridCard extends StatelessWidget { .textTheme .bodySmall ?.copyWith( - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ], diff --git a/lib/views/monthly/monthly_list_page.dart b/lib/views/monthly/monthly_list_page.dart index 7a76a4f..7f64528 100644 --- a/lib/views/monthly/monthly_list_page.dart +++ b/lib/views/monthly/monthly_list_page.dart @@ -1,5 +1,7 @@ import 'dart:async'; +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/enums.dart'; import 'package:didvan/models/view/action_sheet_data.dart'; @@ -178,7 +180,9 @@ class _MonthlyListPageState extends State { style: theme.textTheme.headlineSmall?.copyWith( color: isDark ? Colors.white - : const Color.fromARGB(255, 0, 53, 70), + : DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70), fontWeight: FontWeight.bold, fontSize: 19), ), @@ -193,7 +197,7 @@ class _MonthlyListPageState extends State { colorFilter: ColorFilter.mode( isDark ? Colors.white70 - : const Color.fromARGB(255, 102, 102, 102), + : Theme.of(context).colorScheme.caption, BlendMode.srcIn), ), ), @@ -237,7 +241,9 @@ class _MonthlyListPageState extends State { }, child: Container( decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 36, 36, 36) + : Colors.white, borderRadius: BorderRadius.circular(16), border: Border.all( color: const Color.fromARGB(255, 184, 184, 184), @@ -267,8 +273,10 @@ class _MonthlyListPageState extends State { children: [ DidvanText( item.title, - style: const TextStyle( - color: Colors.black, + style: TextStyle( + color: DesignConfig.isDark + ? Colors.white + : Colors.black, fontWeight: FontWeight.bold, fontSize: 15, ), diff --git a/lib/views/news/news.dart b/lib/views/news/news.dart index 6778808..0954f4c 100644 --- a/lib/views/news/news.dart +++ b/lib/views/news/news.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'dart:math'; +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/enums.dart'; import 'package:didvan/models/requests/news.dart'; @@ -69,7 +71,7 @@ class _NewsState extends State { title: Text( 'دنیای فولاد', style: theme.textTheme.headlineSmall?.copyWith( - color: const Color.fromARGB(255, 0, 53, 70), + color: DesignConfig.isDark? const Color.fromARGB(255, 0, 90, 119) : const Color.fromARGB(255, 0, 53, 70), fontWeight: FontWeight.bold, fontSize: 19), ), @@ -80,8 +82,8 @@ class _NewsState extends State { 'lib/assets/icons/arrow-left.svg', width: 30, height: 30, - colorFilter: const ColorFilter.mode( - Color.fromARGB(255, 102, 102, 102), BlendMode.srcIn), + colorFilter: ColorFilter.mode( + Theme.of(context).colorScheme.caption, BlendMode.srcIn), ), ), const SizedBox(width: 8), diff --git a/lib/views/notification_settings/notification_settings.dart b/lib/views/notification_settings/notification_settings.dart index 947b09c..5736663 100644 --- a/lib/views/notification_settings/notification_settings.dart +++ b/lib/views/notification_settings/notification_settings.dart @@ -1,4 +1,5 @@ import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/models/day_time.dart'; import 'package:didvan/models/enums.dart'; @@ -106,7 +107,7 @@ class _NotificationSettingsState extends State child: SvgPicture.asset( Assets.horizontalLogoWithText, fit: BoxFit.contain, - height: 80, + height: 90, ), ), actions: [ @@ -115,12 +116,15 @@ class _NotificationSettingsState extends State Navigator.of(context).pushNamed(Routes.bookmarks); }, icon: SvgPicture.asset( - 'lib/assets/icons/hugeicons_telescope-01.svg')), + 'lib/assets/icons/hugeicons_telescope-01.svg', + color: DesignConfig.isDark + ? Theme.of(context).colorScheme.caption + : null)), IconButton( onPressed: () => Navigator.of(context).pop(), icon: SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, )), const SizedBox(width: 8), ], @@ -160,22 +164,24 @@ class _NotificationSettingsState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Padding( - padding: EdgeInsets.all(18.0), + Padding( + padding: const EdgeInsets.all(18.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: 10), + const SizedBox(height: 10), Text( 'دسته‌بندی اعلان‌ها', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, - color: Colors.black), + color: DesignConfig.isDark + ? Colors.white + : Colors.black), ), - SizedBox(height: 10), - Text( + const SizedBox(height: 10), + const Text( 'در این بخش می‌توانید تعیین کنید از کدام دسته از محتواهای منتشرشده در اپلیکیشن دیدوان، اعلان دریافت کنید.', style: TextStyle( fontSize: 14, @@ -228,28 +234,30 @@ class _NotificationSettingsState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Padding( - padding: EdgeInsets.all(18.0), + Padding( + padding: const EdgeInsets.all(18.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox(height: 10), + const SizedBox(height: 10), Text( 'زمان‌بندی دریافت اعلان‌ها', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, - color: Colors.black), + color: DesignConfig.isDark + ? Colors.white + : Colors.black), ), - SizedBox(height: 10), - Text( + const SizedBox(height: 10), + const Text( 'در این بخش می‌توانید تعیین کنید اعلان‌های دسته‌بندی‌هایی که انتخاب کرده‌اید، در چه بازه‌های زمانی برای شما ارسال شوند..', style: TextStyle( fontSize: 14, color: Color.fromARGB(255, 128, 128, 128), )), - SizedBox( + const SizedBox( height: 15, ) ], @@ -353,8 +361,8 @@ class _CategoryExpansionGroupState extends State<_CategoryExpansionGroup> { @override Widget build(BuildContext context) { - const expansionColor = Color.fromARGB(255, 230, 243, 250); - const grayTextColor = Color.fromARGB(255, 102, 102, 102); + final expansionColor = Theme.of(context).colorScheme.focused; + final grayTextColor = Theme.of(context).colorScheme.caption; return Padding( padding: const EdgeInsets.all(16.0), @@ -380,7 +388,9 @@ class _CategoryExpansionGroupState extends State<_CategoryExpansionGroup> { widget.title, style: Theme.of(context).textTheme.titleMedium?.copyWith( fontWeight: FontWeight.normal, - color: const Color.fromARGB(255, 41, 41, 41), + color: DesignConfig.isDark + ? Theme.of(context).colorScheme.caption + : const Color.fromARGB(255, 41, 41, 41), ), maxLines: 1, overflow: TextOverflow.ellipsis, @@ -392,7 +402,9 @@ class _CategoryExpansionGroupState extends State<_CategoryExpansionGroup> { duration: const Duration(milliseconds: 200), child: SvgPicture.asset( 'lib/assets/icons/arrow-down.svg', - color: const Color.fromARGB(255, 41, 41, 41), + color: DesignConfig.isDark + ? Theme.of(context).colorScheme.caption + : const Color.fromARGB(255, 41, 41, 41), ), ), ], @@ -415,7 +427,9 @@ class _CategoryExpansionGroupState extends State<_CategoryExpansionGroup> { padding: const EdgeInsets.symmetric(horizontal: 12), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), - color: Theme.of(context).colorScheme.surface, + color: DesignConfig.isDark + ? null + : Theme.of(context).colorScheme.surface, ), child: Column( children: [ @@ -444,6 +458,7 @@ class _CategoryExpansionGroupState extends State<_CategoryExpansionGroup> { textDirection: TextDirection.ltr, child: CupertinoSwitch( value: item.selected ?? false, + // ignore: deprecated_member_use activeColor: Theme.of(context).colorScheme.primary, onChanged: (value) { diff --git a/lib/views/podcasts/podcasts.dart b/lib/views/podcasts/podcasts.dart index 700ff38..7b30944 100644 --- a/lib/views/podcasts/podcasts.dart +++ b/lib/views/podcasts/podcasts.dart @@ -206,7 +206,7 @@ class _PodcastsState extends State { builder: (context, setState) => Column( children: [ DidvanRadialButton( - title: 'تازه‌ترین‌ها', + title: 'جدیدترین‌ها', onSelected: () => setState( () => state.selectedSortTypeIndex = 0, ), diff --git a/lib/views/podcasts/podcasts_state.dart b/lib/views/podcasts/podcasts_state.dart index 05bf73d..7672282 100644 --- a/lib/views/podcasts/podcasts_state.dart +++ b/lib/views/podcasts/podcasts_state.dart @@ -55,7 +55,7 @@ class PodcastsState extends CoreProvier { } String get orderString { - if (selectedSortTypeIndex == 0) return 'تازه‌ترین‌ها'; + if (selectedSortTypeIndex == 0) return 'جدیدترین‌ها'; if (selectedSortTypeIndex == 1) return 'قدیمی‌ترین‌ها'; if (selectedSortTypeIndex == 2) return 'پربازدیدترین‌ها'; return 'پربحث‌ترین‌ها'; diff --git a/lib/views/podcasts/studio_details/studio_details.mobile.dart b/lib/views/podcasts/studio_details/studio_details.mobile.dart index 1192075..c9dbe64 100644 --- a/lib/views/podcasts/studio_details/studio_details.mobile.dart +++ b/lib/views/podcasts/studio_details/studio_details.mobile.dart @@ -1,6 +1,7 @@ // ignore_for_file: use_build_context_synchronously, deprecated_member_use import 'package:chewie/chewie.dart'; +import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; @@ -311,7 +312,7 @@ class _StudioDetailsState extends State appBar: PreferredSize( preferredSize: const Size.fromHeight(90.0), child: AppBar( - backgroundColor: Colors.white, + backgroundColor: Theme.of(context).colorScheme.surface, elevation: 0, automaticallyImplyLeading: false, flexibleSpace: SafeArea( @@ -324,14 +325,16 @@ class _StudioDetailsState extends State Center( child: SvgPicture.asset( 'lib/assets/images/logos/logo-horizontal-light.svg', + color: DesignConfig.isDark + ? Theme.of(context).colorScheme.caption + : null, height: 55, ), ), IconButton( icon: SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', - color: - const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, height: 24, ), onPressed: () { @@ -450,10 +453,12 @@ class _StudioDetailsState extends State padding: const EdgeInsets.all(8.0), child: Text( state.studio.title, - style: const TextStyle( + style: TextStyle( fontSize: 17, fontWeight: FontWeight.bold, - color: Color.fromARGB(255, 0, 53, 70)), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70)), ), ), ), @@ -568,8 +573,8 @@ class _StudioDetailsState extends State children: [ Container( padding: const EdgeInsets.all(5.0), - decoration: const BoxDecoration( - color: Color.fromARGB(255, 230, 243, 250), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.focused, shape: BoxShape.circle, ), child: SvgPicture.asset( @@ -682,14 +687,18 @@ class _StudioDetailsState extends State children: [ CircleAvatar( radius: 20, - backgroundColor: Colors.white, + backgroundColor: DesignConfig.isDark + ? Colors.transparent + : Colors.white, backgroundImage: hasProfileImage ? NetworkImage(user.photo!) : null, child: !hasProfileImage - ? const Icon( + ? Icon( DidvanIcons.avatar_light, size: 50, - color: Colors.black, + color: DesignConfig.isDark + ? Colors.white + : Colors.black, ) : null, ), @@ -702,12 +711,14 @@ class _StudioDetailsState extends State }, ), const SizedBox(height: 16), - const SizedBox( + SizedBox( width: double.infinity, child: DidvanText( 'نظرات کاربران:', style: TextStyle( - color: Color.fromARGB(255, 0, 53, 70), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70), fontSize: 18, fontWeight: FontWeight.bold, ), @@ -740,13 +751,15 @@ class _StudioDetailsState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Padding( - padding: EdgeInsets.all(8.0), + Padding( + padding: const EdgeInsets.all(8.0), child: Text( "مطالب مرتبط:", style: TextStyle( fontSize: 18, - color: Color.fromARGB(255, 0, 53, 70), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 0, 90, 119) + : const Color.fromARGB(255, 0, 53, 70), fontWeight: FontWeight.bold), ), ), @@ -823,7 +836,6 @@ class _StudioDetailsState extends State 'type': item.type, 'onMarkChanged': (int id, bool value, [bool shouldUpdate = true]) { - // Match original if (widget.pageData['onMarkChanged'] != null) { widget.pageData['onMarkChanged']( @@ -845,7 +857,7 @@ class _StudioDetailsState extends State if (widget.pageData['onMarkChanged'] != null) { widget.pageData['onMarkChanged']( - id, value, true); // Modified + id, value, true); } }, ), diff --git a/lib/views/podcasts/studio_details/widgets/studio_details_widget.dart b/lib/views/podcasts/studio_details/widgets/studio_details_widget.dart index 60def50..f84fbdf 100644 --- a/lib/views/podcasts/studio_details/widgets/studio_details_widget.dart +++ b/lib/views/podcasts/studio_details/widgets/studio_details_widget.dart @@ -1,5 +1,7 @@ import 'dart:math'; +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/models/enums.dart'; import 'package:didvan/models/studio_details_data.dart'; import 'package:didvan/views/comments/comments.dart'; @@ -241,7 +243,7 @@ class StudioPreview extends StatelessWidget { width: 170, height: 235, decoration: BoxDecoration( - color: const Color.fromRGBO(235, 235, 235, 1), + color: DesignConfig.isDark? const Color.fromARGB(255, 83, 83, 83): const Color.fromRGBO(235, 235, 235, 1), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( @@ -281,7 +283,7 @@ class StudioPreview extends StatelessWidget { _previewTitle, style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.normal, - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, fontSize: 12 ), maxLines: 1, @@ -292,7 +294,7 @@ class StudioPreview extends StatelessWidget { studio.title, style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.normal, - color: Colors.black87, + color: DesignConfig.isDark? Colors.white70 : Colors.black87, ), maxLines: 1, overflow: TextOverflow.ellipsis, @@ -302,7 +304,7 @@ class StudioPreview extends StatelessWidget { children: [ SvgPicture.asset( 'lib/assets/icons/clock.svg', - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), const SizedBox(width: 4), DidvanText( @@ -311,7 +313,7 @@ class StudioPreview extends StatelessWidget { .textTheme .bodySmall ?.copyWith( - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ], diff --git a/lib/views/profile/change_password/widgets/new_password_screen.dart b/lib/views/profile/change_password/widgets/new_password_screen.dart index aeba51a..a8421bd 100644 --- a/lib/views/profile/change_password/widgets/new_password_screen.dart +++ b/lib/views/profile/change_password/widgets/new_password_screen.dart @@ -1,3 +1,5 @@ +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/providers/user.dart'; import 'package:didvan/routes/routes.dart'; @@ -81,7 +83,6 @@ class _NewPasswordScreenState extends State curve: const Interval(0.35, 0.65, curve: Curves.easeOutCubic), )); - _fadeAnimation = Tween( begin: 0.0, end: 1.0, @@ -136,7 +137,7 @@ class _NewPasswordScreenState extends State key: _formKey, child: DidvanScaffold( padding: const EdgeInsets.only( - top: 16, + top: 0, left: 0, right: 0, ), @@ -169,10 +170,14 @@ class _NewPasswordScreenState extends State opacity: _buttonFadeAnimation, child: IconButton( onPressed: () { - Navigator.of(context).pushNamed(Routes.bookmarks); + Navigator.of(context) + .pushNamed(Routes.bookmarks); }, icon: SvgPicture.asset( - 'lib/assets/icons/hugeicons_telescope-01.svg')), + 'lib/assets/icons/hugeicons_telescope-01.svg', + color: DesignConfig.isDark + ? Theme.of(context).colorScheme.caption + : null)), ), ), SlideTransition( @@ -183,7 +188,7 @@ class _NewPasswordScreenState extends State onPressed: () => Navigator.of(context).pop(), icon: SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ), @@ -219,10 +224,9 @@ class _NewPasswordScreenState extends State .textTheme .headlineSmall ?.copyWith( - fontWeight: FontWeight.bold, - fontSize: 18 - ), - textAlign: TextAlign.start, + fontWeight: FontWeight.bold, + fontSize: 18), + textAlign: TextAlign.start, ), ), ], @@ -230,7 +234,9 @@ class _NewPasswordScreenState extends State ), ), ), - const SizedBox(height: 5,), + const SizedBox( + height: 5, + ), Padding( padding: const EdgeInsets.symmetric(horizontal: 25.0), child: Column( @@ -374,11 +380,11 @@ class _NewPasswordScreenState extends State final changePasswordState = context.read(); changePasswordState.newPassword = _newPassword; - + final userProvider = context.read(); - final success = - await changePasswordState.changePassword(userProvider); - + final success = await changePasswordState + .changePassword(userProvider); + if (success && mounted) { Navigator.of(context).pushNamedAndRemoveUntil( Routes.profile, diff --git a/lib/views/profile/change_password/widgets/verify_otp_screen.dart b/lib/views/profile/change_password/widgets/verify_otp_screen.dart index 33ba0f3..9277014 100644 --- a/lib/views/profile/change_password/widgets/verify_otp_screen.dart +++ b/lib/views/profile/change_password/widgets/verify_otp_screen.dart @@ -1,8 +1,12 @@ +// ignore_for_file: deprecated_member_use + import 'dart:async'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/config/design_config.dart'; import 'package:didvan/providers/user.dart'; import 'package:didvan/routes/routes.dart'; +import 'package:didvan/utils/extension.dart'; import 'package:didvan/views/profile/change_password/change_password_state.dart'; import 'package:didvan/views/widgets/didvan/button.dart'; import 'package:didvan/views/widgets/didvan/scaffold.dart'; @@ -170,7 +174,7 @@ class _VerifyOtpScreenState extends State padding: const EdgeInsets.only(bottom: 150), child: DidvanScaffold( padding: const EdgeInsets.only( - top: 16, + top: 0, left: 0, right: 0, ), @@ -202,11 +206,15 @@ class _VerifyOtpScreenState extends State child: FadeTransition( opacity: _buttonFadeAnimation, child: IconButton( - onPressed: () { - Navigator.of(context).pushNamed(Routes.bookmarks); - }, - icon: SvgPicture.asset( - 'lib/assets/icons/hugeicons_telescope-01.svg')), + onPressed: () { + Navigator.of(context).pushNamed(Routes.bookmarks); + }, + icon: SvgPicture.asset( + 'lib/assets/icons/hugeicons_telescope-01.svg', + color: DesignConfig.isDark + ? Theme.of(context).colorScheme.caption + : null), + ), ), ), SlideTransition( @@ -217,7 +225,7 @@ class _VerifyOtpScreenState extends State onPressed: () => Navigator.of(context).pop(), icon: SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ), @@ -270,7 +278,7 @@ class _VerifyOtpScreenState extends State const TextSpan( text: 'ما یک کد تأیید 6 رقمی به شماره '), TextSpan( - text: phoneNumber, + text: phoneNumber.convertToPersianDigits(), style: TextStyle( color: Theme.of(context).colorScheme.primary, diff --git a/lib/views/profile/direct_list/direct_list.dart b/lib/views/profile/direct_list/direct_list.dart index 6e4f3bc..8a7ba5b 100644 --- a/lib/views/profile/direct_list/direct_list.dart +++ b/lib/views/profile/direct_list/direct_list.dart @@ -1,3 +1,7 @@ +// ignore_for_file: deprecated_member_use + +import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/models/enums.dart'; import 'package:didvan/routes/routes.dart'; @@ -105,12 +109,16 @@ class _DirectListState extends State Navigator.of(context).pushNamed(Routes.bookmarks); }, icon: SvgPicture.asset( - 'lib/assets/icons/hugeicons_telescope-01.svg')), + 'lib/assets/icons/hugeicons_telescope-01.svg', + color: DesignConfig.isDark + ? Theme.of(context).colorScheme.caption + : null, + )), IconButton( onPressed: () => Navigator.of(context).pop(), icon: SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, )), const SizedBox(width: 8), ], diff --git a/lib/views/profile/direct_list/widgets/direct_item.dart b/lib/views/profile/direct_list/widgets/direct_item.dart index d3f8dfb..394ca39 100644 --- a/lib/views/profile/direct_list/widgets/direct_item.dart +++ b/lib/views/profile/direct_list/widgets/direct_item.dart @@ -1,3 +1,4 @@ +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/chat_room/chat_room.dart'; @@ -56,7 +57,7 @@ class ChatRoomItem extends StatelessWidget { child: DidvanText( chatRoom.type, style: Theme.of(context).textTheme.bodyLarge?.copyWith( - color: const Color.fromARGB(255, 102, 102, 102)), + color: Theme.of(context).colorScheme.caption), ), ), // if (chatRoom.unread != 0) @@ -78,8 +79,10 @@ class ChatRoomItem extends StatelessWidget { decoration: BoxDecoration( color: chatRoom.lastMessage.readed ? chatRoom.lastMessage.writedByAdmin - ? const Color.fromARGB(255, 230, 243, 250) - : const Color.fromARGB(255, 235, 235, 235) + ? Theme.of(context).colorScheme.focused + : DesignConfig.isDark + ? const Color.fromARGB(255, 188, 188, 188) + : const Color.fromARGB(255, 235, 235, 235) : const Color.fromARGB(255, 255, 200, 215), borderRadius: BorderRadius.circular(8)), child: Padding( @@ -150,7 +153,7 @@ class ChatRoomItem extends StatelessWidget { maxLines: 1, overflow: TextOverflow.ellipsis, textAlign: TextAlign.start, - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ], diff --git a/lib/views/profile/edit_profile/edit_profile.dart b/lib/views/profile/edit_profile/edit_profile.dart index 818604a..8d6d653 100644 --- a/lib/views/profile/edit_profile/edit_profile.dart +++ b/lib/views/profile/edit_profile/edit_profile.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/providers/user.dart'; import 'package:didvan/routes/routes.dart'; @@ -250,7 +251,7 @@ class _EditProfileState extends State icon: SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', color: - const Color.fromARGB(255, 102, 102, 102), + Theme.of(context).colorScheme.caption, )), ), ), diff --git a/lib/views/profile/profile.dart b/lib/views/profile/profile.dart index 0148489..afc0a24 100644 --- a/lib/views/profile/profile.dart +++ b/lib/views/profile/profile.dart @@ -1,4 +1,5 @@ import 'package:didvan/config/design_config.dart'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/models/view/action_sheet_data.dart'; @@ -95,7 +96,7 @@ class _ProfilePageState extends State onRetry: context.read().init, state: context.read(), builder: (context, state) => DidvanScaffold( - padding: const EdgeInsets.fromLTRB(8, 20, 0, 20), + padding: const EdgeInsets.fromLTRB(0, 0, 0, 20), appBarData: null, showSliversFirst: true, slivers: [ @@ -118,12 +119,12 @@ class _ProfilePageState extends State Navigator.of(context).pushNamed(Routes.bookmarks); }, icon: SvgPicture.asset( - 'lib/assets/icons/hugeicons_telescope-01.svg')), + 'lib/assets/icons/hugeicons_telescope-01.svg',color: Theme.of(context).colorScheme.caption,)), IconButton( onPressed: () => Navigator.of(context).pop(), icon: SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, )), const SizedBox(width: 8), ], @@ -212,7 +213,7 @@ class _ProfilePageState extends State width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( - color: const Color.fromARGB(255, 230, 243, 250), + color: Theme.of(context).colorScheme.focused, borderRadius: BorderRadius.circular(16), ), child: Center( @@ -222,7 +223,7 @@ class _ProfilePageState extends State .textTheme .titleMedium ?.copyWith( - color: Colors.black, + color: DesignConfig.isDark? Colors.white : Colors.black, fontWeight: FontWeight.normal, fontSize: 15), ), @@ -230,10 +231,10 @@ class _ProfilePageState extends State ), const SizedBox(height: 15), MenuOption( - titleWidget: const DidvanText('ویرایش پروفایل', + titleWidget: DidvanText('ویرایش پروفایل', style: TextStyle( color: - Color.fromARGB(255, 102, 102, 102))), + Theme.of(context).colorScheme.caption)), onTap: () => Navigator.of(context) .pushNamed(Routes.editProfile), iconWidget: SvgPicture.asset( @@ -241,10 +242,10 @@ class _ProfilePageState extends State ), const DidvanDivider(), MenuOption( - titleWidget: const DidvanText('تغییر رمز عبور ', + titleWidget: DidvanText('تغییر رمز عبور ', style: TextStyle( color: - Color.fromARGB(255, 102, 102, 102))), + Theme.of(context).colorScheme.caption)), iconWidget: SvgPicture.asset('lib/assets/icons/lock.svg'), onTap: () => Navigator.of(context).pushNamed( @@ -303,7 +304,7 @@ class _ProfilePageState extends State width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( - color: const Color.fromARGB(255, 230, 243, 250), + color: Theme.of(context).colorScheme.focused, borderRadius: BorderRadius.circular(16), ), child: Center( @@ -313,7 +314,7 @@ class _ProfilePageState extends State .textTheme .titleMedium ?.copyWith( - color: Colors.black, + color: DesignConfig.isDark? Colors.white : Colors.black, fontWeight: FontWeight.normal, fontSize: 15), ), @@ -321,10 +322,10 @@ class _ProfilePageState extends State ), const SizedBox(height: 15), MenuOption( - titleWidget: const DidvanText('تنظیمات اعلان‌ها', + titleWidget: DidvanText('تنظیمات اعلان‌ها', style: TextStyle( color: - Color.fromARGB(255, 102, 102, 102))), + Theme.of(context).colorScheme.caption)), onTap: () => Navigator.of(context) .pushNamed(Routes.notificationSettings), iconWidget: SvgPicture.asset( @@ -332,10 +333,9 @@ class _ProfilePageState extends State ), const DidvanDivider(), MenuOption( - titleWidget: const DidvanText('ظاهر اپلیکیشن', + titleWidget: DidvanText('ظاهر اپلیکیشن', style: TextStyle( - color: Color.fromARGB( - 255, 102, 102, 102))), + color: Theme.of(context).colorScheme.caption)), iconWidget: SvgPicture.asset( 'lib/assets/icons/fluent_paint-brush-16-regular.svg'), onTap: () { @@ -348,7 +348,7 @@ class _ProfilePageState extends State : 'lib/assets/icons/arrow-down.svg', height: 25, color: - const Color.fromARGB(255, 102, 102, 102), + Theme.of(context).colorScheme.caption, )), const SizedBox(height: 8), AnimatedVisibility( @@ -368,10 +368,9 @@ class _ProfilePageState extends State : state.fontFamily == 'Iransans-FA' ? 'ایران سنس' : 'ایران یکان', - titleWidget: const DidvanText('فونت', + titleWidget: DidvanText('فونت', style: TextStyle( - color: Color.fromARGB( - 255, 102, 102, 102))), + color: Theme.of(context).colorScheme.caption)), onTap: _showFontFamilyBottomSheet, iconWidget: SvgPicture.asset( 'lib/assets/icons/hugeicons_edit-01.svg'), @@ -383,11 +382,10 @@ class _ProfilePageState extends State child: MenuOption( suffix: fontScaleSuffix( state.fontSizeScale), - titleWidget: const DidvanText( + titleWidget: DidvanText( 'اندازه متن', style: TextStyle( - color: Color.fromARGB( - 255, 102, 102, 102))), + color: Theme.of(context).colorScheme.caption)), onTap: _showFontScaleBottomSheet, iconWidget: SvgPicture.asset( 'lib/assets/icons/smallcaps.svg'), @@ -404,13 +402,9 @@ class _ProfilePageState extends State SvgPicture.asset( 'lib/assets/icons/moon.svg'), const SizedBox(width: 4), - const DidvanText('تم برنامه', + DidvanText('تم برنامه', style: TextStyle( - color: Color.fromARGB( - 255, - 102, - 102, - 102))), + color: Theme.of(context).colorScheme.caption)), ], ), const SizedBox(height: 16), @@ -462,7 +456,7 @@ class _ProfilePageState extends State width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( - color: const Color.fromARGB(255, 230, 243, 250), + color: Theme.of(context).colorScheme.focused, borderRadius: BorderRadius.circular(16), ), child: Center( @@ -472,7 +466,7 @@ class _ProfilePageState extends State .textTheme .titleMedium ?.copyWith( - color: Colors.black, + color: DesignConfig.isDark? Colors.white : Colors.black, fontWeight: FontWeight.normal, fontSize: 15), ), @@ -482,10 +476,10 @@ class _ProfilePageState extends State MenuOption( iconWidget: SvgPicture.asset( 'lib/assets/icons/info-circle.svg'), - titleWidget: const DidvanText('درباره دیدوان', + titleWidget: DidvanText('درباره دیدوان', style: TextStyle( color: - Color.fromARGB(255, 102, 102, 102))), + Theme.of(context).colorScheme.caption)), onTap: () => launchUrlString( 'https://didvan.com/#info', mode: LaunchMode.inAppWebView), @@ -494,10 +488,9 @@ class _ProfilePageState extends State MenuOption( iconWidget: SvgPicture.asset( 'lib/assets/icons/call-calling.svg'), - titleWidget: const DidvanText('تماس با ما', + titleWidget: DidvanText('تماس با ما', style: TextStyle( - color: Color.fromARGB( - 255, 102, 102, 102))), + color: Theme.of(context).colorScheme.caption)), onTap: () { Navigator.of(context) .pushNamed(Routes.directList) @@ -604,10 +597,10 @@ class _ProfilePageState extends State MenuOption( iconWidget: SvgPicture.asset( 'lib/assets/icons/security-safe.svg'), - titleWidget: const DidvanText('حریم خصوصی', + titleWidget: DidvanText('حریم خصوصی', style: TextStyle( color: - Color.fromARGB(255, 102, 102, 102))), + Theme.of(context).colorScheme.caption)), onTap: () => launchUrlString( 'https://didvan.com/terms-of-use#privacy', mode: LaunchMode.inAppWebView), diff --git a/lib/views/radar/radar.dart b/lib/views/radar/radar.dart index 248fafb..05d4eb5 100644 --- a/lib/views/radar/radar.dart +++ b/lib/views/radar/radar.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:math'; +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/models/category.dart'; import 'package:didvan/models/enums.dart'; @@ -108,7 +109,7 @@ class _RadarStateView extends State { colorFilter: ColorFilter.mode( isDark ? Colors.white70 - : const Color.fromARGB(255, 102, 102, 102), + : Theme.of(context).colorScheme.caption, BlendMode.srcIn), ), ), diff --git a/lib/views/widgets/audio/audio_player_widget.dart b/lib/views/widgets/audio/audio_player_widget.dart index d017249..fe8dd87 100644 --- a/lib/views/widgets/audio/audio_player_widget.dart +++ b/lib/views/widgets/audio/audio_player_widget.dart @@ -36,7 +36,6 @@ class AudioPlayerWidget extends StatelessWidget { aspectRatio: 1 / 1.3, borderRadius: BorderRadius.circular(0), ), - Positioned( bottom: 0, left: 0, @@ -127,9 +126,7 @@ class AudioPlayerWidget extends StatelessWidget { .withOpacity(0.7), ), ), - const SizedBox(width: 8), - Expanded( child: AudioWaveformProgress( progress: progress.clamp(0.0, 1.0), @@ -147,7 +144,6 @@ class AudioPlayerWidget extends StatelessWidget { ), ), const SizedBox(width: 8), - Text( _formatDuration(position), style: TextStyle( @@ -168,9 +164,7 @@ class AudioPlayerWidget extends StatelessWidget { ], ), ), - const SizedBox(height: 16), - Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -187,8 +181,8 @@ class AudioPlayerWidget extends StatelessWidget { 'lib/assets/icons/timer-pause.svg', width: 35, height: 35, - colorFilter: const ColorFilter.mode( - Color.fromARGB(255, 102, 102, 102), + colorFilter: ColorFilter.mode( + Theme.of(context).colorScheme.caption, BlendMode.srcIn, ), ), @@ -245,7 +239,12 @@ class AudioPlayerWidget extends StatelessWidget { ); }, icon: SvgPicture.asset( - 'lib/assets/icons/forward-10-seconds.svg'), + 'lib/assets/icons/forward-10-seconds.svg', + colorFilter: ColorFilter.mode( + Theme.of(context).colorScheme.caption, + BlendMode.srcIn, + ), + ), ), ), ), @@ -291,7 +290,12 @@ class AudioPlayerWidget extends StatelessWidget { ); }, icon: SvgPicture.asset( - 'lib/assets/icons/backward-5-seconds.svg'), + 'lib/assets/icons/backward-5-seconds.svg', + colorFilter: ColorFilter.mode( + Theme.of(context).colorScheme.caption, + BlendMode.srcIn, + ), + ), ), ), ), @@ -310,8 +314,8 @@ class AudioPlayerWidget extends StatelessWidget { child: Container( width: 46, alignment: Alignment.center, - margin: const EdgeInsets.fromLTRB( - 12, 0, 0, 0), // تغییر: 46 پایین حذف شد + margin: + const EdgeInsets.fromLTRB(12, 0, 0, 0), padding: const EdgeInsets.only(top: 2), decoration: BoxDecoration( borderRadius: @@ -323,10 +327,12 @@ class AudioPlayerWidget extends StatelessWidget { padding: const EdgeInsets.all(8.0), child: DidvanText( '${snapshot.data!.toString().replaceAll('.0', '')}X', - style: const TextStyle( - fontWeight: FontWeight.w900, - color: Color.fromARGB( - 255, 102, 102, 102)), + style: TextStyle( + fontWeight: FontWeight.w900, + color: Theme.of(context) + .colorScheme + .caption, + ), ), ), ), @@ -350,7 +356,6 @@ class AudioPlayerWidget extends StatelessWidget { ), ], ), - // اضافه کردن کمی فاصله در پایین const SizedBox(height: 16), ], ), @@ -410,14 +415,15 @@ class AudioPlayerWidget extends StatelessWidget { SvgPicture.asset( 'lib/assets/icons/timer-pause.svg', height: 24, - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), const SizedBox( width: 10, ), - const Text( + Text( 'زمان خواب', - style: TextStyle(color: Color.fromARGB(255, 102, 102, 102)), + style: + TextStyle(color: Theme.of(context).colorScheme.caption), ) ], ), diff --git a/lib/views/widgets/carousel_3d.dart b/lib/views/widgets/carousel_3d.dart index f8ff2d3..65b52d3 100644 --- a/lib/views/widgets/carousel_3d.dart +++ b/lib/views/widgets/carousel_3d.dart @@ -1,16 +1,17 @@ +// ignore_for_file: deprecated_member_use + import 'dart:async'; -import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; - class Carousel3D extends StatefulWidget { final List items; final double height; final Duration autoPlayDuration; final Function(int)? onItemChanged; final bool showControls; + final void Function(int index)? onItemTap; const Carousel3D({ super.key, @@ -19,17 +20,23 @@ class Carousel3D extends StatefulWidget { this.autoPlayDuration = const Duration(seconds: 4), this.onItemChanged, this.showControls = true, + this.onItemTap, }); @override State createState() => _Carousel3DState(); } -class _Carousel3DState extends State with SingleTickerProviderStateMixin { +class _Carousel3DState extends State + with SingleTickerProviderStateMixin { late final AnimationController _controller; Timer? _autoPlayTimer; int _currentIndex = 0; int _targetIndex = 0; + double _dragDelta = 0.0; + static const double _dragDistanceToComplete = 120.0; + static const double _dragDistanceThreshold = 20.0; // was 40 + static const double _dragVelocityThreshold = 150.0; // was 300 @override void initState() { @@ -75,7 +82,6 @@ class _Carousel3DState extends State with SingleTickerProviderStateM _goToIndex((_currentIndex - 1 + widget.items.length) % widget.items.length); } - @override void dispose() { _autoPlayTimer?.cancel(); @@ -89,87 +95,180 @@ class _Carousel3DState extends State with SingleTickerProviderStateM return Column( children: [ - SizedBox( - height: widget.height, - child: AnimatedBuilder( - animation: _controller, - builder: (context, child) { - return Stack( - alignment: Alignment.center, - children: List.generate(widget.items.length, (index) { - final double currentRelativePos = (index - _currentIndex).toDouble(); - final double targetRelativePos = (index - _targetIndex).toDouble(); - final double relativePos = Tween( - begin: currentRelativePos, - end: targetRelativePos, - ).transform(CurvedAnimation(parent: _controller, curve: Curves.easeInOutCubic).value); + GestureDetector( + behavior: HitTestBehavior.opaque, + onHorizontalDragStart: (_) { + _autoPlayTimer?.cancel(); + _dragDelta = 0.0; + _controller.stop(); + _controller.value = 0.0; + }, + onHorizontalDragUpdate: (details) { + _dragDelta += details.delta.dx; + final len = widget.items.length; + final bool dragLeft = _dragDelta < 0; + final int newTarget = dragLeft + ? (_currentIndex - 1 + len) % len + : (_currentIndex + 1) % len; + if (newTarget != _targetIndex) { + setState(() => _targetIndex = newTarget); + } + final double progress = + (_dragDelta.abs() / _dragDistanceToComplete).clamp(0.0, 1.0); + _controller.value = progress; + }, + onHorizontalDragEnd: (details) { + final velocity = details.primaryVelocity ?? 0.0; + final bool commit = velocity.abs() > _dragVelocityThreshold || + _dragDelta.abs() > _dragDistanceThreshold; - final bool isGrayscale = relativePos != 0; - final double absRelativePos = relativePos.abs(); + if (commit) { + _controller + .animateTo(1.0, + duration: const Duration(milliseconds: 150), + curve: Curves.easeOut) + .then((_) { + setState(() { + _currentIndex = _targetIndex; + }); + widget.onItemChanged?.call(_currentIndex); + _controller.value = 0.0; + _dragDelta = 0.0; + _startAutoPlay(); + }); + } else { + setState(() { + _targetIndex = _currentIndex; + }); + _controller + .animateBack(0.0, + duration: const Duration(milliseconds: 150), + curve: Curves.easeOut) + .then((_) { + _dragDelta = 0.0; + _startAutoPlay(); + }); + } + }, + child: SizedBox( + height: widget.height, + child: AnimatedBuilder( + animation: _controller, + builder: (context, child) { + return Stack( + alignment: Alignment.center, + children: List.generate(widget.items.length, (index) { + final int len = widget.items.length; + final int half = len ~/ 2; - final double scale = (1 - (absRelativePos * 0.15)).clamp(0.0, 1.0); - final double translateX = relativePos * -30.0; - final double translateZ = absRelativePos * -100.0; - final double opacity = (1 - (absRelativePos * 0.3)).clamp(0.0, 1.0); + int circularDelta(int i, int center) { + int raw = i - center; + if (raw > half) raw -= len; + if (raw < -half) raw += len; + return raw; + } - Matrix4 transform = Matrix4.identity() - ..setEntry(3, 2, 0.001) - ..translate(translateX, 0.0, translateZ) - ..scale(scale); + final double currentRelativePos = + circularDelta(index, _currentIndex).toDouble(); + final double targetRelativePos = + circularDelta(index, _targetIndex).toDouble(); + final double relativePos = Tween( + begin: currentRelativePos, + end: targetRelativePos, + ).transform(CurvedAnimation( + parent: _controller, curve: Curves.easeInOutCubic) + .value); - return Transform( - transform: transform, - alignment: Alignment.center, - child: Opacity( - opacity: opacity, - child: GestureDetector( - onTap: () { - if (relativePos != 0) { - _goToIndex(index); - } - }, - child: Container( - width: screenWidth * 0.7, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(isGrayscale ? 0.1 : 0.25), - spreadRadius: 2, - blurRadius: 10, - offset: const Offset(0, 5), - ), - ], - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(12), - child: ColorFiltered( - colorFilter: isGrayscale - ? 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, - ]) - : const ColorFilter.mode( - Colors.transparent, - BlendMode.multiply, - ), - child: widget.items[index], - ), - ), - ), + final bool isGrayscale = relativePos != 0; + final double absRelativePos = relativePos.abs(); + + final double scale = + (1 - (absRelativePos * 0.15)).clamp(0.0, 1.0); + final double translateX = relativePos * -30.0; + final double translateZ = absRelativePos * -100.0; + final double opacity = + (1 - (absRelativePos * 0.3)).clamp(0.0, 1.0); + + Matrix4 transform = Matrix4.identity() + ..setEntry(3, 2, 0.001) + ..translate(translateX, 0.0, translateZ) + ..scale(scale); + + return Transform( + transform: transform, + alignment: Alignment.center, + child: Opacity( + opacity: opacity, + child: IgnorePointer( + ignoring: relativePos != 0, + child: GestureDetector( + onTap: relativePos == 0 + ? () => widget.onItemTap?.call(index) + : null, + child: Container( + width: screenWidth * 0.7, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.black + .withOpacity(isGrayscale ? 0.1 : 0.25), + spreadRadius: 2, + blurRadius: 10, + offset: const Offset(0, 5), + ), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: ColorFiltered( + colorFilter: isGrayscale + ? 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, + ]) + : const ColorFilter.mode( + Colors.transparent, + BlendMode.multiply, + ), + child: widget.items[index], + ), + ), + ), + ), + ), ), - ), - ); - }).toList() - ..sort((a, b) { - final transformA = a.transform; - final transformB = b.transform; - return transformA.getTranslation().z.compareTo(transformB.getTranslation().z); - }), - ); - }, + ); + }).toList() + ..sort((a, b) { + final transformA = a.transform; + final transformB = b.transform; + return transformA + .getTranslation() + .z + .compareTo(transformB.getTranslation().z); + }), + ); + }, + ), ), ), if (widget.showControls) ...[ @@ -212,4 +311,4 @@ class _Carousel3DState extends State with SingleTickerProviderStateM ], ); } -} \ No newline at end of file +} diff --git a/lib/views/widgets/custom_media_tab_bar.dart b/lib/views/widgets/custom_media_tab_bar.dart index 86eb94a..bab878f 100644 --- a/lib/views/widgets/custom_media_tab_bar.dart +++ b/lib/views/widgets/custom_media_tab_bar.dart @@ -1,3 +1,4 @@ +import 'package:didvan/config/theme_data.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -57,7 +58,7 @@ class _CustomMediaTabBarState extends State { colorFilter: ColorFilter.mode( isSelected ? Theme.of(context).colorScheme.primary - : const Color.fromARGB(255, 102, 102, 102), + : Theme.of(context).colorScheme.caption, BlendMode.srcIn, ), ), @@ -73,7 +74,7 @@ class _CustomMediaTabBarState extends State { style: Theme.of(context).textTheme.bodySmall!.copyWith( color: isSelected ? Theme.of(context).colorScheme.primary - : const Color.fromARGB(255, 102, 102, 102), + : Theme.of(context).colorScheme.caption, fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400, ), ), diff --git a/lib/views/widgets/didvan/bnb.dart b/lib/views/widgets/didvan/bnb.dart index 89c75c6..7fbc1ea 100644 --- a/lib/views/widgets/didvan/bnb.dart +++ b/lib/views/widgets/didvan/bnb.dart @@ -313,7 +313,7 @@ class _NavBarItemState extends State<_NavBarItem> child: DidvanText( widget.title, style: Theme.of(context).textTheme.bodySmall, - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, fontWeight: FontWeight.w500, ), ) diff --git a/lib/views/widgets/didvan/page_view.dart b/lib/views/widgets/didvan/page_view.dart index 8d20b0a..939e359 100644 --- a/lib/views/widgets/didvan/page_view.dart +++ b/lib/views/widgets/didvan/page_view.dart @@ -103,7 +103,7 @@ class _DidvanPageViewState extends State { appBar: PreferredSize( preferredSize: const Size.fromHeight(90.0), child: AppBar( - backgroundColor: Colors.white, + backgroundColor: Theme.of(context).colorScheme.surface, elevation: 0, automaticallyImplyLeading: false, flexibleSpace: SafeArea( @@ -122,7 +122,7 @@ class _DidvanPageViewState extends State { IconButton( icon: SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, height: 24, ), onPressed: () { @@ -555,9 +555,9 @@ class _DidvanPageViewState extends State { children: [ DidvanText( _formatDuration(totalDuration), - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), const SizedBox(width: 8), @@ -578,9 +578,9 @@ class _DidvanPageViewState extends State { const SizedBox(width: 8), DidvanText( _formatDuration(position), - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ], @@ -603,7 +603,7 @@ class _DidvanPageViewState extends State { 'lib/assets/icons/timer-pause.svg', width: 24, height: 24, - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), onPressed: () { ScaffoldMessenger.of(context).showSnackBar(const SnackBar( @@ -686,12 +686,12 @@ class _DidvanPageViewState extends State { decoration: BoxDecoration( borderRadius: DesignConfig.mediumBorderRadius, border: Border.all( - color: const Color.fromARGB(255, 102, 102, 102))), + color: Theme.of(context).colorScheme.caption)), child: DidvanText( '${snapshot.data!.toString().replaceAll('.0', '')}X', - style: const TextStyle( + style: TextStyle( fontWeight: FontWeight.w900, - color: Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, fontSize: 12), ), ), @@ -877,7 +877,7 @@ class _DidvanPageViewState extends State { DidvanText( DateTime.parse(item.createdAt!).toPersianDateStr(), style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ], @@ -892,7 +892,7 @@ class _DidvanPageViewState extends State { DidvanText( DateTime.parse(item.createdAt!).toPersianDateStr(), style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ), ], diff --git a/lib/views/widgets/didvan/text_field.dart b/lib/views/widgets/didvan/text_field.dart index f1950cb..d0359d9 100644 --- a/lib/views/widgets/didvan/text_field.dart +++ b/lib/views/widgets/didvan/text_field.dart @@ -199,7 +199,7 @@ class _DidvanTextFieldState extends State { Color _borderColor() { if (_focusNode.hasFocus) { - return const Color.fromARGB(255, 102, 102, 102); + return Theme.of(context).colorScheme.caption; } else if (_error != null) { return Theme.of(context).colorScheme.error; } @@ -213,7 +213,7 @@ class _DidvanTextFieldState extends State { if (_error != null) { return Theme.of(context).colorScheme.error; } - return const Color.fromARGB(255, 102, 102, 102); + return Theme.of(context).colorScheme.caption; } Color _fillColor() { @@ -247,6 +247,9 @@ class _DidvanTextFieldState extends State { _hideContent ? 'lib/assets/icons/eye.svg' : 'lib/assets/icons/eye-slash.svg', + color: DesignConfig.isDark + ? Theme.of(context).colorScheme.caption + : null, height: 20, ), ), diff --git a/lib/views/widgets/hoshan_app_bar.dart b/lib/views/widgets/hoshan_app_bar.dart index 0dacfa1..64d3a2a 100644 --- a/lib/views/widgets/hoshan_app_bar.dart +++ b/lib/views/widgets/hoshan_app_bar.dart @@ -1,3 +1,4 @@ +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/views/ai/history_ai_chat_state.dart'; @@ -19,6 +20,7 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { return Container( + color: Theme.of(context).colorScheme.surface, padding: const EdgeInsets.all(16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -80,6 +82,7 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget { padding: const EdgeInsets.all(8), child: SvgPicture.asset( 'lib/assets/icons/history.svg', + color: Theme.of(context).colorScheme.inputText, height: 24, ), ), @@ -90,6 +93,7 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget { if (withInfo) DidvanIconButton( icon: DidvanIcons.angle_left_light, + color: Theme.of(context).colorScheme.inputText, size: 32, onPressed: () => onBack?.call(), ), diff --git a/lib/views/widgets/hoshan_home_app_bar.dart b/lib/views/widgets/hoshan_home_app_bar.dart index c2d3c24..822b33c 100644 --- a/lib/views/widgets/hoshan_home_app_bar.dart +++ b/lib/views/widgets/hoshan_home_app_bar.dart @@ -1,5 +1,5 @@ +import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; -import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/models/ai/ai_chat_args.dart'; import 'package:didvan/providers/user.dart'; @@ -84,9 +84,11 @@ class _HoshanHomeAppBarState extends State { final userProvider = context.watch(); return Container( - decoration: const BoxDecoration( - color: Color.fromRGBO(230, 242, 246, 1), - borderRadius: BorderRadius.only( + decoration: BoxDecoration( + color: DesignConfig.isDark + ? const Color.fromARGB(255, 78, 82, 84) + : const Color.fromRGBO(230, 242, 246, 1), + borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(32), bottomRight: Radius.circular(32), ), @@ -121,6 +123,7 @@ class _HoshanHomeAppBarState extends State { child: SvgPicture.asset( 'lib/assets/icons/history.svg', height: 24, + color: Theme.of(context).colorScheme.inputText, ), ), ), @@ -148,7 +151,9 @@ class _HoshanHomeAppBarState extends State { padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 11), decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 195, 195, 196) + : Colors.white, borderRadius: BorderRadius.circular(30), border: Border.all( color: const Color.fromARGB(255, 25, 93, 128), @@ -308,7 +313,9 @@ class _HistoryDrawerContentState extends State { width: MediaQuery.of(context).size.width * 0.75, height: MediaQuery.of(context).size.height, decoration: BoxDecoration( - color: const Color.fromARGB(255, 237, 237, 237), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 166, 166, 166) + : const Color.fromARGB(255, 237, 237, 237), boxShadow: [ BoxShadow( // ignore: deprecated_member_use @@ -390,11 +397,16 @@ class _HistoryDrawerContentState extends State { padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 11), decoration: BoxDecoration( - color: Colors.white, + color: DesignConfig.isDark + ? const Color.fromARGB(255, 155, 154, 154) + : const Color.fromARGB(255, 237, 237, 237), borderRadius: BorderRadius.circular(8), border: Border.all( - color: const Color.fromARGB( - 255, 223, 223, 223), + color: DesignConfig.isDark + ? const Color.fromARGB( + 255, 107, 106, 106) + : const Color.fromARGB( + 255, 223, 223, 223), width: 1)), child: Row( children: [ @@ -404,11 +416,14 @@ class _HistoryDrawerContentState extends State { Expanded( child: TextField( controller: _searchController, - decoration: const InputDecoration( + decoration: InputDecoration( hintText: 'جستجو', hintStyle: TextStyle( - color: Color.fromARGB( - 255, 161, 160, 160), + color: DesignConfig.isDark + ? const Color.fromARGB( + 255, 113, 112, 1112) + : const Color.fromARGB( + 255, 161, 160, 160), fontSize: 14), border: InputBorder.none, isDense: true, @@ -460,11 +475,13 @@ class _HistoryDrawerContentState extends State { ), ), ), - const Padding( - padding: EdgeInsets.fromLTRB(40, 10, 40, 0), + Padding( + padding: const EdgeInsets.fromLTRB(40, 10, 40, 0), child: Divider( height: 3, - color: Color.fromARGB(255, 161, 160, 160), + color: DesignConfig.isDark + ? const Color.fromARGB(255, 113, 112, 1112) + : const Color.fromARGB(255, 161, 160, 160), ), ), Expanded( @@ -716,7 +733,6 @@ class _HistoryDrawerContentState extends State { ), ), ), - const PopupMenuDivider(height: 10), ], ), ], diff --git a/lib/views/widgets/infography_tag.dart b/lib/views/widgets/infography_tag.dart index afefa91..6563854 100644 --- a/lib/views/widgets/infography_tag.dart +++ b/lib/views/widgets/infography_tag.dart @@ -1,4 +1,5 @@ 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'; @@ -42,16 +43,16 @@ class InfographyTag extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - const Icon( + Icon( DidvanIcons.hashtag_regular, - color: Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, size: 16, ), Padding( padding: const EdgeInsets.all(2.0), child: DidvanText( tag.label, - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, style: Theme.of(context).textTheme.labelMedium, ), ), diff --git a/lib/views/widgets/menu_item.dart b/lib/views/widgets/menu_item.dart index de02e4d..28e6d41 100644 --- a/lib/views/widgets/menu_item.dart +++ b/lib/views/widgets/menu_item.dart @@ -77,7 +77,7 @@ class MenuOption extends StatelessWidget { child: trailing ?? SvgPicture.asset( 'lib/assets/icons/arrow-left.svg', - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, ), ) ], diff --git a/lib/views/widgets/overview/news.dart b/lib/views/widgets/overview/news.dart index 5ed5e27..158a760 100644 --- a/lib/views/widgets/overview/news.dart +++ b/lib/views/widgets/overview/news.dart @@ -1,3 +1,4 @@ +import 'package:didvan/config/theme_data.dart'; import 'package:didvan/models/overview_data.dart'; import 'package:didvan/models/requests/news.dart'; import 'package:didvan/routes/routes.dart'; @@ -124,7 +125,7 @@ class NewsOverview extends StatelessWidget { onLikedChanged(news.id, value, false), askForConfirmation: hasUnmarkConfirmation, likes: news.likes, - unlikedColor: const Color.fromARGB(255, 102, 102, 102), + unlikedColor: Theme.of(context).colorScheme.caption, ), const SizedBox( width: 4.0, @@ -139,8 +140,8 @@ class NewsOverview extends StatelessWidget { askForConfirmation: hasUnmarkConfirmation, svgIconOn: 'lib/assets/icons/bookmark_fill.svg', svgIconOff: 'lib/assets/icons/archive-tick.svg', - color: const Color.fromARGB(255, 102, 102, 102), - unbookmarkedColor: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, + unbookmarkedColor: Theme.of(context).colorScheme.caption, ), ], ) diff --git a/lib/views/widgets/overview/radar.dart b/lib/views/widgets/overview/radar.dart index f02b89e..69231f0 100644 --- a/lib/views/widgets/overview/radar.dart +++ b/lib/views/widgets/overview/radar.dart @@ -160,7 +160,7 @@ class RadarOverview extends StatelessWidget { onLikedChanged(radar.id, value, false), askForConfirmation: hasUnmarkConfirmation, likes: radar.likes, - unlikedColor: const Color.fromARGB(255, 102, 102, 102), + unlikedColor: Theme.of(context).colorScheme.caption, ), const SizedBox( width: 4.0, @@ -175,9 +175,9 @@ class RadarOverview extends StatelessWidget { askForConfirmation: hasUnmarkConfirmation, svgIconOn: 'lib/assets/icons/bookmark_fill.svg', svgIconOff: 'lib/assets/icons/archive-tick.svg', - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, unbookmarkedColor: - const Color.fromARGB(255, 102, 102, 102), + Theme.of(context).colorScheme.caption, ), ], ), diff --git a/lib/views/widgets/search_field.dart b/lib/views/widgets/search_field.dart index 5d511ab..49b100f 100644 --- a/lib/views/widgets/search_field.dart +++ b/lib/views/widgets/search_field.dart @@ -1,3 +1,4 @@ +import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/theme_data.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -50,13 +51,15 @@ class _SearchFieldState extends State { Expanded( child: Container( decoration: BoxDecoration( - color: const Color.fromARGB(255, 235, 235, 235), + color: DesignConfig.isDark? const Color.fromARGB(255, 188, 188, 188) : const Color.fromARGB(255, 235, 235, 235), borderRadius: BorderRadius.circular(40), ), child: TextFormField( initialValue: widget.value, focusNode: widget.focusNode, - style: Theme.of(context).textTheme.bodyMedium, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color:Colors.black, + ), textAlignVertical: TextAlignVertical.center, onChanged: widget.onChanged, keyboardType: TextInputType.text, @@ -143,8 +146,8 @@ class _SearchFieldState extends State { ), border: InputBorder.none, hintText: 'جست‌وجو در ${widget.title}', - hintStyle: const TextStyle( - color: Color.fromARGB(255, 122, 122, 122), + hintStyle: TextStyle( + color: DesignConfig.isDark? const Color.fromARGB(255, 98, 98, 98) : const Color.fromARGB(255, 122, 122, 122), fontSize: 13, ), ), diff --git a/lib/views/widgets/tag_item.dart b/lib/views/widgets/tag_item.dart index b83bd87..67b765d 100644 --- a/lib/views/widgets/tag_item.dart +++ b/lib/views/widgets/tag_item.dart @@ -1,4 +1,5 @@ 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'; @@ -44,14 +45,14 @@ class TagItem extends StatelessWidget { child: Row( mainAxisSize: MainAxisSize.min, children: [ - const Icon( + Icon( DidvanIcons.hashtag_regular, - color: Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, size: 17, ), DidvanText( tag.label, - color: const Color.fromARGB(255, 102, 102, 102), + color: Theme.of(context).colorScheme.caption, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), ), ], diff --git a/lib/views/widgets/text_divider.dart b/lib/views/widgets/text_divider.dart index 978afbf..2750983 100644 --- a/lib/views/widgets/text_divider.dart +++ b/lib/views/widgets/text_divider.dart @@ -1,3 +1,4 @@ +import 'package:didvan/config/design_config.dart'; import 'package:flutter/material.dart'; class TextDivider extends StatelessWidget { @@ -37,7 +38,7 @@ class TextDivider extends StatelessWidget { text, style: textStyle ?? Theme.of(context).textTheme.bodyLarge?.copyWith( - color: const Color.fromARGB(255, 0, 53, 70), + color: DesignConfig.isDark? const Color.fromARGB(255, 0, 90, 119) : const Color.fromARGB(255, 0, 53, 70), fontWeight: FontWeight.bold, ), ),