redesign login page

This commit is contained in:
Mr.Jebelli 2025-11-15 16:01:18 +03:30
parent 66f4e4906b
commit a421c56d0b
68 changed files with 1545 additions and 592 deletions

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.375 11.125C12.0078 11.125 12.5 10.6328 12.5 10C12.5 9.40234 11.9727 8.875 11.375 8.875H8C7.40234 8.875 6.875 9.40234 6.875 10C6.875 10.6328 7.40234 11.125 8 11.125H11.375ZM11.375 15.625C12.0078 15.625 12.5 15.1328 12.5 14.5C12.5 13.9023 11.9727 13.375 11.375 13.375H5.75C5.15234 13.375 4.625 13.9023 4.625 14.5C4.625 15.1328 5.15234 15.625 5.75 15.625H11.375ZM11.375 6.625C12.0078 6.625 12.5 6.13281 12.5 5.5C12.5 4.90234 12.0078 4.375 11.375 4.375H10.25C9.6875 4.375 9.16016 4.90234 9.16016 5.5C9.16016 6.13281 9.65234 6.625 10.25 6.625H11.375ZM3.5 17.875C2.90234 17.875 2.375 18.4023 2.375 19C2.375 19.6328 2.90234 20.125 3.5 20.125H11.375C11.9727 20.125 12.5 19.6328 12.5 19C12.5 18.4023 11.9727 17.875 11.375 17.875H3.5ZM15.875 14.8867C15.4531 14.4297 14.75 14.3945 14.3633 14.8164C13.9062 15.2383 13.8711 15.9414 14.293 16.4336L17.3516 19.8086C17.7734 20.2656 18.582 20.2656 19.0039 19.8086L22.0625 16.4336C22.4844 15.9414 22.4492 15.2383 21.9922 14.8164C21.7812 14.6406 21.5 14.5352 21.2539 14.5352C20.9375 14.5352 20.6211 14.6406 20.4102 14.8867L19.25 16.1523V5.53516C19.25 4.90234 18.7578 4.375 18.125 4.375C17.5273 4.375 17 4.90234 17 5.53516V16.1523L15.875 14.8867Z" fill="#1B3C59"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

4
lib/assets/icons/pen.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.6753 2.67773C16.3055 2.59714 17.071 2.8031 18.0161 3.63086L18.2075 3.80469C19.2458 4.78697 19.535 5.60019 19.4878 6.27637C19.4448 6.89114 19.1184 7.50127 18.5806 8.12695L18.3364 8.39648L10.1265 17.0869L10.1206 17.0938C10.0168 17.2075 9.83425 17.343 9.61182 17.4619C9.39038 17.5803 9.17068 17.6593 9.01221 17.6875L5.79541 18.2373H5.79443C5.34835 18.3141 5.01422 18.1943 4.80518 17.9961C4.59576 17.7975 4.45651 17.468 4.50635 17.0166L4.87549 13.7861C4.89674 13.627 4.96716 13.4025 5.07471 13.1719C5.18266 12.9404 5.30723 12.745 5.41357 12.6318L13.6235 3.94336L13.6226 3.94238C14.3045 3.22217 14.9773 2.76717 15.6753 2.67773Z" stroke="#007EA7" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.89 5.0498C12.0996 6.39066 12.7486 7.62394 13.735 8.55605C14.7214 9.48816 15.9894 10.0663 17.34 10.1998M3 21.9998H21" stroke="#007EA7" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 KiB

View File

@ -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<String, dynamic> json) {
return DidvanPlusModel(
id: json['id'],
image: json['image'],
file: json['file'],
publishedAt: json['publishedAt'],
);
}
}

View File

@ -23,6 +23,8 @@ class RequestHelper {
static const String checkHasPassword = '$_baseUserUrl/checkHasPassword'; static const String checkHasPassword = '$_baseUserUrl/checkHasPassword';
static const String mainPageContent = _baseHomeUrl; static const String mainPageContent = _baseHomeUrl;
static const String didvanPlus = '$baseUrl/didvanPlus';
static String searchAll({ static String searchAll({
required int page, required int page,
String? startDate, String? startDate,

View File

@ -90,4 +90,15 @@ extension StringUrl on String {
char; // Replace with English number if exists, else keep original char char; // Replace with English number if exists, else keep original char
}).join(''); }).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;
}
} }

View File

@ -425,10 +425,12 @@ class _AiChatPageState extends State<AiChatPage> with TickerProviderStateMixin {
), ),
); );
}, },
child: const Text( child: Text(
'چطور می‌تونم کمکت کنم؟', 'چطور می‌تونم کمکت کنم؟',
style: TextStyle( 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, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),

View File

@ -94,13 +94,13 @@ class _HistoryAiChatPageState extends State<HistoryAiChatPage> {
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Padding( Padding(
padding: EdgeInsets.all(8.0), padding: EdgeInsets.all(8.0),
child: Text('فهرست آرشیوشده‌ها', child: Text('فهرست آرشیوشده‌ها',
style: TextStyle( style: TextStyle(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, 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( // SearchField(
// title: 'گفت‌و‌گو‌ها', // title: 'گفت‌و‌گو‌ها',

View File

@ -173,9 +173,9 @@ class _InfoPageState extends State<InfoPage> {
children: [ children: [
Container( Container(
margin: const EdgeInsets.only(left: 8), margin: const EdgeInsets.only(left: 8),
decoration: const ShapeDecoration( decoration: ShapeDecoration(
shape: CircleBorder( shape: CircleBorder(
side: BorderSide(width: 3, color: Colors.black)), side: BorderSide(width: 3, color: DesignConfig.isDark? Colors.white : Colors.black)),
), ),
), ),
DidvanText( DidvanText(

View File

@ -251,6 +251,7 @@ class _AiMessageBarState extends State<AiMessageBar> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<AiChatState>(builder: (context, state, child) { return Consumer<AiChatState>(builder: (context, state, child) {
final theme = Theme.of(context); final theme = Theme.of(context);
final isDark = theme.brightness == Brightness.dark;
return Container( return Container(
padding: const EdgeInsets.fromLTRB(12, 24, 12, 0).copyWith( padding: const EdgeInsets.fromLTRB(12, 24, 12, 0).copyWith(
@ -266,7 +267,9 @@ class _AiMessageBarState extends State<AiMessageBar> {
children: [ children: [
Container( Container(
decoration: BoxDecoration( 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( border: Border.all(
color: const Color.fromARGB(255, 0, 126, 167), color: const Color.fromARGB(255, 0, 126, 167),
width: 1.5), width: 1.5),
@ -357,6 +360,10 @@ class _AiMessageBarState extends State<AiMessageBar> {
SvgPicture.asset( SvgPicture.asset(
'lib/assets/icons/ChatGPT-Logo.svg', 'lib/assets/icons/ChatGPT-Logo.svg',
height: 17, height: 17,
color: DesignConfig.isDark
? const Color.fromARGB(
255, 195, 195, 196)
: null,
), ),
const SizedBox(width: 12.0), const SizedBox(width: 12.0),
const DidvanText( const DidvanText(
@ -388,6 +395,10 @@ class _AiMessageBarState extends State<AiMessageBar> {
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
'lib/assets/icons/grok.svg', 'lib/assets/icons/grok.svg',
color: DesignConfig.isDark
? const Color.fromARGB(
255, 195, 195, 196)
: null,
height: 17, height: 17,
), ),
const SizedBox(width: 12.0), const SizedBox(width: 12.0),
@ -411,13 +422,20 @@ class _AiMessageBarState extends State<AiMessageBar> {
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
icon, icon,
color: DesignConfig.isDark
? const Color.fromARGB(
255, 195, 195, 196)
: null,
height: 17, height: 17,
), ),
const SizedBox(width: 8.0), const SizedBox(width: 8.0),
DidvanText( DidvanText(
label, label,
fontSize: 14, fontSize: 14,
color: const Color.fromARGB( color: DesignConfig.isDark
? const Color.fromARGB(
255, 195, 195, 196)
: const Color.fromARGB(
255, 61, 61, 61), 255, 61, 61, 61),
), ),
const SizedBox(width: 4.0), const SizedBox(width: 4.0),
@ -470,11 +488,11 @@ class _AiMessageBarState extends State<AiMessageBar> {
height: 25, height: 25,
), ),
const SizedBox(width: 8.0), const SizedBox(width: 8.0),
const DidvanText( DidvanText(
'جستجو در وب', 'جستجو در وب',
fontSize: 14, fontSize: 14,
color: Color.fromARGB( color:
255, 61, 61, 61), theme.colorScheme.inputText,
), ),
], ],
), ),
@ -634,9 +652,13 @@ class _AiMessageBarState extends State<AiMessageBar> {
} }
TextFormField edittext(BuildContext context, AiChatState state) { TextFormField edittext(BuildContext context, AiChatState state) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return TextFormField( return TextFormField(
textInputAction: TextInputAction.newline, 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, minLines: 1,
maxLines: 6, maxLines: 6,
keyboardType: TextInputType.multiline, keyboardType: TextInputType.multiline,

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/models/ai/ai_chat_args.dart'; import 'package:didvan/models/ai/ai_chat_args.dart';
import 'package:didvan/models/ai/bots_model.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/history_ai_chat_state.dart';
import 'package:didvan/views/ai/ai_state.dart'; import 'package:didvan/views/ai/ai_state.dart';
class AiSectionPage extends StatefulWidget { class AiSectionPage extends StatefulWidget {
const AiSectionPage({super.key}); const AiSectionPage({super.key});
@ -33,7 +33,8 @@ class _AiSectionGridItem {
}); });
} }
class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateMixin { class _AiSectionPageState extends State<AiSectionPage>
with TickerProviderStateMixin {
late final List<_AiSectionGridItem> _gridItems; late final List<_AiSectionGridItem> _gridItems;
late AnimationController _fadeController; late AnimationController _fadeController;
late AnimationController _slideController; late AnimationController _slideController;
@ -219,8 +220,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
return Column( return Column(
children: [ children: [
if (!aiState.isChatting) if (!aiState.isChatting) const HoshanHomeAppBar(),
const HoshanHomeAppBar(),
Expanded( Expanded(
child: aiState.isChatting child: aiState.isChatting
? AiChatPage(args: aiState.currentChatArgs!) ? AiChatPage(args: aiState.currentChatArgs!)
@ -235,8 +235,11 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: Row( child: Row(
children: [ children: [
SvgPicture.asset('lib/assets/icons/clarity_tools-line.svg'), SvgPicture.asset(
const SizedBox(width: 8,), 'lib/assets/icons/clarity_tools-line.svg'),
const SizedBox(
width: 8,
),
DidvanText( DidvanText(
'جعبه ابزار استراتژیک هوشان', 'جعبه ابزار استراتژیک هوشان',
style: Theme.of(context).textTheme.titleMedium, style: Theme.of(context).textTheme.titleMedium,
@ -307,14 +310,16 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
child: SizedBox( child: SizedBox(
width: 180, width: 180,
height: 160, height: 160,
child: _buildGridItemCard(context, _gridItems[columnIndex * 2]), child: _buildGridItemCard(
context, _gridItems[columnIndex * 2]),
), ),
), ),
if (columnIndex * 2 + 1 < _gridItems.length) if (columnIndex * 2 + 1 < _gridItems.length)
Padding( Padding(
padding: const EdgeInsets.only(top: 16.0), padding: const EdgeInsets.only(top: 16.0),
child: TweenAnimationBuilder<double>( child: TweenAnimationBuilder<double>(
duration: Duration(milliseconds: 700 + (columnIndex * 100)), duration:
Duration(milliseconds: 700 + (columnIndex * 100)),
tween: Tween(begin: 0.0, end: 1.0), tween: Tween(begin: 0.0, end: 1.0),
curve: Curves.easeOut, curve: Curves.easeOut,
builder: (context, value, child) { builder: (context, value, child) {
@ -329,7 +334,8 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
child: SizedBox( child: SizedBox(
width: 180, width: 180,
height: 160, height: 160,
child: _buildGridItemCard(context, _gridItems[columnIndex * 2 + 1]), child: _buildGridItemCard(
context, _gridItems[columnIndex * 2 + 1]),
), ),
), ),
), ),
@ -381,7 +387,9 @@ class _AnimatedGridCardState extends State<_AnimatedGridCard> {
transform: Matrix4.identity() transform: Matrix4.identity()
..translate(0.0, _isHovered ? -8.0 : 0.0), ..translate(0.0, _isHovered ? -8.0 : 0.0),
decoration: BoxDecoration( 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), borderRadius: BorderRadius.circular(20),
border: Border.all( border: Border.all(
color: _isHovered color: _isHovered

View File

@ -33,7 +33,8 @@ class _PasswordInputState extends State<PasswordInput> {
onSubmitted: (value) => _onLogin(context), onSubmitted: (value) => _onLogin(context),
autoFocus: true, autoFocus: true,
title: 'کلمه عبور', title: 'کلمه عبور',
hintText: 'کلمه عبور', hintText: 'رمز عبور خود را وارد کنید.',
prefixSvgPath: 'lib/assets/icons/key.svg',
obsecureText: true, obsecureText: true,
validator: (value) => value.length < 8 validator: (value) => value.length < 8
? 'کلمه عبور نمی‌تواند از 8 کاراکتر کمتر باشد' ? 'کلمه عبور نمی‌تواند از 8 کاراکتر کمتر باشد'

View File

@ -35,6 +35,7 @@ class _ResetPasswordState extends State<ResetPassword> {
: null, : null,
hintText: 'کلمه عبور جدید', hintText: 'کلمه عبور جدید',
obsecureText: true, obsecureText: true,
prefixSvgPath: 'lib/assets/icons/key.svg',
), ),
const SizedBox( const SizedBox(
height: 16, height: 16,
@ -47,6 +48,7 @@ class _ResetPasswordState extends State<ResetPassword> {
: null, : null,
hintText: 'تکرار کلمه عبور جدید', hintText: 'تکرار کلمه عبور جدید',
obsecureText: true, obsecureText: true,
prefixSvgPath: 'lib/assets/icons/key.svg',
), ),
const Spacer(), const Spacer(),
DidvanButton( DidvanButton(

View File

@ -33,6 +33,7 @@ class _UsernameInputState extends State<UsernameInput> {
title: 'نام کاربری یا شماره موبایل', title: 'نام کاربری یا شماره موبایل',
hintText: 'نام کاربری یا شماره موبایل', hintText: 'نام کاربری یا شماره موبایل',
textAlign: TextAlign.center, textAlign: TextAlign.center,
prefixSvgPath: 'lib/assets/icons/mobile.svg',
acceptSpace: false, acceptSpace: false,
onSubmitted: (value) => state.confirmUsername(), onSubmitted: (value) => state.confirmUsername(),
validator: (value) { validator: (value) {
@ -57,7 +58,7 @@ class _UsernameInputState extends State<UsernameInput> {
), ),
), ),
DidvanButton( DidvanButton(
title: 'ورود', title: 'ادامه',
onPressed: () { onPressed: () {
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
state.confirmUsername(); state.confirmUsername();
@ -72,7 +73,7 @@ class _UsernameInputState extends State<UsernameInput> {
text: TextSpan( text: TextSpan(
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
children: [ children: [
const TextSpan(text: 'با ورود به دیدوان،'), const TextSpan(text: 'با ورود به اپلیکیشن دیدوان،'),
TextSpan( TextSpan(
text: ' شرایط ', text: ' شرایط ',
style: Theme.of(context) style: Theme.of(context)

View File

@ -2,9 +2,16 @@
import 'dart:async'; 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/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/providers/user.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/authentication_state.dart';
import 'package:didvan/views/authentication/widgets/authentication_layout.dart'; import 'package:didvan/views/authentication/widgets/authentication_layout.dart';
import 'package:didvan/views/widgets/didvan/button.dart'; import 'package:didvan/views/widgets/didvan/button.dart';
@ -27,6 +34,12 @@ class _VerificationState extends State<Verification> {
int _secondsRemaining = 119; int _secondsRemaining = 119;
bool _isResendButtonEnabled = false; bool _isResendButtonEnabled = false;
bool _isConfirmButtonEnabled = false;
String _completedCode = "";
// START: Added state for error
bool _hasError = false;
// END: Added state
@override @override
void initState() { void initState() {
@ -58,37 +71,82 @@ class _VerificationState extends State<Verification> {
await SmsAutoFill().listenForCode(); await SmsAutoFill().listenForCode();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final AuthenticationState state = context.read<AuthenticationState>(); final AuthenticationState state = context.read<AuthenticationState>();
// 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( return WillPopScope(
onWillPop: () async { onWillPop: () async {
_timer?.cancel(); _timer?.cancel();
// منطق بازگشت هماهنگ با authentication.dart
if (state.currentPageIndex == 0) {
return true; return true;
}
if (state.currentPageIndex == 2 && !state.hasPassword) {
state.currentPageIndex = 0; // برگرد به صفحه نام کاربری
return false;
}
state.currentPageIndex--; // در غیر این صورت یکی برگرد
return false;
}, },
child: AuthenticationLayout( child: AuthenticationLayout(
appBarTitle: 'تغییر رمز عبور', appBarTitle: 'تغییر رمز عبور',
children: [ children: [
DidvanText( Row(
'کد 6 رقمی ارسال شده به موبایل', mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
DidvanText('کد تایید پنج رقمی به شماره ',
style: Theme.of(context).textTheme.titleSmall, style: Theme.of(context).textTheme.titleSmall,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
), color: Theme.of(context).colorScheme.caption),
const SizedBox(
height: 8,
),
DidvanText( DidvanText(
state.username, state.username.toString().convertToPersianDigits(),
style: Theme.of(context).textTheme.titleMedium, style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.normal,
fontSize: 15,
color: Theme.of(context).colorScheme.caption),
), ),
const SizedBox( DidvanText(' ارسال شد.',
height: 8,
),
DidvanText(
'را وارد کنید:',
style: Theme.of(context).textTheme.titleSmall, style: Theme.of(context).textTheme.titleSmall,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: Theme.of(context).colorScheme.caption),
],
),
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( const SizedBox(
height: 24, height: 24,
@ -98,43 +156,154 @@ class _VerificationState extends State<Verification> {
child: PinCodeTextField( child: PinCodeTextField(
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
animationType: AnimationType.scale, 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( pinTheme: PinTheme(
fieldHeight: 48, fieldHeight: 58,
fieldWidth: 48, fieldWidth: 58,
selectedColor: Theme.of(context).colorScheme.primary, // START: Dynamic border/bg colors
inactiveColor: Theme.of(context).colorScheme.border, selectedColor: _hasError ? const Color.fromARGB(255, 178, 4, 54) : primaryColor,
activeFillColor: Theme.of(context).colorScheme.primary, inactiveColor: _hasError ? const Color.fromARGB(255, 178, 4, 54) : borderColor,
activeColor: Theme.of(context).colorScheme.primary, 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, borderRadius: DesignConfig.lowBorderRadius,
borderWidth: 1, borderWidth: 1,
shape: PinCodeFieldShape.box, shape: PinCodeFieldShape.box,
), ),
appContext: context, appContext: context,
length: 6, length: 6,
// START: Modified onCompleted
onCompleted: (value) async { onCompleted: (value) async {
final result = await state.verifyOtpToken(value); final result = await state.verifyOtpToken(value);
if (result) { if (result) {
_timer?.cancel(); _timer?.cancel();
} }
}, },
onChanged: (value) {}, // END: Modified onCompleted
), // START: Modified onChanged
), onChanged: (value) {
const Spacer(), setState(() {
DidvanButton( _completedCode = value;
enabled: _isResendButtonEnabled, _isConfirmButtonEnabled = value.length == 6;
onPressed: () { if (_hasError) {
_handleTimer(); _hasError = false; // پاک کردن خطا با شروع تایپ
state.sendOtpToken(); }
});
}, },
title: !_isResendButtonEnabled // END: Modified onChanged
? '$_secondsRemaining ثانیه دیگر' ),
: 'ارسال مجدد کد', ),
// ویجت ارسال مجدد کد
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: _isConfirmButtonEnabled,
// START: Modified onPressed
onPressed: () async {
if (_completedCode.length == 6) {
final result = await state.verifyOtpToken(_completedCode);
if (!result) {
if (mounted) setState(() => _hasError = true);
}
// در صورت موفقیت، onCompleted خودش کار را انجام میدهد
}
},
// 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( const SizedBox(
height: 48, height: 24, // پدینگ نهایی پایین صفحه
), ),
// END: Added RichText
], ],
), ),
); );

View File

@ -1,3 +1,5 @@
// ignore_for_file: deprecated_member_use
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
@ -192,7 +194,7 @@ class _CommentMessageBoxState extends State<CommentMessageBox> {
Container( Container(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
decoration: BoxDecoration( 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), border: Border.all(color: Theme.of(context).colorScheme.border),
borderRadius: BorderRadius.circular(32), borderRadius: BorderRadius.circular(32),
), ),
@ -210,10 +212,9 @@ class _CommentMessageBoxState extends State<CommentMessageBox> {
decoration: InputDecoration( decoration: InputDecoration(
border: InputBorder.none, border: InputBorder.none,
hintText: 'دیدگاه‌های خود را بنویسید...', hintText: 'دیدگاه‌های خود را بنویسید...',
hintStyle: Theme.of(context) hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith(
.textTheme color:
.bodySmall! DesignConfig.isDark ? Colors.white : Colors.black),
.copyWith(color: Colors.black),
), ),
onChanged: (value) => state.text = value, onChanged: (value) => state.text = value,
), ),

View File

@ -94,10 +94,10 @@ class CommentState extends State<Comment> {
children: [ children: [
DidvanText( DidvanText(
comment.user.fullName, comment.user.fullName,
style: const TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: Color.fromARGB(255, 102, 102, 102)), color: Theme.of(context).colorScheme.caption),
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
DidvanText( DidvanText(
@ -122,7 +122,7 @@ class CommentState extends State<Comment> {
const SizedBox(height: 8), const SizedBox(height: 8),
DidvanText( DidvanText(
comment.text, comment.text,
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
if (comment.status == 2) if (comment.status == 2)
@ -180,7 +180,7 @@ class CommentState extends State<Comment> {
child: DidvanText( child: DidvanText(
'پاسخ', 'پاسخ',
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
), ),
], ],

View File

@ -1,5 +1,7 @@
// ignore_for_file: deprecated_member_use // 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/app_icons.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/enums.dart'; import 'package:didvan/models/enums.dart';
@ -137,7 +139,7 @@ class _DirectState extends State<Direct> {
.textTheme .textTheme
.headlineSmall .headlineSmall
?.copyWith( ?.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, fontWeight: FontWeight.bold,
fontSize: 19), fontSize: 19),
), ),
@ -148,8 +150,8 @@ class _DirectState extends State<Direct> {
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
width: 30, width: 30,
height: 30, height: 30,
colorFilter: const ColorFilter.mode( colorFilter: ColorFilter.mode(
Color.fromARGB(255, 102, 102, 102), Theme.of(context).colorScheme.caption,
BlendMode.srcIn), BlendMode.srcIn),
), ),
), ),

View File

@ -84,9 +84,9 @@ class AudioWidget extends StatelessWidget {
width: 45, width: 45,
child: Text( child: Text(
_formatDuration(totalDuration), _formatDuration(totalDuration),
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: Color.fromARGB(255, 102, 102, 102)), color: Theme.of(context).colorScheme.caption),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
@ -111,9 +111,9 @@ class AudioWidget extends StatelessWidget {
width: 45, width: 45,
child: Text( child: Text(
_formatDuration(currentPosition), _formatDuration(currentPosition),
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: Color.fromARGB(255, 102, 102, 102)), color: Theme.of(context).colorScheme.caption),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),

View File

@ -107,8 +107,8 @@ class _MessageState extends State<Message> with SingleTickerProviderStateMixin {
child: Container( child: Container(
margin: const EdgeInsets.only(bottom: 12), margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
decoration: const BoxDecoration( decoration: BoxDecoration(
color: Color.fromARGB(255, 200, 224, 244), color: Theme.of(context).colorScheme.splash,
borderRadius: DesignConfig.mediumBorderRadius, borderRadius: DesignConfig.mediumBorderRadius,
), ),
child: Padding( child: Padding(
@ -189,6 +189,9 @@ class _MessageState extends State<Message> with SingleTickerProviderStateMixin {
'lib/assets/icons/Didvan.svg', 'lib/assets/icons/Didvan.svg',
width: 12, width: 12,
height: 12, height: 12,
color: DesignConfig.isDark
? Colors.white
: null,
), ),
), ),
)) ))
@ -226,10 +229,12 @@ class _MessageState extends State<Message> with SingleTickerProviderStateMixin {
width: 1, width: 1,
), ),
), ),
child: const Icon( child: Icon(
Icons.person_rounded, Icons.person_rounded,
size: 12, size: 12,
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
), ),
); );
}, },
@ -247,10 +252,12 @@ class _MessageState extends State<Message> with SingleTickerProviderStateMixin {
width: 1, width: 1,
), ),
), ),
child: const Icon( child: Icon(
Icons.person_rounded, Icons.person_rounded,
size: 12, size: 12,
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
), ),
), ),
), ),

View File

@ -126,6 +126,8 @@ class _TypingState extends State<_Typing> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final state = context.watch<DirectState>(); final state = context.watch<DirectState>();
final isDark = Theme.of(context).brightness == Brightness.dark;
return Row( return Row(
children: [ children: [
Expanded( Expanded(
@ -134,10 +136,16 @@ class _TypingState extends State<_Typing> {
child: TextFormField( child: TextFormField(
controller: state.textController, controller: state.textController,
textInputAction: TextInputAction.send, 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( decoration: InputDecoration(
filled: true, 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( border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0), borderRadius: BorderRadius.circular(32.0),
borderSide: BorderSide.none, borderSide: BorderSide.none,
@ -154,7 +162,7 @@ class _TypingState extends State<_Typing> {
hintStyle: Theme.of(context) hintStyle: Theme.of(context)
.textTheme .textTheme
.bodySmall! .bodySmall!
.copyWith(color: const Color.fromARGB(255, 102, 102, 102)), .copyWith(color: Theme.of(context).colorScheme.caption),
contentPadding: contentPadding:
const EdgeInsets.symmetric(horizontal: 20, vertical: 10), const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
prefixIcon: Padding( prefixIcon: Padding(

View File

@ -1,4 +1,4 @@
// ignore_for_file: unused_element_parameter // ignore_for_file: unused_element_parameter, deprecated_member_use
import 'dart:async'; import 'dart:async';
@ -210,8 +210,7 @@ class _BookmarksState extends State<Bookmarks> {
'lib/assets/icons/New_Profile.svg', 'lib/assets/icons/New_Profile.svg',
width: 30, width: 30,
height: 30, height: 30,
color: color: Theme.of(context).colorScheme.caption,
const Color.fromARGB(255, 102, 102, 102),
), ),
), ),
), ),
@ -226,8 +225,7 @@ class _BookmarksState extends State<Bookmarks> {
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
width: 25, width: 25,
height: 25, height: 25,
color: color: Theme.of(context).colorScheme.caption,
const Color.fromARGB(255, 102, 102, 102),
), ),
), ),
), ),
@ -274,7 +272,7 @@ class _BookmarksState extends State<Bookmarks> {
color: Theme.of(context).colorScheme.surface, color: Theme.of(context).colorScheme.surface,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 224, 224, 224), color: Theme.of(context).colorScheme.focused,
width: 1, width: 1,
), ),
boxShadow: [ boxShadow: [
@ -292,7 +290,7 @@ class _BookmarksState extends State<Bookmarks> {
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color.fromARGB(255, 230, 243, 250), color: Theme.of(context).colorScheme.focused,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: Center( child: Center(
@ -302,7 +300,9 @@ class _BookmarksState extends State<Bookmarks> {
.textTheme .textTheme
.titleMedium .titleMedium
?.copyWith( ?.copyWith(
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
fontSize: 15), fontSize: 15),
), ),
@ -317,9 +317,10 @@ class _BookmarksState extends State<Bookmarks> {
"lib/assets/icons/Stratzhic Radar.svg", "lib/assets/icons/Stratzhic Radar.svg",
width: 20, width: 20,
), ),
titleWidget: const DidvanText('رادارهای استراتژیک', titleWidget: DidvanText('رادارهای استراتژیک',
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102))), color:
Theme.of(context).colorScheme.caption)),
), ),
), ),
const _FadeInSlide( const _FadeInSlide(
@ -334,9 +335,10 @@ class _BookmarksState extends State<Bookmarks> {
"lib/assets/icons/Donye_Foolad.svg", "lib/assets/icons/Donye_Foolad.svg",
width: 20, width: 20,
), ),
titleWidget: const DidvanText('دنیای فولاد', titleWidget: DidvanText('دنیای فولاد',
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102))), color:
Theme.of(context).colorScheme.caption)),
), ),
), ),
const _FadeInSlide( const _FadeInSlide(
@ -351,9 +353,10 @@ class _BookmarksState extends State<Bookmarks> {
"lib/assets/icons/Pouyesh_Ofogh_New.svg", "lib/assets/icons/Pouyesh_Ofogh_New.svg",
width: 20, width: 20,
), ),
titleWidget: const DidvanText('پویش افق', titleWidget: DidvanText('پویش افق',
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102))), color:
Theme.of(context).colorScheme.caption)),
), ),
), ),
const _FadeInSlide( const _FadeInSlide(
@ -369,9 +372,10 @@ class _BookmarksState extends State<Bookmarks> {
color: const Color.fromARGB(255, 0, 126, 167), color: const Color.fromARGB(255, 0, 126, 167),
width: 20, width: 20,
), ),
titleWidget: const DidvanText('ویدیو‌کست', titleWidget: DidvanText('ویدیو‌کست',
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102))), color:
Theme.of(context).colorScheme.caption)),
), ),
), ),
const _FadeInSlide( const _FadeInSlide(
@ -387,9 +391,10 @@ class _BookmarksState extends State<Bookmarks> {
color: const Color.fromARGB(255, 0, 126, 167), color: const Color.fromARGB(255, 0, 126, 167),
width: 20, width: 20,
), ),
titleWidget: const DidvanText('پادکست', titleWidget: DidvanText('پادکست',
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102))), color:
Theme.of(context).colorScheme.caption)),
), ),
), ),
const _FadeInSlide( const _FadeInSlide(
@ -404,9 +409,10 @@ class _BookmarksState extends State<Bookmarks> {
"lib/assets/icons/Saha.svg", "lib/assets/icons/Saha.svg",
width: 20, width: 20,
), ),
titleWidget: const DidvanText('سها', titleWidget: DidvanText('سها',
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102))), color:
Theme.of(context).colorScheme.caption)),
), ),
), ),
const _FadeInSlide( const _FadeInSlide(
@ -422,9 +428,10 @@ class _BookmarksState extends State<Bookmarks> {
color: const Color.fromARGB(255, 0, 126, 167), color: const Color.fromARGB(255, 0, 126, 167),
width: 20, width: 20,
), ),
titleWidget: const DidvanText('اینفوگرافی', titleWidget: DidvanText('اینفوگرافی',
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102))), color:
Theme.of(context).colorScheme.caption)),
), ),
), ),
const _FadeInSlide( const _FadeInSlide(
@ -435,10 +442,10 @@ class _BookmarksState extends State<Bookmarks> {
delay: const Duration(milliseconds: 800), delay: const Duration(milliseconds: 800),
child: MenuOption( child: MenuOption(
onTap: () => _onCategorySelected(8), onTap: () => _onCategorySelected(8),
titleWidget: const DidvanText( titleWidget: DidvanText('ماژول بایدها و نبایدها',
'ماژول بایدها و نبایدها',
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102))), color:
Theme.of(context).colorScheme.caption)),
iconWidget: SvgPicture.asset( iconWidget: SvgPicture.asset(
"lib/assets/icons/Swot_New.svg", "lib/assets/icons/Swot_New.svg",
width: 24), width: 24),
@ -453,9 +460,10 @@ class _BookmarksState extends State<Bookmarks> {
delay: const Duration(milliseconds: 900), delay: const Duration(milliseconds: 900),
child: MenuOption( child: MenuOption(
onTap: () => _onCategorySelected(9), onTap: () => _onCategorySelected(9),
titleWidget: const DidvanText('ماهنامه تحلیلی', titleWidget: DidvanText('ماهنامه تحلیلی',
style: TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102))), color:
Theme.of(context).colorScheme.caption)),
iconWidget: SvgPicture.asset( iconWidget: SvgPicture.asset(
"lib/assets/icons/Monthly.svg", "lib/assets/icons/Monthly.svg",
width: 24), width: 24),
@ -633,7 +641,7 @@ class _FadeInSlide extends StatefulWidget {
this.delay = Duration.zero, this.delay = Duration.zero,
// ignore: unused_element_parameter // ignore: unused_element_parameter
this.duration = const Duration(milliseconds: 400), this.duration = const Duration(milliseconds: 400),
this.slideOffset = 50.0, // میزانی که ویجت از پایین به بالا حرکت میکند this.slideOffset = 50.0,
}) : super(key: key); }) : super(key: key);
@override @override

View File

@ -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/main.dart';
import 'package:didvan/models/home_page_content/home_page_list.dart'; import 'package:didvan/models/home_page_content/home_page_list.dart';
import 'package:didvan/models/home_page_content/swot.dart'; import 'package:didvan/models/home_page_content/swot.dart';
@ -281,7 +283,9 @@ class SwotSection extends StatelessWidget {
DidvanText( DidvanText(
"ماژول بایدها و نبایدها", "ماژول بایدها و نبایدها",
style: Theme.of(context).textTheme.titleSmall, 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, headerText,
style: style:
const TextStyle(fontSize: 17, fontWeight: FontWeight.w500), 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('======================='); print('=======================');
} }
// Open PDF viewer directly
Navigator.of(context).pushNamed( Navigator.of(context).pushNamed(
Routes.pdfViewer, Routes.pdfViewer,
arguments: { arguments: {
@ -579,7 +584,9 @@ class MainPageSection extends StatelessWidget {
margin: margin:
const EdgeInsets.symmetric(vertical: 3, horizontal: 5), const EdgeInsets.symmetric(vertical: 3, horizontal: 5),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: DesignConfig.isDark
? const Color.fromARGB(255, 36, 36, 36)
: Colors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 184, 184, 184), color: const Color.fromARGB(255, 184, 184, 184),
@ -609,8 +616,10 @@ class MainPageSection extends StatelessWidget {
children: [ children: [
Text( Text(
item.title, item.title,
style: const TextStyle( style: TextStyle(
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 15), fontSize: 15),
maxLines: 3, maxLines: 3,
@ -683,7 +692,9 @@ class MainPageSection extends StatelessWidget {
child: Container( child: Container(
margin: const EdgeInsets.symmetric(horizontal: 4), margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: DesignConfig.isDark
? const Color.fromARGB(255, 36, 36, 36)
: Colors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 184, 184, 184), color: const Color.fromARGB(255, 184, 184, 184),
@ -711,8 +722,10 @@ class MainPageSection extends StatelessWidget {
Text( Text(
item.title, item.title,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: const TextStyle( style: TextStyle(
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -731,8 +744,9 @@ class MainPageSection extends StatelessWidget {
Text( Text(
DateTime.parse(item.subtitles.first) DateTime.parse(item.subtitles.first)
.toPersianDateStr(), .toPersianDateStr(),
style: const TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102), color:
Theme.of(context).colorScheme.caption,
fontSize: 12), fontSize: 12),
), ),
], ],
@ -760,7 +774,9 @@ class MainPageSection extends StatelessWidget {
child: Container( child: Container(
margin: const EdgeInsets.symmetric(horizontal: 4), margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: DesignConfig.isDark
? const Color.fromARGB(255, 36, 36, 36)
: Colors.white,
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 184, 184, 184))), color: const Color.fromARGB(255, 184, 184, 184))),
@ -783,8 +799,10 @@ class MainPageSection extends StatelessWidget {
child: Text( child: Text(
item.title, item.title,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: const TextStyle( style: TextStyle(
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -806,8 +824,9 @@ class MainPageSection extends StatelessWidget {
Text( Text(
DateTime.parse(item.subtitles.first) DateTime.parse(item.subtitles.first)
.toPersianDateStr(), .toPersianDateStr(),
style: const TextStyle( style: TextStyle(
color: Color.fromARGB(255, 102, 102, 102), color:
Theme.of(context).colorScheme.caption,
fontSize: 12), fontSize: 12),
), ),
], ],
@ -854,7 +873,9 @@ class MainPageSection extends StatelessWidget {
child: Container( child: Container(
margin: const EdgeInsets.symmetric(horizontal: 4), margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: DesignConfig.isDark
? const Color.fromARGB(255, 36, 36, 36)
: Colors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 184, 184, 184), color: const Color.fromARGB(255, 184, 184, 184),
@ -874,8 +895,10 @@ class MainPageSection extends StatelessWidget {
Text( Text(
item.title, item.title,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: const TextStyle( style: TextStyle(
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
maxLines: 3, maxLines: 3,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -892,9 +915,10 @@ class MainPageSection extends StatelessWidget {
), ),
Text( Text(
item.subtitles.last, item.subtitles.last,
style: const TextStyle( style: TextStyle(
color: color: Theme.of(context)
Color.fromARGB(255, 102, 102, 102)), .colorScheme
.caption),
), ),
], ],
) )
@ -943,7 +967,9 @@ class MainPageSection extends StatelessWidget {
child: Container( child: Container(
margin: const EdgeInsets.symmetric(horizontal: 4), margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: DesignConfig.isDark
? const Color.fromARGB(255, 36, 36, 36)
: Colors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 184, 184, 184), color: const Color.fromARGB(255, 184, 184, 184),
@ -971,8 +997,10 @@ class MainPageSection extends StatelessWidget {
Text( Text(
item.title, item.title,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: const TextStyle( style: TextStyle(
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -1023,7 +1051,9 @@ class MainPageSection extends StatelessWidget {
child: Container( child: Container(
margin: const EdgeInsets.symmetric(horizontal: 4), margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: DesignConfig.isDark
? const Color.fromARGB(255, 36, 36, 36)
: Colors.white,
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 184, 184, 184))), color: const Color.fromARGB(255, 184, 184, 184))),
@ -1041,8 +1071,10 @@ class MainPageSection extends StatelessWidget {
child: Text( child: Text(
item.title, item.title,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: const TextStyle( style: TextStyle(
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -1105,7 +1137,9 @@ class MainPageSection extends StatelessWidget {
child: Container( child: Container(
margin: const EdgeInsets.symmetric(horizontal: 4), margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: DesignConfig.isDark
? const Color.fromARGB(255, 36, 36, 36)
: Colors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 184, 184, 184), color: const Color.fromARGB(255, 184, 184, 184),
@ -1138,8 +1172,10 @@ class MainPageSection extends StatelessWidget {
Text( Text(
item.title, item.title,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: const TextStyle( style: TextStyle(
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
maxLines: 3, maxLines: 3,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -1171,10 +1207,14 @@ class MainPageSection extends StatelessWidget {
height: 10, height: 10,
), ),
Container( Container(
decoration: const BoxDecoration( decoration: BoxDecoration(
color: Color.fromARGB(255, 235, 235, 235), color: DesignConfig.isDark
borderRadius: ? const Color.fromARGB(
BorderRadius.all(Radius.circular(8)), 255, 188, 188, 188)
: const Color.fromARGB(
255, 235, 235, 235),
borderRadius: const BorderRadius.all(
Radius.circular(8)),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
@ -1224,7 +1264,7 @@ class MainPageSection extends StatelessWidget {
child: Container( child: Container(
margin: const EdgeInsets.symmetric(horizontal: 4), margin: const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: DesignConfig.isDark ? Colors.black : Colors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 184, 184, 184), color: const Color.fromARGB(255, 184, 184, 184),
@ -1252,8 +1292,10 @@ class MainPageSection extends StatelessWidget {
Text( Text(
item.title, item.title,
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: const TextStyle( style: TextStyle(
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,

View File

@ -75,9 +75,11 @@ class _HomeState extends State<Home>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
key: homeScaffKey, key: homeScaffKey,
// ignore: deprecated_member_use
backgroundColor: Theme.of(context).colorScheme.background, backgroundColor: Theme.of(context).colorScheme.background,
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
drawer: null, drawer: null,
// ignore: deprecated_member_use
body: WillPopScope( body: WillPopScope(
onWillPop: () async { onWillPop: () async {
if (context.read<HomeState>().tabController.index == 0) { if (context.read<HomeState>().tabController.index == 0) {

View File

@ -1,11 +1,16 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.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/home_page_list.dart';
import 'package:didvan/models/home_page_content/swot.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/explore/explore.dart';
import 'package:didvan/views/home/main/main_page_state.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/main_content.dart';
import 'package:didvan/views/home/main/widgets/story_section.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/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/home/new_statistic/new_statistics_state.dart';
import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/state_handlers/state_handler.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:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_animate/flutter_animate.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:flutter/foundation.dart' show kIsWeb, defaultTargetPlatform; import 'package:flutter/foundation.dart' show kIsWeb, defaultTargetPlatform;
@ -74,14 +80,20 @@ class _MainPageState extends State<MainPage> {
const TextDivider(text: 'دیده‌بان') const TextDivider(text: 'دیده‌بان')
.animate() .animate()
.fadeIn(delay: 400.ms, duration: 500.ms), .fadeIn(delay: 400.ms, duration: 500.ms),
// const _DidvanSignalsTitle() const _DidvanSignalsTitle()
// .animate() .animate()
// .fadeIn(delay: 500.ms, duration: 500.ms), .fadeIn(delay: 500.ms, duration: 500.ms),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: StorySection(stories: state.stories), child: StorySection(stories: state.stories),
).animate().fadeIn(delay: 600.ms, duration: 500.ms), ).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 SizedBox(height: 12),
const TextDivider(text: 'پیشخوان استراتژیک') const TextDivider(text: 'پیشخوان استراتژیک')
.animate() .animate()
@ -120,38 +132,38 @@ class _MainPageState extends State<MainPage> {
} }
} }
// class _DidvanSignalsTitle extends StatelessWidget { class _DidvanSignalsTitle extends StatelessWidget {
// const _DidvanSignalsTitle(); const _DidvanSignalsTitle();
// @override @override
// Widget build(BuildContext context) { Widget build(BuildContext context) {
// return Padding( return Padding(
// padding: const EdgeInsets.only( padding: const EdgeInsets.only(
// left: 16, left: 16,
// right: 16, right: 16,
// bottom: 16, bottom: 16,
// top: 0, top: 0,
// ), ),
// child: Row( child: Row(
// children: [ children: [
// SvgPicture.asset( SvgPicture.asset(
// 'lib/assets/icons/voice-square.svg', 'lib/assets/icons/voice-square.svg',
// color: Theme.of(context).colorScheme.title, color: Theme.of(context).colorScheme.title,
// width: 30, width: 30,
// height: 30, height: 30,
// ), ),
// const SizedBox(width: 5), const SizedBox(width: 5),
// DidvanText( DidvanText(
// "سیگنال‌های دیدوان", "سیگنال‌های دیدوان",
// style: Theme.of(context).textTheme.titleMedium, style: Theme.of(context).textTheme.titleMedium,
// color: const Color.fromARGB(255, 0, 89, 119), color: const Color.fromARGB(255, 0, 89, 119),
// fontSize: 13, fontSize: 13,
// ), ),
// ], ],
// ), ),
// ); );
// } }
// } }
class _ExploreLatestTitle extends StatelessWidget { class _ExploreLatestTitle extends StatelessWidget {
const _ExploreLatestTitle(); const _ExploreLatestTitle();
@ -180,7 +192,7 @@ class _ExploreLatestTitle extends StatelessWidget {
DidvanText( DidvanText(
"تازه‌ترین‌های کاوش", "تازه‌ترین‌های کاوش",
style: Theme.of(context).textTheme.titleMedium, 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, fontSize: 13,
), ),
], ],
@ -215,6 +227,8 @@ class _ExploreLatestSlider extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final List<Widget> items = []; final List<Widget> items = [];
final List<({String type, MainPageContentType? content, SwotItem? swotItem})> itemsData = [];
for (var list in lists) { for (var list in lists) {
if (list.type == 'video' || if (list.type == 'video' ||
list.type == 'podcast' || 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) { if (items.isEmpty) {
@ -259,6 +275,23 @@ class _ExploreLatestSlider extends StatelessWidget {
onItemChanged: (index) { onItemChanged: (index) {
// Optional: Handle item change if needed // 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<MainPageState>().navigationHandler(
data.type,
data.content!.id,
data.content!.link,
description: data.content!.title,
);
}
},
); );
} }
} }

View File

@ -1,4 +1,5 @@
import 'package:didvan/main.dart'; import 'package:didvan/main.dart';
import 'package:didvan/models/didvan_plus_model.dart';
import 'package:didvan/models/enums.dart'; import 'package:didvan/models/enums.dart';
import 'package:didvan/models/home_page_content/content.dart'; import 'package:didvan/models/home_page_content/content.dart';
import 'package:didvan/models/home_page_content/home_page_content.dart'; import 'package:didvan/models/home_page_content/home_page_content.dart';
@ -22,6 +23,7 @@ class MainPageState extends CoreProvier {
int unread = 0; int unread = 0;
List<UserStories> stories = []; List<UserStories> stories = [];
List<SwotItem> swotItems = []; List<SwotItem> swotItems = [];
DidvanPlusModel? didvanPlus;
Future<void> _getMainPageContent() async { Future<void> _getMainPageContent() async {
final service = RequestService(RequestHelper.mainPageContent); final service = RequestService(RequestHelper.mainPageContent);
@ -49,6 +51,29 @@ class MainPageState extends CoreProvier {
} }
} }
Future<void> _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<void> _fetchStories() async { Future<void> _fetchStories() async {
try { try {
stories = await StoryService.getStories(); stories = await StoryService.getStories();
@ -60,7 +85,7 @@ class MainPageState extends CoreProvier {
} }
void init() { void init() {
print("DEBUG: MainPageState init called"); debugPrint("🏠 MainPageState init called");
Future.delayed(Duration.zero, () async { Future.delayed(Duration.zero, () async {
appState = AppState.busy; appState = AppState.busy;
try { try {
@ -68,9 +93,12 @@ class MainPageState extends CoreProvier {
_getMainPageContent(), _getMainPageContent(),
_fetchStories(), _fetchStories(),
_getSwotItems(), _getSwotItems(),
_getDidvanPlus(),
]); ]);
debugPrint("✅ All main page data loaded");
appState = AppState.idle; appState = AppState.idle;
} catch (e) { } catch (e) {
debugPrint("❌ Main page init failed: $e");
appState = AppState.failed; appState = AppState.failed;
} }
}); });
@ -139,6 +167,17 @@ class MainPageState extends CoreProvier {
}; };
break; break;
} }
case 'monthly':
{
Navigator.of(navigatorKey.currentContext!).pushNamed(
Routes.pdfViewer,
arguments: {
'pdfUrl': link,
'title': description ?? 'ماهنامه تحلیلی دیدوان',
},
);
return;
}
} }
if (link == '') { if (link == '') {
return; return;

View File

@ -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<DidvanPlusSection> createState() => _DidvanPlusSectionState();
}
class _DidvanPlusSectionState extends State<DidvanPlusSection> {
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();
},
),
),
),
),
),
],
),
);
}
}

View File

@ -31,34 +31,35 @@ class SimpleExploreCard extends StatelessWidget {
String _getCategoryIcon(String? contentType, bool isSwot) { String _getCategoryIcon(String? contentType, bool isSwot) {
if (isSwot) { if (isSwot) {
// For SWOT items (فرصت تهدید) return 'lib/assets/icons/Swot_New.svg';
return 'lib/assets/icons/swot.svg';
} }
switch (contentType?.toLowerCase()) { switch (contentType?.toLowerCase()) {
case 'startup': case 'startup':
return 'lib/assets/icons/bi_rocket-fill.svg'; return 'lib/assets/icons/Startup.svg';
case 'radar': 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 'trend': // رادار روند
case 'trends': case 'trends':
return 'lib/assets/icons/solar_graph-new-bold.svg'; return 'lib/assets/icons/Ravand.svg';
case 'technology': // رادار تکنولوزی/فناوری case 'technology': // رادار تکنولوزی/فناوری
case 'tech': case 'tech':
return 'lib/assets/icons/cpu-charge.svg'; return 'lib/assets/icons/Technology.svg';
case 'risk': // رادار ریسک case 'risk': // رادار ریسک
return 'lib/assets/icons/risk radar.svg'; return 'lib/assets/icons/risk-radar.svg';
case 'survey': case 'survey':
case 'delphi': // دولفی case 'delphi':
return 'lib/assets/icons/icon-park-solid_thinking-problem.svg'; return 'lib/assets/icons/Saha.svg';
case 'monthly':
return 'lib/assets/icons/Monthly.svg';
case 'news': case 'news':
return 'lib/assets/icons/news-icon.svg'; // You can replace with actual icon return 'lib/assets/icons/news-icon.svg';
case 'infography': case 'infography':
return 'lib/assets/icons/infography-icon.svg'; // You can replace with actual icon return 'lib/assets/icons/infography-icon.svg';
case 'video': case 'video':
return 'lib/assets/icons/video-icon.svg'; // You can replace with actual icon return 'lib/assets/icons/video-icon.svg';
case 'podcast': case 'podcast':
return 'lib/assets/icons/podcast-icon.svg'; // You can replace with actual icon return 'lib/assets/icons/podcast-icon.svg';
default: default:
return 'lib/assets/icons/bi_rocket-fill.svg'; // Default fallback return 'lib/assets/icons/bi_rocket-fill.svg'; // Default fallback
} }
@ -121,17 +122,19 @@ class SimpleExploreCard extends StatelessWidget {
.onSurface .onSurface
.withValues(alpha: 0.1), .withValues(alpha: 0.1),
), ),
child: const Icon(Icons.image_not_supported_outlined), child:
const Icon(Icons.image_not_supported_outlined),
); );
}, },
fit: BoxFit.cover, fit: BoxFit.cover,
imageRenderMethodForWeb: ImageRenderMethodForWeb.HttpGet, imageRenderMethodForWeb:
ImageRenderMethodForWeb.HttpGet,
httpHeaders: { httpHeaders: {
'Authorization': 'Bearer ${RequestService.token}' 'Authorization': 'Bearer ${RequestService.token}'
}, },
width: double.infinity, width: double.infinity,
imageUrl: imageUrl, imageUrl: imageUrl,
placeholder: (context, _) => ShimmerPlaceholder( placeholder: (context, _) => const ShimmerPlaceholder(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
), ),
@ -153,7 +156,8 @@ class SimpleExploreCard extends StatelessWidget {
), ),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), padding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
child: Row( child: Row(
children: [ children: [
SvgPicture.asset( SvgPicture.asset(

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/models/story_model.dart'; import 'package:didvan/models/story_model.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -104,6 +105,7 @@ class _StoryCircle extends StatelessWidget {
child: Image.asset( child: Image.asset(
userStories.user userStories.user
.profileImageUrl, .profileImageUrl,
color: DesignConfig.isDark ? Colors.grey : null,
fit: BoxFit.cover, fit: BoxFit.cover,
width: 50.0, width: 50.0,
height: 50.0, height: 50.0,

View File

@ -1,5 +1,6 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.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/constants/app_icons.dart';
import 'package:didvan/models/home_page_content/swot.dart'; import 'package:didvan/models/home_page_content/swot.dart';
import 'package:didvan/services/app_initalizer.dart'; import 'package:didvan/services/app_initalizer.dart';
@ -156,17 +157,17 @@ class _SwotItemCardState extends State<SwotItemCard> {
// دستهبندی // دستهبندی
Row( Row(
children: [ children: [
const Icon( Icon(
DidvanIcons.puzzle_light, DidvanIcons.puzzle_light,
size: 23, size: 23,
color: Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
const SizedBox(width: 6), const SizedBox(width: 6),
Expanded( Expanded(
child: Text( child: Text(
_getCategoryName(widget.item.category), _getCategoryName(widget.item.category),
style: theme.textTheme.bodySmall?.copyWith( style: theme.textTheme.bodySmall?.copyWith(
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,

View File

@ -1,4 +1,7 @@
// ignore_for_file: deprecated_member_use
import 'dart:async'; import 'dart:async';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/models/requests/studio.dart'; import 'package:didvan/models/requests/studio.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/media/media.dart'; import 'package:didvan/services/media/media.dart';
@ -6,7 +9,6 @@ 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/podcasts/podcasts_state.dart';
import 'package:didvan/views/widgets/item_title.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/empty_result.dart';
import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -56,16 +58,50 @@ class _PodcastTabPageState extends State<PodcastTabPage> {
void _showSortDialog() { void _showSortDialog() {
final state = context.read<PodcastsState>(); final state = context.read<PodcastsState>();
showModalBottomSheet( showModalBottomSheet(
backgroundColor: Colors.white, backgroundColor: DesignConfig.isDark
? const Color.fromARGB(255, 30, 30, 30)
: Colors.white,
context: context, context: context,
builder: (context) { builder: (context) {
return Container( return Container(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [ 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( ListTile(
title: const Text('تازه‌ترین‌ها'), title: const Text('جدیدترین‌ها'),
leading: Radio<int>(
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: () { onTap: () {
state.selectedSortTypeIndex = 0; state.selectedSortTypeIndex = 0;
state.getStudios(page: 1); state.getStudios(page: 1);
@ -74,6 +110,18 @@ class _PodcastTabPageState extends State<PodcastTabPage> {
), ),
ListTile( ListTile(
title: const Text('قدیمی‌ترین‌ها'), title: const Text('قدیمی‌ترین‌ها'),
leading: Radio<int>(
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: () { onTap: () {
state.selectedSortTypeIndex = 1; state.selectedSortTypeIndex = 1;
state.getStudios(page: 1); state.getStudios(page: 1);
@ -82,6 +130,18 @@ class _PodcastTabPageState extends State<PodcastTabPage> {
), ),
ListTile( ListTile(
title: const Text('پربازدیدترین‌ها'), title: const Text('پربازدیدترین‌ها'),
leading: Radio<int>(
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: () { onTap: () {
state.selectedSortTypeIndex = 2; state.selectedSortTypeIndex = 2;
state.getStudios(page: 1); state.getStudios(page: 1);
@ -90,6 +150,18 @@ class _PodcastTabPageState extends State<PodcastTabPage> {
), ),
ListTile( ListTile(
title: const Text('پربحث‌ترین‌ها'), title: const Text('پربحث‌ترین‌ها'),
leading: Radio<int>(
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: () { onTap: () {
state.selectedSortTypeIndex = 3; state.selectedSortTypeIndex = 3;
state.getStudios(page: 1); state.getStudios(page: 1);
@ -129,11 +201,11 @@ class _PodcastTabPageState extends State<PodcastTabPage> {
); );
} }
@override @override
void dispose() { void dispose() {
_rotationTimer?.cancel(); _rotationTimer?.cancel();
if (MediaService.isPlayingFromFeaturedCard && MediaService.audioPlayer.playing) { if (MediaService.isPlayingFromFeaturedCard &&
MediaService.audioPlayer.playing) {
MediaService.audioPlayer.pause(); MediaService.audioPlayer.pause();
} }
super.dispose(); super.dispose();
@ -175,7 +247,6 @@ class _PodcastTabPageState extends State<PodcastTabPage> {
onPlayStateChanged: _onPlayStateChanged, onPlayStateChanged: _onPlayStateChanged,
), ),
), ),
if (state.studios.length > 1) if (state.studios.length > 1)
Padding( Padding(
padding: padding:
@ -183,10 +254,12 @@ class _PodcastTabPageState extends State<PodcastTabPage> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const ItemTitle( ItemTitle(
title: 'همه پادکست‌ها', title: 'همه پادکست‌ها',
color: Color.fromARGB(255, 0, 53, 70), color: DesignConfig.isDark
style: TextStyle( ? const Color.fromARGB(255, 0, 90, 119)
: const Color.fromARGB(255, 0, 53, 70),
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 18), fontWeight: FontWeight.bold, fontSize: 18),
), ),
Row( Row(
@ -195,19 +268,23 @@ class _PodcastTabPageState extends State<PodcastTabPage> {
onTap: _showSortDialog, onTap: _showSortDialog,
child: Text( child: Text(
state.orderString, state.orderString,
style: const TextStyle( 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)),
)), )),
IconButton( IconButton(
onPressed: _showSortDialog, onPressed: _showSortDialog,
icon: SvgPicture.asset( 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) if (state.studios.length > 1)
ListView.builder( ListView.builder(
itemCount: state.studios.length, itemCount: state.studios.length,

View File

@ -1,6 +1,7 @@
// ignore_for_file: use_build_context_synchronously, deprecated_member_use // ignore_for_file: use_build_context_synchronously, deprecated_member_use
import 'package:chewie/chewie.dart'; import 'package:chewie/chewie.dart';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
@ -170,7 +171,7 @@ class _VideoDetailsPageState extends State<VideoDetailsPage>
appBar: PreferredSize( appBar: PreferredSize(
preferredSize: const Size.fromHeight(90.0), preferredSize: const Size.fromHeight(90.0),
child: AppBar( child: AppBar(
backgroundColor: Colors.white, backgroundColor: Theme.of(context).colorScheme.surface,
elevation: 0, elevation: 0,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
flexibleSpace: SafeArea( flexibleSpace: SafeArea(
@ -189,8 +190,7 @@ class _VideoDetailsPageState extends State<VideoDetailsPage>
IconButton( IconButton(
icon: SvgPicture.asset( icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
color: color: Theme.of(context).colorScheme.caption,
const Color.fromARGB(255, 102, 102, 102),
height: 24, height: 24,
), ),
onPressed: () { onPressed: () {
@ -283,17 +283,19 @@ class _VideoDetailsPageState extends State<VideoDetailsPage>
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
state.studio.title, state.studio.title,
style: const TextStyle( style: TextStyle(
fontSize: 17, fontSize: 17,
fontWeight: FontWeight.bold, 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( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.vertical( borderRadius: BorderRadius.vertical(
bottom: Radius.circular( bottom:
_isDescriptionExpanded ? 0 : 16.0), Radius.circular(_isDescriptionExpanded ? 0 : 16.0),
), ),
boxShadow: _isDescriptionExpanded boxShadow: _isDescriptionExpanded
? null ? null
@ -396,8 +398,8 @@ class _VideoDetailsPageState extends State<VideoDetailsPage>
children: [ children: [
Container( Container(
padding: const EdgeInsets.all(4.0), padding: const EdgeInsets.all(4.0),
decoration: const BoxDecoration( decoration: BoxDecoration(
color: Color.fromARGB(255, 230, 243, 250), color: Theme.of(context).colorScheme.focused,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: SvgPicture.asset( child: SvgPicture.asset(
@ -489,14 +491,18 @@ class _VideoDetailsPageState extends State<VideoDetailsPage>
children: [ children: [
CircleAvatar( CircleAvatar(
radius: 20, radius: 20,
backgroundColor: Colors.white, backgroundColor: DesignConfig.isDark
? Colors.transparent
: Colors.white,
backgroundImage: backgroundImage:
hasProfileImage ? NetworkImage(user.photo!) : null, hasProfileImage ? NetworkImage(user.photo!) : null,
child: !hasProfileImage child: !hasProfileImage
? const Icon( ? Icon(
DidvanIcons.avatar_light, DidvanIcons.avatar_light,
size: 50, size: 50,
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
) )
: null, : null,
), ),
@ -509,12 +515,14 @@ class _VideoDetailsPageState extends State<VideoDetailsPage>
}, },
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
const SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: DidvanText( child: DidvanText(
'نظرات کاربران:', 'نظرات کاربران:',
style: TextStyle( 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, fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -547,13 +555,15 @@ class _VideoDetailsPageState extends State<VideoDetailsPage>
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Padding( Padding(
padding: EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"مطالب مرتبط:", "مطالب مرتبط:",
style: TextStyle( style: TextStyle(
fontSize: 18, 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), fontWeight: FontWeight.bold),
), ),
), ),

View File

@ -1,4 +1,7 @@
// ignore_for_file: deprecated_member_use
import 'dart:async'; import 'dart:async';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/routes/routes.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/featured_video_card.dart';
import 'package:didvan/views/home/media/widgets/videocast_grid_card.dart'; import 'package:didvan/views/home/media/widgets/videocast_grid_card.dart';
@ -47,16 +50,50 @@ class _VideoCastTabPageState extends State<VideoCastTabPage> {
void _showSortDialog() { void _showSortDialog() {
final state = context.read<PodcastsState>(); final state = context.read<PodcastsState>();
showModalBottomSheet( showModalBottomSheet(
backgroundColor: Colors.white, backgroundColor: DesignConfig.isDark
? const Color.fromARGB(255, 30, 30, 30)
: Colors.white,
context: context, context: context,
builder: (context) { builder: (context) {
return Container( return Container(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [ 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( ListTile(
title: const Text('تازه‌ترین‌ها'), title: const Text('جدیدترین‌ها'),
leading: Radio<int>(
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: () { onTap: () {
state.selectedSortTypeIndex = 0; state.selectedSortTypeIndex = 0;
state.getStudios(page: 1); state.getStudios(page: 1);
@ -65,6 +102,18 @@ class _VideoCastTabPageState extends State<VideoCastTabPage> {
), ),
ListTile( ListTile(
title: const Text('قدیمی‌ترین‌ها'), title: const Text('قدیمی‌ترین‌ها'),
leading: Radio<int>(
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: () { onTap: () {
state.selectedSortTypeIndex = 1; state.selectedSortTypeIndex = 1;
state.getStudios(page: 1); state.getStudios(page: 1);
@ -73,6 +122,18 @@ class _VideoCastTabPageState extends State<VideoCastTabPage> {
), ),
ListTile( ListTile(
title: const Text('پربازدیدترین‌ها'), title: const Text('پربازدیدترین‌ها'),
leading: Radio<int>(
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: () { onTap: () {
state.selectedSortTypeIndex = 2; state.selectedSortTypeIndex = 2;
state.getStudios(page: 1); state.getStudios(page: 1);
@ -81,6 +142,18 @@ class _VideoCastTabPageState extends State<VideoCastTabPage> {
), ),
ListTile( ListTile(
title: const Text('پربحث‌ترین‌ها'), title: const Text('پربحث‌ترین‌ها'),
leading: Radio<int>(
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: () { onTap: () {
state.selectedSortTypeIndex = 3; state.selectedSortTypeIndex = 3;
state.getStudios(page: 1); state.getStudios(page: 1);
@ -145,7 +218,6 @@ class _VideoCastTabPageState extends State<VideoCastTabPage> {
}, },
), ),
), ),
if (state.studios.length > 1) if (state.studios.length > 1)
Padding( Padding(
padding: padding:
@ -153,10 +225,13 @@ class _VideoCastTabPageState extends State<VideoCastTabPage> {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const ItemTitle( ItemTitle(
title: 'همه ویدیوکست‌ها', title: 'همه ویدیوکست‌ها',
color: Color.fromARGB(255, 0, 53, 70), color: DesignConfig.isDark
style: TextStyle(fontWeight: FontWeight.bold,fontSize: 18), ? const Color.fromARGB(255, 0, 90, 119)
: const Color.fromARGB(255, 0, 53, 70),
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 18),
), ),
Row( Row(
children: [ children: [
@ -164,19 +239,24 @@ class _VideoCastTabPageState extends State<VideoCastTabPage> {
onTap: _showSortDialog, onTap: _showSortDialog,
child: Text( child: Text(
state.orderString, state.orderString,
style: const TextStyle( 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)),
)), )),
IconButton( IconButton(
onPressed: _showSortDialog, onPressed: _showSortDialog,
icon: SvgPicture.asset( 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) if (state.studios.length > 1)
Padding( Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),

View File

@ -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/infography/infography_screen_state.dart';
import 'package:didvan/views/home/main/widgets/infography_item.dart'; import 'package:didvan/views/home/main/widgets/infography_item.dart';
import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
@ -61,9 +63,7 @@ class _BannerGridViewState extends State<BannerGridView> {
return Column( return Column(
children: [ children: [
_buildCategoryFilters(state), _buildCategoryFilters(state),
const SizedBox(height: 16), const SizedBox(height: 16),
ListView.separated( ListView.separated(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
@ -90,7 +90,6 @@ class _BannerGridViewState extends State<BannerGridView> {
); );
}, },
), ),
if (hasMoreItems) if (hasMoreItems)
Padding( Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0), padding: const EdgeInsets.symmetric(vertical: 16.0),
@ -162,12 +161,16 @@ class _BannerGridViewState extends State<BannerGridView> {
}, },
selectedColor: const Color.fromARGB(255, 200, 224, 244), selectedColor: const Color.fromARGB(255, 200, 224, 244),
backgroundColor: state.selectedCats.isEmpty backgroundColor: state.selectedCats.isEmpty
? const Color.fromARGB(255, 200, 224, 244) ? 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), : const Color.fromARGB(255, 224, 224, 224),
labelStyle: TextStyle( labelStyle: TextStyle(
color: state.selectedCats.isEmpty color: state.selectedCats.isEmpty
? const Color.fromARGB(255, 0, 115, 153) ? const Color.fromARGB(255, 0, 115, 153)
: const Color.fromARGB(255, 102, 102, 102), : Theme.of(context).colorScheme.caption,
fontWeight: state.selectedCats.isEmpty fontWeight: state.selectedCats.isEmpty
? FontWeight.bold ? FontWeight.bold
: FontWeight.normal, : FontWeight.normal,
@ -178,7 +181,6 @@ class _BannerGridViewState extends State<BannerGridView> {
showCheckmark: false, showCheckmark: false,
), ),
), ),
...state.categories.map((category) { ...state.categories.map((category) {
final isSelected = state.selectedCats.contains(category); final isSelected = state.selectedCats.contains(category);
@ -203,12 +205,16 @@ class _BannerGridViewState extends State<BannerGridView> {
}, },
selectedColor: const Color.fromARGB(255, 200, 224, 244), selectedColor: const Color.fromARGB(255, 200, 224, 244),
backgroundColor: isSelected backgroundColor: isSelected
? const Color.fromARGB(255, 200, 224, 244) ? 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), : const Color.fromARGB(255, 224, 224, 224),
labelStyle: TextStyle( labelStyle: TextStyle(
color: isSelected color: isSelected
? const Color.fromARGB(255, 0, 115, 153) ? 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, fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
), ),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(

View File

@ -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/overview_data.dart';
import 'package:didvan/models/studio_details_data.dart'; import 'package:didvan/models/studio_details_data.dart';
import 'package:didvan/services/media/media.dart'; import 'package:didvan/services/media/media.dart';
@ -31,6 +35,7 @@ class _FeaturedPodcastCardState extends State<FeaturedPodcastCard>
Duration _currentPosition = Duration.zero; Duration _currentPosition = Duration.zero;
Duration _totalDuration = Duration.zero; Duration _totalDuration = Duration.zero;
// ignore: prefer_final_fields
var _subscriptions = <dynamic>[]; var _subscriptions = <dynamic>[];
@override @override
@ -217,7 +222,9 @@ class _FeaturedPodcastCardState extends State<FeaturedPodcastCard>
return Container( return Container(
margin: const EdgeInsets.all(16), margin: const EdgeInsets.all(16),
decoration: BoxDecoration( 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), borderRadius: BorderRadius.circular(16),
), ),
child: Column( child: Column(
@ -245,10 +252,10 @@ class _FeaturedPodcastCardState extends State<FeaturedPodcastCard>
children: [ children: [
DidvanText( DidvanText(
widget.podcast.title, widget.podcast.title,
style: const TextStyle( style: TextStyle(
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.black, color: DesignConfig.isDark ? Colors.white : Colors.black,
), ),
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -260,9 +267,9 @@ class _FeaturedPodcastCardState extends State<FeaturedPodcastCard>
width: 45, width: 45,
child: Text( child: Text(
_formatDuration(_totalDuration), _formatDuration(_totalDuration),
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: Color.fromARGB(255, 102, 102, 102)), color: Theme.of(context).colorScheme.caption),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
), ),
@ -289,9 +296,9 @@ class _FeaturedPodcastCardState extends State<FeaturedPodcastCard>
width: 45, width: 45,
child: Text( child: Text(
_formatDuration(_currentPosition), _formatDuration(_currentPosition),
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: Color.fromARGB(255, 102, 102, 102)), color: Theme.of(context).colorScheme.caption),
textAlign: TextAlign.right, textAlign: TextAlign.right,
), ),
), ),
@ -307,7 +314,9 @@ class _FeaturedPodcastCardState extends State<FeaturedPodcastCard>
'lib/assets/icons/forward-10-seconds.svg', 'lib/assets/icons/forward-10-seconds.svg',
width: 30, width: 30,
height: 30, height: 30,
), color: DesignConfig.isDark
? const Color.fromARGB(255, 117, 117, 117)
: null),
), ),
const SizedBox(width: 15), const SizedBox(width: 15),
GestureDetector( GestureDetector(
@ -351,7 +360,9 @@ class _FeaturedPodcastCardState extends State<FeaturedPodcastCard>
'lib/assets/icons/backward-5-seconds.svg', 'lib/assets/icons/backward-5-seconds.svg',
width: 30, width: 30,
height: 30, height: 30,
), color: DesignConfig.isDark
? const Color.fromARGB(255, 117, 117, 117)
: null),
), ),
], ],
), ),

View File

@ -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/overview_data.dart';
import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:didvan/views/widgets/skeleton_image.dart';
@ -73,7 +77,9 @@ class PodcastListCard extends StatelessWidget {
child: Padding( child: Padding(
padding: const EdgeInsets.fromLTRB(12, 3, 12, 10), padding: const EdgeInsets.fromLTRB(12, 3, 12, 10),
child: Container( child: Container(
color: Colors.white, color: DesignConfig.isDark
? Colors.transparent
: Colors.white,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@ -82,7 +88,9 @@ class PodcastListCard extends StatelessWidget {
podcast.title, podcast.title,
style: textTheme.bodyMedium?.copyWith( style: textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Colors.black87, color: DesignConfig.isDark
? const Color.fromARGB(255, 206, 206, 206)
: Colors.black87,
), ),
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -91,13 +99,15 @@ class PodcastListCard extends StatelessWidget {
Row( Row(
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
'lib/assets/icons/calendar.svg'), 'lib/assets/icons/calendar.svg',
color: Theme.of(context).colorScheme.caption,
),
const SizedBox(width: 4), const SizedBox(width: 4),
DidvanText( DidvanText(
_formatDate(podcast.createdAt), _formatDate(podcast.createdAt),
style: textTheme.bodySmall?.copyWith( style: textTheme.bodySmall?.copyWith(
color: const Color.fromARGB( color:
255, 102, 102, 102), Theme.of(context).colorScheme.caption,
), ),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -109,16 +119,15 @@ class PodcastListCard extends StatelessWidget {
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
'lib/assets/icons/clock.svg', 'lib/assets/icons/clock.svg',
color: color: Theme.of(context).colorScheme.caption,
const Color.fromARGB(255, 102, 102, 102),
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
DidvanText( DidvanText(
_formatDuration(podcast.duration) _formatDuration(podcast.duration)
.toPersianDigit(), .toPersianDigit(),
style: textTheme.bodySmall?.copyWith( style: textTheme.bodySmall?.copyWith(
color: const Color.fromARGB( color:
255, 102, 102, 102), Theme.of(context).colorScheme.caption,
), ),
), ),
], ],

View File

@ -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/overview_data.dart';
import 'package:didvan/views/widgets/didvan/text.dart'; import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/skeleton_image.dart'; import 'package:didvan/views/widgets/skeleton_image.dart';
@ -37,7 +41,9 @@ class VideocastGridCard extends StatelessWidget {
onTap: onTap, onTap: onTap,
child: Container( child: Container(
decoration: BoxDecoration( 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), borderRadius: BorderRadius.circular(20),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
@ -50,7 +56,6 @@ class VideocastGridCard extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
// Video cover
Padding( Padding(
padding: const EdgeInsets.all(6.0), padding: const EdgeInsets.all(6.0),
child: AspectRatio( child: AspectRatio(
@ -66,7 +71,6 @@ class VideocastGridCard extends StatelessWidget {
), ),
), ),
), ),
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.fromLTRB(12, 4, 12, 8), padding: const EdgeInsets.fromLTRB(12, 4, 12, 8),
@ -78,7 +82,9 @@ class VideocastGridCard extends StatelessWidget {
videocast.title, videocast.title,
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Colors.black87, color: DesignConfig.isDark
? Colors.white70
: Colors.black87,
), ),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -94,7 +100,7 @@ class VideocastGridCard extends StatelessWidget {
.textTheme .textTheme
.bodySmall .bodySmall
?.copyWith( ?.copyWith(
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -106,7 +112,7 @@ class VideocastGridCard extends StatelessWidget {
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
'lib/assets/icons/clock.svg', 'lib/assets/icons/clock.svg',
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
DidvanText( DidvanText(
@ -115,7 +121,7 @@ class VideocastGridCard extends StatelessWidget {
.textTheme .textTheme
.bodySmall .bodySmall
?.copyWith( ?.copyWith(
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
), ),
], ],

View File

@ -1,5 +1,7 @@
import 'dart:async'; 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/constants/app_icons.dart';
import 'package:didvan/models/enums.dart'; import 'package:didvan/models/enums.dart';
import 'package:didvan/models/view/action_sheet_data.dart'; import 'package:didvan/models/view/action_sheet_data.dart';
@ -178,6 +180,8 @@ class _MonthlyListPageState extends State<MonthlyListPage> {
style: theme.textTheme.headlineSmall?.copyWith( style: theme.textTheme.headlineSmall?.copyWith(
color: isDark color: isDark
? Colors.white ? Colors.white
: DesignConfig.isDark
? const Color.fromARGB(255, 0, 90, 119)
: const Color.fromARGB(255, 0, 53, 70), : const Color.fromARGB(255, 0, 53, 70),
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 19), fontSize: 19),
@ -193,7 +197,7 @@ class _MonthlyListPageState extends State<MonthlyListPage> {
colorFilter: ColorFilter.mode( colorFilter: ColorFilter.mode(
isDark isDark
? Colors.white70 ? Colors.white70
: const Color.fromARGB(255, 102, 102, 102), : Theme.of(context).colorScheme.caption,
BlendMode.srcIn), BlendMode.srcIn),
), ),
), ),
@ -237,7 +241,9 @@ class _MonthlyListPageState extends State<MonthlyListPage> {
}, },
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: DesignConfig.isDark
? const Color.fromARGB(255, 36, 36, 36)
: Colors.white,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 184, 184, 184), color: const Color.fromARGB(255, 184, 184, 184),
@ -267,8 +273,10 @@ class _MonthlyListPageState extends State<MonthlyListPage> {
children: [ children: [
DidvanText( DidvanText(
item.title, item.title,
style: const TextStyle( style: TextStyle(
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 15, fontSize: 15,
), ),

View File

@ -1,6 +1,8 @@
import 'dart:async'; import 'dart:async';
import 'dart:math'; 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/constants/app_icons.dart';
import 'package:didvan/models/enums.dart'; import 'package:didvan/models/enums.dart';
import 'package:didvan/models/requests/news.dart'; import 'package:didvan/models/requests/news.dart';
@ -69,7 +71,7 @@ class _NewsState extends State<News> {
title: Text( title: Text(
'دنیای فولاد', 'دنیای فولاد',
style: theme.textTheme.headlineSmall?.copyWith( 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, fontWeight: FontWeight.bold,
fontSize: 19), fontSize: 19),
), ),
@ -80,8 +82,8 @@ class _NewsState extends State<News> {
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
width: 30, width: 30,
height: 30, height: 30,
colorFilter: const ColorFilter.mode( colorFilter: ColorFilter.mode(
Color.fromARGB(255, 102, 102, 102), BlendMode.srcIn), Theme.of(context).colorScheme.caption, BlendMode.srcIn),
), ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),

View File

@ -1,4 +1,5 @@
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/day_time.dart'; import 'package:didvan/models/day_time.dart';
import 'package:didvan/models/enums.dart'; import 'package:didvan/models/enums.dart';
@ -106,7 +107,7 @@ class _NotificationSettingsState extends State<NotificationSettings>
child: SvgPicture.asset( child: SvgPicture.asset(
Assets.horizontalLogoWithText, Assets.horizontalLogoWithText,
fit: BoxFit.contain, fit: BoxFit.contain,
height: 80, height: 90,
), ),
), ),
actions: [ actions: [
@ -115,12 +116,15 @@ class _NotificationSettingsState extends State<NotificationSettings>
Navigator.of(context).pushNamed(Routes.bookmarks); Navigator.of(context).pushNamed(Routes.bookmarks);
}, },
icon: SvgPicture.asset( 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( IconButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
icon: SvgPicture.asset( icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
)), )),
const SizedBox(width: 8), const SizedBox(width: 8),
], ],
@ -160,22 +164,24 @@ class _NotificationSettingsState extends State<NotificationSettings>
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Padding( Padding(
padding: EdgeInsets.all(18.0), padding: const EdgeInsets.all(18.0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SizedBox(height: 10), const SizedBox(height: 10),
Text( Text(
'دسته‌بندی اعلان‌ها', 'دسته‌بندی اعلان‌ها',
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.black), color: DesignConfig.isDark
? Colors.white
: Colors.black),
), ),
SizedBox(height: 10), const SizedBox(height: 10),
Text( const Text(
'در این بخش می‌توانید تعیین کنید از کدام دسته از محتواهای منتشرشده در اپلیکیشن دیدوان، اعلان دریافت کنید.', 'در این بخش می‌توانید تعیین کنید از کدام دسته از محتواهای منتشرشده در اپلیکیشن دیدوان، اعلان دریافت کنید.',
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
@ -228,28 +234,30 @@ class _NotificationSettingsState extends State<NotificationSettings>
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Padding( Padding(
padding: EdgeInsets.all(18.0), padding: const EdgeInsets.all(18.0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SizedBox(height: 10), const SizedBox(height: 10),
Text( Text(
'زمان‌بندی دریافت اعلان‌ها', 'زمان‌بندی دریافت اعلان‌ها',
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: Colors.black), color: DesignConfig.isDark
? Colors.white
: Colors.black),
), ),
SizedBox(height: 10), const SizedBox(height: 10),
Text( const Text(
'در این بخش می‌توانید تعیین کنید اعلان‌های دسته‌بندی‌هایی که انتخاب کرده‌اید، در چه بازه‌های زمانی برای شما ارسال شوند..', 'در این بخش می‌توانید تعیین کنید اعلان‌های دسته‌بندی‌هایی که انتخاب کرده‌اید، در چه بازه‌های زمانی برای شما ارسال شوند..',
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
color: Color.fromARGB(255, 128, 128, 128), color: Color.fromARGB(255, 128, 128, 128),
)), )),
SizedBox( const SizedBox(
height: 15, height: 15,
) )
], ],
@ -353,8 +361,8 @@ class _CategoryExpansionGroupState extends State<_CategoryExpansionGroup> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const expansionColor = Color.fromARGB(255, 230, 243, 250); final expansionColor = Theme.of(context).colorScheme.focused;
const grayTextColor = Color.fromARGB(255, 102, 102, 102); final grayTextColor = Theme.of(context).colorScheme.caption;
return Padding( return Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
@ -380,7 +388,9 @@ class _CategoryExpansionGroupState extends State<_CategoryExpansionGroup> {
widget.title, widget.title,
style: Theme.of(context).textTheme.titleMedium?.copyWith( style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.normal, 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, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -392,7 +402,9 @@ class _CategoryExpansionGroupState extends State<_CategoryExpansionGroup> {
duration: const Duration(milliseconds: 200), duration: const Duration(milliseconds: 200),
child: SvgPicture.asset( child: SvgPicture.asset(
'lib/assets/icons/arrow-down.svg', '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), padding: const EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
color: Theme.of(context).colorScheme.surface, color: DesignConfig.isDark
? null
: Theme.of(context).colorScheme.surface,
), ),
child: Column( child: Column(
children: [ children: [
@ -444,6 +458,7 @@ class _CategoryExpansionGroupState extends State<_CategoryExpansionGroup> {
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: CupertinoSwitch( child: CupertinoSwitch(
value: item.selected ?? false, value: item.selected ?? false,
// ignore: deprecated_member_use
activeColor: activeColor:
Theme.of(context).colorScheme.primary, Theme.of(context).colorScheme.primary,
onChanged: (value) { onChanged: (value) {

View File

@ -206,7 +206,7 @@ class _PodcastsState extends State<Podcasts> {
builder: (context, setState) => Column( builder: (context, setState) => Column(
children: [ children: [
DidvanRadialButton( DidvanRadialButton(
title: 'تازه‌ترین‌ها', title: 'جدیدترین‌ها',
onSelected: () => setState( onSelected: () => setState(
() => state.selectedSortTypeIndex = 0, () => state.selectedSortTypeIndex = 0,
), ),

View File

@ -55,7 +55,7 @@ class PodcastsState extends CoreProvier {
} }
String get orderString { String get orderString {
if (selectedSortTypeIndex == 0) return 'تازه‌ترین‌ها'; if (selectedSortTypeIndex == 0) return 'جدیدترین‌ها';
if (selectedSortTypeIndex == 1) return 'قدیمی‌ترین‌ها'; if (selectedSortTypeIndex == 1) return 'قدیمی‌ترین‌ها';
if (selectedSortTypeIndex == 2) return 'پربازدیدترین‌ها'; if (selectedSortTypeIndex == 2) return 'پربازدیدترین‌ها';
return 'پربحث‌ترین‌ها'; return 'پربحث‌ترین‌ها';

View File

@ -1,6 +1,7 @@
// ignore_for_file: use_build_context_synchronously, deprecated_member_use // ignore_for_file: use_build_context_synchronously, deprecated_member_use
import 'package:chewie/chewie.dart'; import 'package:chewie/chewie.dart';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
@ -311,7 +312,7 @@ class _StudioDetailsState extends State<StudioDetails>
appBar: PreferredSize( appBar: PreferredSize(
preferredSize: const Size.fromHeight(90.0), preferredSize: const Size.fromHeight(90.0),
child: AppBar( child: AppBar(
backgroundColor: Colors.white, backgroundColor: Theme.of(context).colorScheme.surface,
elevation: 0, elevation: 0,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
flexibleSpace: SafeArea( flexibleSpace: SafeArea(
@ -324,14 +325,16 @@ class _StudioDetailsState extends State<StudioDetails>
Center( Center(
child: SvgPicture.asset( child: SvgPicture.asset(
'lib/assets/images/logos/logo-horizontal-light.svg', 'lib/assets/images/logos/logo-horizontal-light.svg',
color: DesignConfig.isDark
? Theme.of(context).colorScheme.caption
: null,
height: 55, height: 55,
), ),
), ),
IconButton( IconButton(
icon: SvgPicture.asset( icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
color: color: Theme.of(context).colorScheme.caption,
const Color.fromARGB(255, 102, 102, 102),
height: 24, height: 24,
), ),
onPressed: () { onPressed: () {
@ -450,10 +453,12 @@ class _StudioDetailsState extends State<StudioDetails>
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
state.studio.title, state.studio.title,
style: const TextStyle( style: TextStyle(
fontSize: 17, fontSize: 17,
fontWeight: FontWeight.bold, 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<StudioDetails>
children: [ children: [
Container( Container(
padding: const EdgeInsets.all(5.0), padding: const EdgeInsets.all(5.0),
decoration: const BoxDecoration( decoration: BoxDecoration(
color: Color.fromARGB(255, 230, 243, 250), color: Theme.of(context).colorScheme.focused,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: SvgPicture.asset( child: SvgPicture.asset(
@ -682,14 +687,18 @@ class _StudioDetailsState extends State<StudioDetails>
children: [ children: [
CircleAvatar( CircleAvatar(
radius: 20, radius: 20,
backgroundColor: Colors.white, backgroundColor: DesignConfig.isDark
? Colors.transparent
: Colors.white,
backgroundImage: backgroundImage:
hasProfileImage ? NetworkImage(user.photo!) : null, hasProfileImage ? NetworkImage(user.photo!) : null,
child: !hasProfileImage child: !hasProfileImage
? const Icon( ? Icon(
DidvanIcons.avatar_light, DidvanIcons.avatar_light,
size: 50, size: 50,
color: Colors.black, color: DesignConfig.isDark
? Colors.white
: Colors.black,
) )
: null, : null,
), ),
@ -702,12 +711,14 @@ class _StudioDetailsState extends State<StudioDetails>
}, },
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
const SizedBox( SizedBox(
width: double.infinity, width: double.infinity,
child: DidvanText( child: DidvanText(
'نظرات کاربران:', 'نظرات کاربران:',
style: TextStyle( 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, fontSize: 18,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -740,13 +751,15 @@ class _StudioDetailsState extends State<StudioDetails>
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Padding( Padding(
padding: EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
"مطالب مرتبط:", "مطالب مرتبط:",
style: TextStyle( style: TextStyle(
fontSize: 18, 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), fontWeight: FontWeight.bold),
), ),
), ),
@ -823,7 +836,6 @@ class _StudioDetailsState extends State<StudioDetails>
'type': item.type, 'type': item.type,
'onMarkChanged': (int id, bool value, 'onMarkChanged': (int id, bool value,
[bool shouldUpdate = true]) { [bool shouldUpdate = true]) {
// Match original
if (widget.pageData['onMarkChanged'] != if (widget.pageData['onMarkChanged'] !=
null) { null) {
widget.pageData['onMarkChanged']( widget.pageData['onMarkChanged'](
@ -845,7 +857,7 @@ class _StudioDetailsState extends State<StudioDetails>
if (widget.pageData['onMarkChanged'] != if (widget.pageData['onMarkChanged'] !=
null) { null) {
widget.pageData['onMarkChanged']( widget.pageData['onMarkChanged'](
id, value, true); // Modified id, value, true);
} }
}, },
), ),

View File

@ -1,5 +1,7 @@
import 'dart:math'; 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/enums.dart';
import 'package:didvan/models/studio_details_data.dart'; import 'package:didvan/models/studio_details_data.dart';
import 'package:didvan/views/comments/comments.dart'; import 'package:didvan/views/comments/comments.dart';
@ -241,7 +243,7 @@ class StudioPreview extends StatelessWidget {
width: 170, width: 170,
height: 235, height: 235,
decoration: BoxDecoration( 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), borderRadius: BorderRadius.circular(20),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
@ -281,7 +283,7 @@ class StudioPreview extends StatelessWidget {
_previewTitle, _previewTitle,
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
fontSize: 12 fontSize: 12
), ),
maxLines: 1, maxLines: 1,
@ -292,7 +294,7 @@ class StudioPreview extends StatelessWidget {
studio.title, studio.title,
style: Theme.of(context).textTheme.bodyMedium?.copyWith( style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
color: Colors.black87, color: DesignConfig.isDark? Colors.white70 : Colors.black87,
), ),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -302,7 +304,7 @@ class StudioPreview extends StatelessWidget {
children: [ children: [
SvgPicture.asset( SvgPicture.asset(
'lib/assets/icons/clock.svg', 'lib/assets/icons/clock.svg',
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
DidvanText( DidvanText(
@ -311,7 +313,7 @@ class StudioPreview extends StatelessWidget {
.textTheme .textTheme
.bodySmall .bodySmall
?.copyWith( ?.copyWith(
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
), ),
], ],

View File

@ -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/constants/assets.dart';
import 'package:didvan/providers/user.dart'; import 'package:didvan/providers/user.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
@ -81,7 +83,6 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
curve: const Interval(0.35, 0.65, curve: Curves.easeOutCubic), curve: const Interval(0.35, 0.65, curve: Curves.easeOutCubic),
)); ));
_fadeAnimation = Tween<double>( _fadeAnimation = Tween<double>(
begin: 0.0, begin: 0.0,
end: 1.0, end: 1.0,
@ -136,7 +137,7 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
key: _formKey, key: _formKey,
child: DidvanScaffold( child: DidvanScaffold(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
top: 16, top: 0,
left: 0, left: 0,
right: 0, right: 0,
), ),
@ -169,10 +170,14 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
opacity: _buttonFadeAnimation, opacity: _buttonFadeAnimation,
child: IconButton( child: IconButton(
onPressed: () { onPressed: () {
Navigator.of(context).pushNamed(Routes.bookmarks); Navigator.of(context)
.pushNamed(Routes.bookmarks);
}, },
icon: SvgPicture.asset( 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( SlideTransition(
@ -183,7 +188,7 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
icon: SvgPicture.asset( icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
), ),
), ),
@ -220,8 +225,7 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
.headlineSmall .headlineSmall
?.copyWith( ?.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 18 fontSize: 18),
),
textAlign: TextAlign.start, textAlign: TextAlign.start,
), ),
), ),
@ -230,7 +234,9 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
), ),
), ),
), ),
const SizedBox(height: 5,), const SizedBox(
height: 5,
),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0), padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: Column( child: Column(
@ -376,8 +382,8 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
changePasswordState.newPassword = _newPassword; changePasswordState.newPassword = _newPassword;
final userProvider = context.read<UserProvider>(); final userProvider = context.read<UserProvider>();
final success = final success = await changePasswordState
await changePasswordState.changePassword(userProvider); .changePassword(userProvider);
if (success && mounted) { if (success && mounted) {
Navigator.of(context).pushNamedAndRemoveUntil( Navigator.of(context).pushNamedAndRemoveUntil(

View File

@ -1,8 +1,12 @@
// ignore_for_file: deprecated_member_use
import 'dart:async'; import 'dart:async';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/providers/user.dart'; import 'package:didvan/providers/user.dart';
import 'package:didvan/routes/routes.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/profile/change_password/change_password_state.dart';
import 'package:didvan/views/widgets/didvan/button.dart'; import 'package:didvan/views/widgets/didvan/button.dart';
import 'package:didvan/views/widgets/didvan/scaffold.dart'; import 'package:didvan/views/widgets/didvan/scaffold.dart';
@ -170,7 +174,7 @@ class _VerifyOtpScreenState extends State<VerifyOtpScreen>
padding: const EdgeInsets.only(bottom: 150), padding: const EdgeInsets.only(bottom: 150),
child: DidvanScaffold( child: DidvanScaffold(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
top: 16, top: 0,
left: 0, left: 0,
right: 0, right: 0,
), ),
@ -206,7 +210,11 @@ class _VerifyOtpScreenState extends State<VerifyOtpScreen>
Navigator.of(context).pushNamed(Routes.bookmarks); Navigator.of(context).pushNamed(Routes.bookmarks);
}, },
icon: SvgPicture.asset( 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( SlideTransition(
@ -217,7 +225,7 @@ class _VerifyOtpScreenState extends State<VerifyOtpScreen>
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
icon: SvgPicture.asset( icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg', '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<VerifyOtpScreen>
const TextSpan( const TextSpan(
text: 'ما یک کد تأیید 6 رقمی به شماره '), text: 'ما یک کد تأیید 6 رقمی به شماره '),
TextSpan( TextSpan(
text: phoneNumber, text: phoneNumber.convertToPersianDigits(),
style: TextStyle( style: TextStyle(
color: color:
Theme.of(context).colorScheme.primary, Theme.of(context).colorScheme.primary,

View File

@ -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/constants/assets.dart';
import 'package:didvan/models/enums.dart'; import 'package:didvan/models/enums.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
@ -105,12 +109,16 @@ class _DirectListState extends State<DirectList>
Navigator.of(context).pushNamed(Routes.bookmarks); Navigator.of(context).pushNamed(Routes.bookmarks);
}, },
icon: SvgPicture.asset( 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( IconButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
icon: SvgPicture.asset( icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
)), )),
const SizedBox(width: 8), const SizedBox(width: 8),
], ],

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/chat_room/chat_room.dart'; import 'package:didvan/models/chat_room/chat_room.dart';
@ -56,7 +57,7 @@ class ChatRoomItem extends StatelessWidget {
child: DidvanText( child: DidvanText(
chatRoom.type, chatRoom.type,
style: Theme.of(context).textTheme.bodyLarge?.copyWith( 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) // if (chatRoom.unread != 0)
@ -78,7 +79,9 @@ class ChatRoomItem extends StatelessWidget {
decoration: BoxDecoration( decoration: BoxDecoration(
color: chatRoom.lastMessage.readed color: chatRoom.lastMessage.readed
? chatRoom.lastMessage.writedByAdmin ? chatRoom.lastMessage.writedByAdmin
? const Color.fromARGB(255, 230, 243, 250) ? 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, 235, 235, 235)
: const Color.fromARGB(255, 255, 200, 215), : const Color.fromARGB(255, 255, 200, 215),
borderRadius: BorderRadius.circular(8)), borderRadius: BorderRadius.circular(8)),
@ -150,7 +153,7 @@ class ChatRoomItem extends StatelessWidget {
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
textAlign: TextAlign.start, textAlign: TextAlign.start,
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
), ),
], ],

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:didvan/config/design_config.dart'; import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
import 'package:didvan/providers/user.dart'; import 'package:didvan/providers/user.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
@ -250,7 +251,7 @@ class _EditProfileState extends State<EditProfile>
icon: SvgPicture.asset( icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
color: color:
const Color.fromARGB(255, 102, 102, 102), Theme.of(context).colorScheme.caption,
)), )),
), ),
), ),

View File

@ -1,4 +1,5 @@
import 'package:didvan/config/design_config.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/app_icons.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/view/action_sheet_data.dart'; import 'package:didvan/models/view/action_sheet_data.dart';
@ -95,7 +96,7 @@ class _ProfilePageState extends State<ProfilePage>
onRetry: context.read<GeneralSettingsState>().init, onRetry: context.read<GeneralSettingsState>().init,
state: context.read<GeneralSettingsState>(), state: context.read<GeneralSettingsState>(),
builder: (context, state) => DidvanScaffold( builder: (context, state) => DidvanScaffold(
padding: const EdgeInsets.fromLTRB(8, 20, 0, 20), padding: const EdgeInsets.fromLTRB(0, 0, 0, 20),
appBarData: null, appBarData: null,
showSliversFirst: true, showSliversFirst: true,
slivers: [ slivers: [
@ -118,12 +119,12 @@ class _ProfilePageState extends State<ProfilePage>
Navigator.of(context).pushNamed(Routes.bookmarks); Navigator.of(context).pushNamed(Routes.bookmarks);
}, },
icon: SvgPicture.asset( icon: SvgPicture.asset(
'lib/assets/icons/hugeicons_telescope-01.svg')), 'lib/assets/icons/hugeicons_telescope-01.svg',color: Theme.of(context).colorScheme.caption,)),
IconButton( IconButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
icon: SvgPicture.asset( icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
)), )),
const SizedBox(width: 8), const SizedBox(width: 8),
], ],
@ -212,7 +213,7 @@ class _ProfilePageState extends State<ProfilePage>
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color.fromARGB(255, 230, 243, 250), color: Theme.of(context).colorScheme.focused,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: Center( child: Center(
@ -222,7 +223,7 @@ class _ProfilePageState extends State<ProfilePage>
.textTheme .textTheme
.titleMedium .titleMedium
?.copyWith( ?.copyWith(
color: Colors.black, color: DesignConfig.isDark? Colors.white : Colors.black,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
fontSize: 15), fontSize: 15),
), ),
@ -230,10 +231,10 @@ class _ProfilePageState extends State<ProfilePage>
), ),
const SizedBox(height: 15), const SizedBox(height: 15),
MenuOption( MenuOption(
titleWidget: const DidvanText('ویرایش پروفایل', titleWidget: DidvanText('ویرایش پروفایل',
style: TextStyle( style: TextStyle(
color: color:
Color.fromARGB(255, 102, 102, 102))), Theme.of(context).colorScheme.caption)),
onTap: () => Navigator.of(context) onTap: () => Navigator.of(context)
.pushNamed(Routes.editProfile), .pushNamed(Routes.editProfile),
iconWidget: SvgPicture.asset( iconWidget: SvgPicture.asset(
@ -241,10 +242,10 @@ class _ProfilePageState extends State<ProfilePage>
), ),
const DidvanDivider(), const DidvanDivider(),
MenuOption( MenuOption(
titleWidget: const DidvanText('تغییر رمز عبور ', titleWidget: DidvanText('تغییر رمز عبور ',
style: TextStyle( style: TextStyle(
color: color:
Color.fromARGB(255, 102, 102, 102))), Theme.of(context).colorScheme.caption)),
iconWidget: iconWidget:
SvgPicture.asset('lib/assets/icons/lock.svg'), SvgPicture.asset('lib/assets/icons/lock.svg'),
onTap: () => Navigator.of(context).pushNamed( onTap: () => Navigator.of(context).pushNamed(
@ -303,7 +304,7 @@ class _ProfilePageState extends State<ProfilePage>
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color.fromARGB(255, 230, 243, 250), color: Theme.of(context).colorScheme.focused,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: Center( child: Center(
@ -313,7 +314,7 @@ class _ProfilePageState extends State<ProfilePage>
.textTheme .textTheme
.titleMedium .titleMedium
?.copyWith( ?.copyWith(
color: Colors.black, color: DesignConfig.isDark? Colors.white : Colors.black,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
fontSize: 15), fontSize: 15),
), ),
@ -321,10 +322,10 @@ class _ProfilePageState extends State<ProfilePage>
), ),
const SizedBox(height: 15), const SizedBox(height: 15),
MenuOption( MenuOption(
titleWidget: const DidvanText('تنظیمات اعلان‌ها', titleWidget: DidvanText('تنظیمات اعلان‌ها',
style: TextStyle( style: TextStyle(
color: color:
Color.fromARGB(255, 102, 102, 102))), Theme.of(context).colorScheme.caption)),
onTap: () => Navigator.of(context) onTap: () => Navigator.of(context)
.pushNamed(Routes.notificationSettings), .pushNamed(Routes.notificationSettings),
iconWidget: SvgPicture.asset( iconWidget: SvgPicture.asset(
@ -332,10 +333,9 @@ class _ProfilePageState extends State<ProfilePage>
), ),
const DidvanDivider(), const DidvanDivider(),
MenuOption( MenuOption(
titleWidget: const DidvanText('ظاهر اپلیکیشن', titleWidget: DidvanText('ظاهر اپلیکیشن',
style: TextStyle( style: TextStyle(
color: Color.fromARGB( color: Theme.of(context).colorScheme.caption)),
255, 102, 102, 102))),
iconWidget: SvgPicture.asset( iconWidget: SvgPicture.asset(
'lib/assets/icons/fluent_paint-brush-16-regular.svg'), 'lib/assets/icons/fluent_paint-brush-16-regular.svg'),
onTap: () { onTap: () {
@ -348,7 +348,7 @@ class _ProfilePageState extends State<ProfilePage>
: 'lib/assets/icons/arrow-down.svg', : 'lib/assets/icons/arrow-down.svg',
height: 25, height: 25,
color: color:
const Color.fromARGB(255, 102, 102, 102), Theme.of(context).colorScheme.caption,
)), )),
const SizedBox(height: 8), const SizedBox(height: 8),
AnimatedVisibility( AnimatedVisibility(
@ -368,10 +368,9 @@ class _ProfilePageState extends State<ProfilePage>
: state.fontFamily == 'Iransans-FA' : state.fontFamily == 'Iransans-FA'
? 'ایران سنس' ? 'ایران سنس'
: 'ایران یکان', : 'ایران یکان',
titleWidget: const DidvanText('فونت', titleWidget: DidvanText('فونت',
style: TextStyle( style: TextStyle(
color: Color.fromARGB( color: Theme.of(context).colorScheme.caption)),
255, 102, 102, 102))),
onTap: _showFontFamilyBottomSheet, onTap: _showFontFamilyBottomSheet,
iconWidget: SvgPicture.asset( iconWidget: SvgPicture.asset(
'lib/assets/icons/hugeicons_edit-01.svg'), 'lib/assets/icons/hugeicons_edit-01.svg'),
@ -383,11 +382,10 @@ class _ProfilePageState extends State<ProfilePage>
child: MenuOption( child: MenuOption(
suffix: fontScaleSuffix( suffix: fontScaleSuffix(
state.fontSizeScale), state.fontSizeScale),
titleWidget: const DidvanText( titleWidget: DidvanText(
'اندازه متن', 'اندازه متن',
style: TextStyle( style: TextStyle(
color: Color.fromARGB( color: Theme.of(context).colorScheme.caption)),
255, 102, 102, 102))),
onTap: _showFontScaleBottomSheet, onTap: _showFontScaleBottomSheet,
iconWidget: SvgPicture.asset( iconWidget: SvgPicture.asset(
'lib/assets/icons/smallcaps.svg'), 'lib/assets/icons/smallcaps.svg'),
@ -404,13 +402,9 @@ class _ProfilePageState extends State<ProfilePage>
SvgPicture.asset( SvgPicture.asset(
'lib/assets/icons/moon.svg'), 'lib/assets/icons/moon.svg'),
const SizedBox(width: 4), const SizedBox(width: 4),
const DidvanText('تم برنامه', DidvanText('تم برنامه',
style: TextStyle( style: TextStyle(
color: Color.fromARGB( color: Theme.of(context).colorScheme.caption)),
255,
102,
102,
102))),
], ],
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
@ -462,7 +456,7 @@ class _ProfilePageState extends State<ProfilePage>
width: double.infinity, width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color.fromARGB(255, 230, 243, 250), color: Theme.of(context).colorScheme.focused,
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
child: Center( child: Center(
@ -472,7 +466,7 @@ class _ProfilePageState extends State<ProfilePage>
.textTheme .textTheme
.titleMedium .titleMedium
?.copyWith( ?.copyWith(
color: Colors.black, color: DesignConfig.isDark? Colors.white : Colors.black,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
fontSize: 15), fontSize: 15),
), ),
@ -482,10 +476,10 @@ class _ProfilePageState extends State<ProfilePage>
MenuOption( MenuOption(
iconWidget: SvgPicture.asset( iconWidget: SvgPicture.asset(
'lib/assets/icons/info-circle.svg'), 'lib/assets/icons/info-circle.svg'),
titleWidget: const DidvanText('درباره دیدوان', titleWidget: DidvanText('درباره دیدوان',
style: TextStyle( style: TextStyle(
color: color:
Color.fromARGB(255, 102, 102, 102))), Theme.of(context).colorScheme.caption)),
onTap: () => launchUrlString( onTap: () => launchUrlString(
'https://didvan.com/#info', 'https://didvan.com/#info',
mode: LaunchMode.inAppWebView), mode: LaunchMode.inAppWebView),
@ -494,10 +488,9 @@ class _ProfilePageState extends State<ProfilePage>
MenuOption( MenuOption(
iconWidget: SvgPicture.asset( iconWidget: SvgPicture.asset(
'lib/assets/icons/call-calling.svg'), 'lib/assets/icons/call-calling.svg'),
titleWidget: const DidvanText('تماس با ما', titleWidget: DidvanText('تماس با ما',
style: TextStyle( style: TextStyle(
color: Color.fromARGB( color: Theme.of(context).colorScheme.caption)),
255, 102, 102, 102))),
onTap: () { onTap: () {
Navigator.of(context) Navigator.of(context)
.pushNamed(Routes.directList) .pushNamed(Routes.directList)
@ -604,10 +597,10 @@ class _ProfilePageState extends State<ProfilePage>
MenuOption( MenuOption(
iconWidget: SvgPicture.asset( iconWidget: SvgPicture.asset(
'lib/assets/icons/security-safe.svg'), 'lib/assets/icons/security-safe.svg'),
titleWidget: const DidvanText('حریم خصوصی', titleWidget: DidvanText('حریم خصوصی',
style: TextStyle( style: TextStyle(
color: color:
Color.fromARGB(255, 102, 102, 102))), Theme.of(context).colorScheme.caption)),
onTap: () => launchUrlString( onTap: () => launchUrlString(
'https://didvan.com/terms-of-use#privacy', 'https://didvan.com/terms-of-use#privacy',
mode: LaunchMode.inAppWebView), mode: LaunchMode.inAppWebView),

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:math'; import 'dart:math';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/category.dart'; import 'package:didvan/models/category.dart';
import 'package:didvan/models/enums.dart'; import 'package:didvan/models/enums.dart';
@ -108,7 +109,7 @@ class _RadarStateView extends State<Radar> {
colorFilter: ColorFilter.mode( colorFilter: ColorFilter.mode(
isDark isDark
? Colors.white70 ? Colors.white70
: const Color.fromARGB(255, 102, 102, 102), : Theme.of(context).colorScheme.caption,
BlendMode.srcIn), BlendMode.srcIn),
), ),
), ),

View File

@ -36,7 +36,6 @@ class AudioPlayerWidget extends StatelessWidget {
aspectRatio: 1 / 1.3, aspectRatio: 1 / 1.3,
borderRadius: BorderRadius.circular(0), borderRadius: BorderRadius.circular(0),
), ),
Positioned( Positioned(
bottom: 0, bottom: 0,
left: 0, left: 0,
@ -127,9 +126,7 @@ class AudioPlayerWidget extends StatelessWidget {
.withOpacity(0.7), .withOpacity(0.7),
), ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded( Expanded(
child: AudioWaveformProgress( child: AudioWaveformProgress(
progress: progress.clamp(0.0, 1.0), progress: progress.clamp(0.0, 1.0),
@ -147,7 +144,6 @@ class AudioPlayerWidget extends StatelessWidget {
), ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
_formatDuration(position), _formatDuration(position),
style: TextStyle( style: TextStyle(
@ -168,9 +164,7 @@ class AudioPlayerWidget extends StatelessWidget {
], ],
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -187,8 +181,8 @@ class AudioPlayerWidget extends StatelessWidget {
'lib/assets/icons/timer-pause.svg', 'lib/assets/icons/timer-pause.svg',
width: 35, width: 35,
height: 35, height: 35,
colorFilter: const ColorFilter.mode( colorFilter: ColorFilter.mode(
Color.fromARGB(255, 102, 102, 102), Theme.of(context).colorScheme.caption,
BlendMode.srcIn, BlendMode.srcIn,
), ),
), ),
@ -245,7 +239,12 @@ class AudioPlayerWidget extends StatelessWidget {
); );
}, },
icon: SvgPicture.asset( 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( 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( child: Container(
width: 46, width: 46,
alignment: Alignment.center, alignment: Alignment.center,
margin: const EdgeInsets.fromLTRB( margin:
12, 0, 0, 0), // تغییر: 46 پایین حذف شد const EdgeInsets.fromLTRB(12, 0, 0, 0),
padding: const EdgeInsets.only(top: 2), padding: const EdgeInsets.only(top: 2),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: borderRadius:
@ -323,10 +327,12 @@ class AudioPlayerWidget extends StatelessWidget {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: DidvanText( child: DidvanText(
'${snapshot.data!.toString().replaceAll('.0', '')}X', '${snapshot.data!.toString().replaceAll('.0', '')}X',
style: const TextStyle( style: TextStyle(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
color: Color.fromARGB( color: Theme.of(context)
255, 102, 102, 102)), .colorScheme
.caption,
),
), ),
), ),
), ),
@ -350,7 +356,6 @@ class AudioPlayerWidget extends StatelessWidget {
), ),
], ],
), ),
// اضافه کردن کمی فاصله در پایین
const SizedBox(height: 16), const SizedBox(height: 16),
], ],
), ),
@ -410,14 +415,15 @@ class AudioPlayerWidget extends StatelessWidget {
SvgPicture.asset( SvgPicture.asset(
'lib/assets/icons/timer-pause.svg', 'lib/assets/icons/timer-pause.svg',
height: 24, height: 24,
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
const SizedBox( const SizedBox(
width: 10, width: 10,
), ),
const Text( Text(
'زمان خواب', 'زمان خواب',
style: TextStyle(color: Color.fromARGB(255, 102, 102, 102)), style:
TextStyle(color: Theme.of(context).colorScheme.caption),
) )
], ],
), ),

View File

@ -1,16 +1,17 @@
// ignore_for_file: deprecated_member_use
import 'dart:async'; import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
class Carousel3D extends StatefulWidget { class Carousel3D extends StatefulWidget {
final List<Widget> items; final List<Widget> items;
final double height; final double height;
final Duration autoPlayDuration; final Duration autoPlayDuration;
final Function(int)? onItemChanged; final Function(int)? onItemChanged;
final bool showControls; final bool showControls;
final void Function(int index)? onItemTap;
const Carousel3D({ const Carousel3D({
super.key, super.key,
@ -19,17 +20,23 @@ class Carousel3D extends StatefulWidget {
this.autoPlayDuration = const Duration(seconds: 4), this.autoPlayDuration = const Duration(seconds: 4),
this.onItemChanged, this.onItemChanged,
this.showControls = true, this.showControls = true,
this.onItemTap,
}); });
@override @override
State<Carousel3D> createState() => _Carousel3DState(); State<Carousel3D> createState() => _Carousel3DState();
} }
class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateMixin { class _Carousel3DState extends State<Carousel3D>
with SingleTickerProviderStateMixin {
late final AnimationController _controller; late final AnimationController _controller;
Timer? _autoPlayTimer; Timer? _autoPlayTimer;
int _currentIndex = 0; int _currentIndex = 0;
int _targetIndex = 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 @override
void initState() { void initState() {
@ -75,7 +82,6 @@ class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateM
_goToIndex((_currentIndex - 1 + widget.items.length) % widget.items.length); _goToIndex((_currentIndex - 1 + widget.items.length) % widget.items.length);
} }
@override @override
void dispose() { void dispose() {
_autoPlayTimer?.cancel(); _autoPlayTimer?.cancel();
@ -89,7 +95,62 @@ class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateM
return Column( return Column(
children: [ children: [
SizedBox( 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;
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, height: widget.height,
child: AnimatedBuilder( child: AnimatedBuilder(
animation: _controller, animation: _controller,
@ -97,20 +158,36 @@ class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateM
return Stack( return Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: List.generate(widget.items.length, (index) { children: List.generate(widget.items.length, (index) {
final double currentRelativePos = (index - _currentIndex).toDouble(); final int len = widget.items.length;
final double targetRelativePos = (index - _targetIndex).toDouble(); final int half = len ~/ 2;
int circularDelta(int i, int center) {
int raw = i - center;
if (raw > half) raw -= len;
if (raw < -half) raw += len;
return raw;
}
final double currentRelativePos =
circularDelta(index, _currentIndex).toDouble();
final double targetRelativePos =
circularDelta(index, _targetIndex).toDouble();
final double relativePos = Tween<double>( final double relativePos = Tween<double>(
begin: currentRelativePos, begin: currentRelativePos,
end: targetRelativePos, end: targetRelativePos,
).transform(CurvedAnimation(parent: _controller, curve: Curves.easeInOutCubic).value); ).transform(CurvedAnimation(
parent: _controller, curve: Curves.easeInOutCubic)
.value);
final bool isGrayscale = relativePos != 0; final bool isGrayscale = relativePos != 0;
final double absRelativePos = relativePos.abs(); final double absRelativePos = relativePos.abs();
final double scale = (1 - (absRelativePos * 0.15)).clamp(0.0, 1.0); final double scale =
(1 - (absRelativePos * 0.15)).clamp(0.0, 1.0);
final double translateX = relativePos * -30.0; final double translateX = relativePos * -30.0;
final double translateZ = absRelativePos * -100.0; final double translateZ = absRelativePos * -100.0;
final double opacity = (1 - (absRelativePos * 0.3)).clamp(0.0, 1.0); final double opacity =
(1 - (absRelativePos * 0.3)).clamp(0.0, 1.0);
Matrix4 transform = Matrix4.identity() Matrix4 transform = Matrix4.identity()
..setEntry(3, 2, 0.001) ..setEntry(3, 2, 0.001)
@ -122,19 +199,20 @@ class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateM
alignment: Alignment.center, alignment: Alignment.center,
child: Opacity( child: Opacity(
opacity: opacity, opacity: opacity,
child: IgnorePointer(
ignoring: relativePos != 0,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: relativePos == 0
if (relativePos != 0) { ? () => widget.onItemTap?.call(index)
_goToIndex(index); : null,
}
},
child: Container( child: Container(
width: screenWidth * 0.7, width: screenWidth * 0.7,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(isGrayscale ? 0.1 : 0.25), color: Colors.black
.withOpacity(isGrayscale ? 0.1 : 0.25),
spreadRadius: 2, spreadRadius: 2,
blurRadius: 10, blurRadius: 10,
offset: const Offset(0, 5), offset: const Offset(0, 5),
@ -146,10 +224,26 @@ class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateM
child: ColorFiltered( child: ColorFiltered(
colorFilter: isGrayscale colorFilter: isGrayscale
? const ColorFilter.matrix([ ? const ColorFilter.matrix([
0.2126, 0.7152, 0.0722, 0, 0, 0.2126,
0.2126, 0.7152, 0.0722, 0, 0, 0.7152,
0.2126, 0.7152, 0.0722, 0, 0, 0.0722,
0, 0, 0, 1, 0, 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( : const ColorFilter.mode(
Colors.transparent, Colors.transparent,
@ -161,17 +255,22 @@ class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateM
), ),
), ),
), ),
),
); );
}).toList() }).toList()
..sort((a, b) { ..sort((a, b) {
final transformA = a.transform; final transformA = a.transform;
final transformB = b.transform; final transformB = b.transform;
return transformA.getTranslation().z.compareTo(transformB.getTranslation().z); return transformA
.getTranslation()
.z
.compareTo(transformB.getTranslation().z);
}), }),
); );
}, },
), ),
), ),
),
if (widget.showControls) ...[ if (widget.showControls) ...[
const SizedBox(height: 4), const SizedBox(height: 4),
Row( Row(

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/theme_data.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
@ -57,7 +58,7 @@ class _CustomMediaTabBarState extends State<CustomMediaTabBar> {
colorFilter: ColorFilter.mode( colorFilter: ColorFilter.mode(
isSelected isSelected
? Theme.of(context).colorScheme.primary ? Theme.of(context).colorScheme.primary
: const Color.fromARGB(255, 102, 102, 102), : Theme.of(context).colorScheme.caption,
BlendMode.srcIn, BlendMode.srcIn,
), ),
), ),
@ -73,7 +74,7 @@ class _CustomMediaTabBarState extends State<CustomMediaTabBar> {
style: Theme.of(context).textTheme.bodySmall!.copyWith( style: Theme.of(context).textTheme.bodySmall!.copyWith(
color: isSelected color: isSelected
? Theme.of(context).colorScheme.primary ? Theme.of(context).colorScheme.primary
: const Color.fromARGB(255, 102, 102, 102), : Theme.of(context).colorScheme.caption,
fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400, fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400,
), ),
), ),

View File

@ -313,7 +313,7 @@ class _NavBarItemState extends State<_NavBarItem>
child: DidvanText( child: DidvanText(
widget.title, widget.title,
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
) )

View File

@ -103,7 +103,7 @@ class _DidvanPageViewState extends State<DidvanPageView> {
appBar: PreferredSize( appBar: PreferredSize(
preferredSize: const Size.fromHeight(90.0), preferredSize: const Size.fromHeight(90.0),
child: AppBar( child: AppBar(
backgroundColor: Colors.white, backgroundColor: Theme.of(context).colorScheme.surface,
elevation: 0, elevation: 0,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
flexibleSpace: SafeArea( flexibleSpace: SafeArea(
@ -122,7 +122,7 @@ class _DidvanPageViewState extends State<DidvanPageView> {
IconButton( IconButton(
icon: SvgPicture.asset( icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
height: 24, height: 24,
), ),
onPressed: () { onPressed: () {
@ -555,9 +555,9 @@ class _DidvanPageViewState extends State<DidvanPageView> {
children: [ children: [
DidvanText( DidvanText(
_formatDuration(totalDuration), _formatDuration(totalDuration),
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
@ -578,9 +578,9 @@ class _DidvanPageViewState extends State<DidvanPageView> {
const SizedBox(width: 8), const SizedBox(width: 8),
DidvanText( DidvanText(
_formatDuration(position), _formatDuration(position),
style: const TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
), ),
], ],
@ -603,7 +603,7 @@ class _DidvanPageViewState extends State<DidvanPageView> {
'lib/assets/icons/timer-pause.svg', 'lib/assets/icons/timer-pause.svg',
width: 24, width: 24,
height: 24, height: 24,
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
onPressed: () { onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar( ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
@ -686,12 +686,12 @@ class _DidvanPageViewState extends State<DidvanPageView> {
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: DesignConfig.mediumBorderRadius, borderRadius: DesignConfig.mediumBorderRadius,
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 102, 102, 102))), color: Theme.of(context).colorScheme.caption)),
child: DidvanText( child: DidvanText(
'${snapshot.data!.toString().replaceAll('.0', '')}X', '${snapshot.data!.toString().replaceAll('.0', '')}X',
style: const TextStyle( style: TextStyle(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
color: Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
fontSize: 12), fontSize: 12),
), ),
), ),
@ -877,7 +877,7 @@ class _DidvanPageViewState extends State<DidvanPageView> {
DidvanText( DidvanText(
DateTime.parse(item.createdAt!).toPersianDateStr(), DateTime.parse(item.createdAt!).toPersianDateStr(),
style: Theme.of(context).textTheme.bodySmall?.copyWith( 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<DidvanPageView> {
DidvanText( DidvanText(
DateTime.parse(item.createdAt!).toPersianDateStr(), DateTime.parse(item.createdAt!).toPersianDateStr(),
style: Theme.of(context).textTheme.bodySmall?.copyWith( style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
), ),
], ],

View File

@ -199,7 +199,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
Color _borderColor() { Color _borderColor() {
if (_focusNode.hasFocus) { if (_focusNode.hasFocus) {
return const Color.fromARGB(255, 102, 102, 102); return Theme.of(context).colorScheme.caption;
} else if (_error != null) { } else if (_error != null) {
return Theme.of(context).colorScheme.error; return Theme.of(context).colorScheme.error;
} }
@ -213,7 +213,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
if (_error != null) { if (_error != null) {
return Theme.of(context).colorScheme.error; return Theme.of(context).colorScheme.error;
} }
return const Color.fromARGB(255, 102, 102, 102); return Theme.of(context).colorScheme.caption;
} }
Color _fillColor() { Color _fillColor() {
@ -247,6 +247,9 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
_hideContent _hideContent
? 'lib/assets/icons/eye.svg' ? 'lib/assets/icons/eye.svg'
: 'lib/assets/icons/eye-slash.svg', : 'lib/assets/icons/eye-slash.svg',
color: DesignConfig.isDark
? Theme.of(context).colorScheme.caption
: null,
height: 20, height: 20,
), ),
), ),

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
import 'package:didvan/views/ai/history_ai_chat_state.dart'; import 'package:didvan/views/ai/history_ai_chat_state.dart';
@ -19,6 +20,7 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
color: Theme.of(context).colorScheme.surface,
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -80,6 +82,7 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: SvgPicture.asset( child: SvgPicture.asset(
'lib/assets/icons/history.svg', 'lib/assets/icons/history.svg',
color: Theme.of(context).colorScheme.inputText,
height: 24, height: 24,
), ),
), ),
@ -90,6 +93,7 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
if (withInfo) if (withInfo)
DidvanIconButton( DidvanIconButton(
icon: DidvanIcons.angle_left_light, icon: DidvanIcons.angle_left_light,
color: Theme.of(context).colorScheme.inputText,
size: 32, size: 32,
onPressed: () => onBack?.call(), onPressed: () => onBack?.call(),
), ),

View File

@ -1,5 +1,5 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/constants/assets.dart'; import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/ai/ai_chat_args.dart'; import 'package:didvan/models/ai/ai_chat_args.dart';
import 'package:didvan/providers/user.dart'; import 'package:didvan/providers/user.dart';
@ -84,9 +84,11 @@ class _HoshanHomeAppBarState extends State<HoshanHomeAppBar> {
final userProvider = context.watch<UserProvider>(); final userProvider = context.watch<UserProvider>();
return Container( return Container(
decoration: const BoxDecoration( decoration: BoxDecoration(
color: Color.fromRGBO(230, 242, 246, 1), color: DesignConfig.isDark
borderRadius: BorderRadius.only( ? const Color.fromARGB(255, 78, 82, 84)
: const Color.fromRGBO(230, 242, 246, 1),
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(32), bottomLeft: Radius.circular(32),
bottomRight: Radius.circular(32), bottomRight: Radius.circular(32),
), ),
@ -121,6 +123,7 @@ class _HoshanHomeAppBarState extends State<HoshanHomeAppBar> {
child: SvgPicture.asset( child: SvgPicture.asset(
'lib/assets/icons/history.svg', 'lib/assets/icons/history.svg',
height: 24, height: 24,
color: Theme.of(context).colorScheme.inputText,
), ),
), ),
), ),
@ -148,7 +151,9 @@ class _HoshanHomeAppBarState extends State<HoshanHomeAppBar> {
padding: padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 11), const EdgeInsets.symmetric(horizontal: 16, vertical: 11),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: DesignConfig.isDark
? const Color.fromARGB(255, 195, 195, 196)
: Colors.white,
borderRadius: BorderRadius.circular(30), borderRadius: BorderRadius.circular(30),
border: Border.all( border: Border.all(
color: const Color.fromARGB(255, 25, 93, 128), color: const Color.fromARGB(255, 25, 93, 128),
@ -308,7 +313,9 @@ class _HistoryDrawerContentState extends State<HistoryDrawerContent> {
width: MediaQuery.of(context).size.width * 0.75, width: MediaQuery.of(context).size.width * 0.75,
height: MediaQuery.of(context).size.height, height: MediaQuery.of(context).size.height,
decoration: BoxDecoration( 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: [
BoxShadow( BoxShadow(
// ignore: deprecated_member_use // ignore: deprecated_member_use
@ -390,10 +397,15 @@ class _HistoryDrawerContentState extends State<HistoryDrawerContent> {
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 11), horizontal: 12, vertical: 11),
decoration: BoxDecoration( 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), borderRadius: BorderRadius.circular(8),
border: Border.all( border: Border.all(
color: const Color.fromARGB( color: DesignConfig.isDark
? const Color.fromARGB(
255, 107, 106, 106)
: const Color.fromARGB(
255, 223, 223, 223), 255, 223, 223, 223),
width: 1)), width: 1)),
child: Row( child: Row(
@ -404,10 +416,13 @@ class _HistoryDrawerContentState extends State<HistoryDrawerContent> {
Expanded( Expanded(
child: TextField( child: TextField(
controller: _searchController, controller: _searchController,
decoration: const InputDecoration( decoration: InputDecoration(
hintText: 'جستجو', hintText: 'جستجو',
hintStyle: TextStyle( hintStyle: TextStyle(
color: Color.fromARGB( color: DesignConfig.isDark
? const Color.fromARGB(
255, 113, 112, 1112)
: const Color.fromARGB(
255, 161, 160, 160), 255, 161, 160, 160),
fontSize: 14), fontSize: 14),
border: InputBorder.none, border: InputBorder.none,
@ -460,11 +475,13 @@ class _HistoryDrawerContentState extends State<HistoryDrawerContent> {
), ),
), ),
), ),
const Padding( Padding(
padding: EdgeInsets.fromLTRB(40, 10, 40, 0), padding: const EdgeInsets.fromLTRB(40, 10, 40, 0),
child: Divider( child: Divider(
height: 3, 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( Expanded(
@ -716,7 +733,6 @@ class _HistoryDrawerContentState extends State<HistoryDrawerContent> {
), ),
), ),
), ),
const PopupMenuDivider(height: 10),
], ],
), ),
], ],

View File

@ -1,4 +1,5 @@
import 'package:didvan/config/design_config.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/app_icons.dart';
import 'package:didvan/models/tag.dart'; import 'package:didvan/models/tag.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
@ -42,16 +43,16 @@ class InfographyTag extends StatelessWidget {
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const Icon( Icon(
DidvanIcons.hashtag_regular, DidvanIcons.hashtag_regular,
color: Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
size: 16, size: 16,
), ),
Padding( Padding(
padding: const EdgeInsets.all(2.0), padding: const EdgeInsets.all(2.0),
child: DidvanText( child: DidvanText(
tag.label, tag.label,
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
style: Theme.of(context).textTheme.labelMedium, style: Theme.of(context).textTheme.labelMedium,
), ),
), ),

View File

@ -77,7 +77,7 @@ class MenuOption extends StatelessWidget {
child: trailing ?? child: trailing ??
SvgPicture.asset( SvgPicture.asset(
'lib/assets/icons/arrow-left.svg', 'lib/assets/icons/arrow-left.svg',
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
), ),
) )
], ],

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/models/overview_data.dart'; import 'package:didvan/models/overview_data.dart';
import 'package:didvan/models/requests/news.dart'; import 'package:didvan/models/requests/news.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
@ -124,7 +125,7 @@ class NewsOverview extends StatelessWidget {
onLikedChanged(news.id, value, false), onLikedChanged(news.id, value, false),
askForConfirmation: hasUnmarkConfirmation, askForConfirmation: hasUnmarkConfirmation,
likes: news.likes, likes: news.likes,
unlikedColor: const Color.fromARGB(255, 102, 102, 102), unlikedColor: Theme.of(context).colorScheme.caption,
), ),
const SizedBox( const SizedBox(
width: 4.0, width: 4.0,
@ -139,8 +140,8 @@ class NewsOverview extends StatelessWidget {
askForConfirmation: hasUnmarkConfirmation, askForConfirmation: hasUnmarkConfirmation,
svgIconOn: 'lib/assets/icons/bookmark_fill.svg', svgIconOn: 'lib/assets/icons/bookmark_fill.svg',
svgIconOff: 'lib/assets/icons/archive-tick.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), unbookmarkedColor: Theme.of(context).colorScheme.caption,
), ),
], ],
) )

View File

@ -160,7 +160,7 @@ class RadarOverview extends StatelessWidget {
onLikedChanged(radar.id, value, false), onLikedChanged(radar.id, value, false),
askForConfirmation: hasUnmarkConfirmation, askForConfirmation: hasUnmarkConfirmation,
likes: radar.likes, likes: radar.likes,
unlikedColor: const Color.fromARGB(255, 102, 102, 102), unlikedColor: Theme.of(context).colorScheme.caption,
), ),
const SizedBox( const SizedBox(
width: 4.0, width: 4.0,
@ -175,9 +175,9 @@ class RadarOverview extends StatelessWidget {
askForConfirmation: hasUnmarkConfirmation, askForConfirmation: hasUnmarkConfirmation,
svgIconOn: 'lib/assets/icons/bookmark_fill.svg', svgIconOn: 'lib/assets/icons/bookmark_fill.svg',
svgIconOff: 'lib/assets/icons/archive-tick.svg', svgIconOff: 'lib/assets/icons/archive-tick.svg',
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
unbookmarkedColor: unbookmarkedColor:
const Color.fromARGB(255, 102, 102, 102), Theme.of(context).colorScheme.caption,
), ),
], ],
), ),

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart'; import 'package:didvan/config/theme_data.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
@ -50,13 +51,15 @@ class _SearchFieldState extends State<SearchField> {
Expanded( Expanded(
child: Container( child: Container(
decoration: BoxDecoration( 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), borderRadius: BorderRadius.circular(40),
), ),
child: TextFormField( child: TextFormField(
initialValue: widget.value, initialValue: widget.value,
focusNode: widget.focusNode, focusNode: widget.focusNode,
style: Theme.of(context).textTheme.bodyMedium, style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color:Colors.black,
),
textAlignVertical: TextAlignVertical.center, textAlignVertical: TextAlignVertical.center,
onChanged: widget.onChanged, onChanged: widget.onChanged,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
@ -143,8 +146,8 @@ class _SearchFieldState extends State<SearchField> {
), ),
border: InputBorder.none, border: InputBorder.none,
hintText: 'جست‌وجو در ${widget.title}', hintText: 'جست‌وجو در ${widget.title}',
hintStyle: const TextStyle( hintStyle: TextStyle(
color: Color.fromARGB(255, 122, 122, 122), color: DesignConfig.isDark? const Color.fromARGB(255, 98, 98, 98) : const Color.fromARGB(255, 122, 122, 122),
fontSize: 13, fontSize: 13,
), ),
), ),

View File

@ -1,4 +1,5 @@
import 'package:didvan/config/design_config.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/app_icons.dart';
import 'package:didvan/models/tag.dart'; import 'package:didvan/models/tag.dart';
import 'package:didvan/routes/routes.dart'; import 'package:didvan/routes/routes.dart';
@ -44,14 +45,14 @@ class TagItem extends StatelessWidget {
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const Icon( Icon(
DidvanIcons.hashtag_regular, DidvanIcons.hashtag_regular,
color: Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
size: 17, size: 17,
), ),
DidvanText( DidvanText(
tag.label, tag.label,
color: const Color.fromARGB(255, 102, 102, 102), color: Theme.of(context).colorScheme.caption,
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500), style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
), ),
], ],

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/design_config.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class TextDivider extends StatelessWidget { class TextDivider extends StatelessWidget {
@ -37,7 +38,7 @@ class TextDivider extends StatelessWidget {
text, text,
style: textStyle ?? style: textStyle ??
Theme.of(context).textTheme.bodyLarge?.copyWith( 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, fontWeight: FontWeight.bold,
), ),
), ),