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

@ -226,4 +226,4 @@ extension DidvanColorScheme on ColorScheme {
Color get success => brightness == Brightness.dark
? const Color(0xFF2FC250)
: const Color(0xFF2BB24A);
}
}

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 mainPageContent = _baseHomeUrl;
static const String didvanPlus = '$baseUrl/didvanPlus';
static String searchAll({
required int page,
String? startDate,

View File

@ -90,4 +90,15 @@ extension StringUrl on String {
char; // Replace with English number if exists, else keep original char
}).join('');
}
String convertToPersianDigits() {
const english = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
const farsi = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
String text = this;
for (int i = 0; i < english.length; i++) {
text = text.replaceAll(english[i], farsi[i]);
}
return text;
}
}

View File

@ -425,10 +425,12 @@ class _AiChatPageState extends State<AiChatPage> with TickerProviderStateMixin {
),
);
},
child: const Text(
child: Text(
'چطور می‌تونم کمکت کنم؟',
style: TextStyle(
color: Color.fromARGB(255, 0, 53, 70),
color: DesignConfig.isDark
? const Color.fromARGB(255, 0, 90, 119)
: const Color.fromARGB(255, 0, 53, 70),
fontSize: 16,
fontWeight: FontWeight.bold,
),

View File

@ -94,13 +94,13 @@ class _HistoryAiChatPageState extends State<HistoryAiChatPage> {
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
Padding(
padding: EdgeInsets.all(8.0),
child: Text('فهرست آرشیوشده‌ها',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 0, 53, 70))),
color: DesignConfig.isDark? const Color.fromARGB(255, 0, 90, 119) : const Color.fromARGB(255, 0, 53, 70))),
),
// SearchField(
// title: 'گفت‌و‌گو‌ها',

View File

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

View File

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

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/models/ai/ai_chat_args.dart';
import 'package:didvan/models/ai/bots_model.dart';
@ -11,7 +12,6 @@ import 'package:provider/provider.dart';
import 'package:didvan/views/ai/history_ai_chat_state.dart';
import 'package:didvan/views/ai/ai_state.dart';
class AiSectionPage extends StatefulWidget {
const AiSectionPage({super.key});
@ -33,7 +33,8 @@ class _AiSectionGridItem {
});
}
class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateMixin {
class _AiSectionPageState extends State<AiSectionPage>
with TickerProviderStateMixin {
late final List<_AiSectionGridItem> _gridItems;
late AnimationController _fadeController;
late AnimationController _slideController;
@ -43,22 +44,22 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
@override
void initState() {
super.initState();
_fadeController = AnimationController(
duration: const Duration(milliseconds: 800),
vsync: this,
);
_fadeAnimation = CurvedAnimation(
parent: _fadeController,
curve: Curves.easeIn,
);
_slideController = AnimationController(
duration: const Duration(milliseconds: 1000),
vsync: this,
);
_slideAnimation = Tween<Offset>(
begin: const Offset(0, 0.3),
end: Offset.zero,
@ -66,7 +67,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
parent: _slideController,
curve: Curves.easeOutCubic,
));
_fadeController.forward();
_slideController.forward();
WidgetsBinding.instance.addPostFrameCallback((_) {
@ -77,11 +78,11 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
final aiState = context.read<AiState>();
final aiChatState = context.read<AiChatState>();
aiState.onClearChatCallback = () async {
await aiChatState.clearChat();
};
aiState.endChat();
if (aiState.tools == null) {
aiState.getTools();
@ -134,7 +135,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
onTap: (context) {
final aiState = context.read<AiState>();
aiState.endChat();
final aisummeryBot = BotsModel(
id: 100,
name: 'Aisummery',
@ -142,7 +143,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
attachmentType: ['pdf', 'image', 'audio'],
attachment: 1,
);
aiState.startChat(AiChatArgs(bot: aisummeryBot));
},
),
@ -153,7 +154,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
onTap: (context) {
final aiState = context.read<AiState>();
aiState.endChat();
final textToSpeechBot = BotsModel(
id: 101,
name: 'aiaudio',
@ -161,7 +162,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
attachmentType: [],
attachment: 0,
);
aiState.startChat(AiChatArgs(bot: textToSpeechBot));
},
),
@ -172,7 +173,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
onTap: (context) {
final aiState = context.read<AiState>();
aiState.endChat();
final chartAnalysisBot = BotsModel(
id: 27,
name: 'chart-analysis',
@ -180,7 +181,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
attachmentType: ['image', 'pdf'],
attachment: 1,
);
aiState.startChat(AiChatArgs(bot: chartAnalysisBot));
},
),
@ -191,7 +192,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
onTap: (context) {
final aiState = context.read<AiState>();
aiState.endChat();
final aiVideoBot = BotsModel(
id: 102,
name: 'aivideo',
@ -199,7 +200,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
attachmentType: [],
attachment: 0,
);
aiState.startChat(AiChatArgs(bot: aiVideoBot));
},
),
@ -219,8 +220,7 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
return Column(
children: [
if (!aiState.isChatting)
const HoshanHomeAppBar(),
if (!aiState.isChatting) const HoshanHomeAppBar(),
Expanded(
child: aiState.isChatting
? AiChatPage(args: aiState.currentChatArgs!)
@ -235,8 +235,11 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
padding: const EdgeInsets.all(20),
child: Row(
children: [
SvgPicture.asset('lib/assets/icons/clarity_tools-line.svg'),
const SizedBox(width: 8,),
SvgPicture.asset(
'lib/assets/icons/clarity_tools-line.svg'),
const SizedBox(
width: 8,
),
DidvanText(
'جعبه ابزار استراتژیک هوشان',
style: Theme.of(context).textTheme.titleMedium,
@ -307,14 +310,16 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
child: SizedBox(
width: 180,
height: 160,
child: _buildGridItemCard(context, _gridItems[columnIndex * 2]),
child: _buildGridItemCard(
context, _gridItems[columnIndex * 2]),
),
),
if (columnIndex * 2 + 1 < _gridItems.length)
Padding(
padding: const EdgeInsets.only(top: 16.0),
child: TweenAnimationBuilder<double>(
duration: Duration(milliseconds: 700 + (columnIndex * 100)),
duration:
Duration(milliseconds: 700 + (columnIndex * 100)),
tween: Tween(begin: 0.0, end: 1.0),
curve: Curves.easeOut,
builder: (context, value, child) {
@ -329,7 +334,8 @@ class _AiSectionPageState extends State<AiSectionPage> with TickerProviderStateM
child: SizedBox(
width: 180,
height: 160,
child: _buildGridItemCard(context, _gridItems[columnIndex * 2 + 1]),
child: _buildGridItemCard(
context, _gridItems[columnIndex * 2 + 1]),
),
),
),
@ -381,10 +387,12 @@ class _AnimatedGridCardState extends State<_AnimatedGridCard> {
transform: Matrix4.identity()
..translate(0.0, _isHovered ? -8.0 : 0.0),
decoration: BoxDecoration(
color: const Color.fromARGB(255, 245, 245, 245),
color: DesignConfig.isDark
? const Color.fromARGB(255, 78, 82, 84)
: const Color.fromARGB(255, 245, 245, 245),
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: _isHovered
color: _isHovered
? const Color.fromARGB(255, 0, 126, 167)
: const Color.fromARGB(255, 184, 184, 184),
width: _isHovered ? 2 : 1,
@ -426,7 +434,7 @@ class _AnimatedGridCardState extends State<_AnimatedGridCard> {
),
),
),
const SizedBox(height: 8),
const SizedBox(height: 8),
DidvanText(
widget.item.title,
style: Theme.of(context).textTheme.titleSmall,
@ -452,4 +460,4 @@ class _AnimatedGridCardState extends State<_AnimatedGridCard> {
),
);
}
}
}

View File

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

View File

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

View File

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

View File

@ -2,9 +2,16 @@
import 'dart:async';
// START: Added Imports
import 'package:flutter/gestures.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:url_launcher/url_launcher_string.dart';
// END: Added Imports
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/providers/user.dart';
import 'package:didvan/utils/extension.dart';
import 'package:didvan/views/authentication/authentication_state.dart';
import 'package:didvan/views/authentication/widgets/authentication_layout.dart';
import 'package:didvan/views/widgets/didvan/button.dart';
@ -27,6 +34,12 @@ class _VerificationState extends State<Verification> {
int _secondsRemaining = 119;
bool _isResendButtonEnabled = false;
bool _isConfirmButtonEnabled = false;
String _completedCode = "";
// START: Added state for error
bool _hasError = false;
// END: Added state
@override
void initState() {
@ -43,7 +56,7 @@ class _VerificationState extends State<Verification> {
super.initState();
_listenForSms();
}
Future<void> _listenForSms() async {
if (kDebugMode) {
print("<<<<< در حال تلاش برای دریافت امضای برنامه >>>>>");
@ -56,39 +69,84 @@ class _VerificationState extends State<Verification> {
}
await SmsAutoFill().listenForCode();
}
}
@override
Widget build(BuildContext context) {
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(
onWillPop: () async {
_timer?.cancel();
return true;
// منطق بازگشت هماهنگ با authentication.dart
if (state.currentPageIndex == 0) {
return true;
}
if (state.currentPageIndex == 2 && !state.hasPassword) {
state.currentPageIndex = 0; // برگرد به صفحه نام کاربری
return false;
}
state.currentPageIndex--; // در غیر این صورت یکی برگرد
return false;
},
child: AuthenticationLayout(
appBarTitle: 'تغییر رمز عبور',
children: [
DidvanText(
'کد 6 رقمی ارسال شده به موبایل',
style: Theme.of(context).textTheme.titleSmall,
fontWeight: FontWeight.normal,
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
DidvanText('کد تایید پنج رقمی به شماره ',
style: Theme.of(context).textTheme.titleSmall,
fontWeight: FontWeight.normal,
color: Theme.of(context).colorScheme.caption),
DidvanText(
state.username.toString().convertToPersianDigits(),
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.normal,
fontSize: 15,
color: Theme.of(context).colorScheme.caption),
),
DidvanText(' ارسال شد.',
style: Theme.of(context).textTheme.titleSmall,
fontWeight: FontWeight.normal,
color: Theme.of(context).colorScheme.caption),
],
),
const SizedBox(
height: 8,
),
DidvanText(
state.username,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(
height: 8,
),
DidvanText(
'را وارد کنید:',
style: Theme.of(context).textTheme.titleSmall,
fontWeight: FontWeight.normal,
const SizedBox(height: 8),
InkWell(
onTap: () {
_timer?.cancel(); // لغو تایمر
state.currentPageIndex = 0; // بازگشت به صفحه ورود شماره
},
borderRadius: DesignConfig.lowBorderRadius,
child: Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset('lib/assets/icons/pen.svg',height: 20,),
const SizedBox(width: 8),
DidvanText(
'شماره همراه',
style: Theme.of(context).textTheme.titleSmall,
fontWeight: FontWeight.normal,
color: primaryColor,
),
],
),
),
),
const SizedBox(
height: 24,
@ -98,43 +156,154 @@ class _VerificationState extends State<Verification> {
child: PinCodeTextField(
keyboardType: TextInputType.number,
animationType: AnimationType.scale,
cursorColor: Theme.of(context).colorScheme.text,
cursorColor: textColor,
// START: Added textStyle for error color
textStyle: TextStyle(
fontSize: 20, // اندازه فونت را متناسب تنظیم کنید
color: _hasError ? const Color.fromARGB(255, 178, 4, 54) : textColor,
),
// END: Added textStyle
pinTheme: PinTheme(
fieldHeight: 48,
fieldWidth: 48,
selectedColor: Theme.of(context).colorScheme.primary,
inactiveColor: Theme.of(context).colorScheme.border,
activeFillColor: Theme.of(context).colorScheme.primary,
activeColor: Theme.of(context).colorScheme.primary,
fieldHeight: 58,
fieldWidth: 58,
// START: Dynamic border/bg colors
selectedColor: _hasError ? const Color.fromARGB(255, 178, 4, 54) : primaryColor,
inactiveColor: _hasError ? const Color.fromARGB(255, 178, 4, 54) : borderColor,
activeFillColor: _hasError ? const Color.fromARGB(255, 178, 4, 54) : primaryColor, // بستگی به طراحی شما دارد
activeColor: _hasError ? const Color.fromARGB(255, 178, 4, 54) : primaryColor,
// END: Dynamic colors
borderRadius: DesignConfig.lowBorderRadius,
borderWidth: 1,
shape: PinCodeFieldShape.box,
),
appContext: context,
length: 6,
// START: Modified onCompleted
onCompleted: (value) async {
final result = await state.verifyOtpToken(value);
if (result) {
_timer?.cancel();
}
},
onChanged: (value) {},
// END: Modified onCompleted
// START: Modified onChanged
onChanged: (value) {
setState(() {
_completedCode = value;
_isConfirmButtonEnabled = value.length == 6;
if (_hasError) {
_hasError = false; // پاک کردن خطا با شروع تایپ
}
});
},
// END: Modified onChanged
),
),
const Spacer(),
// ویجت ارسال مجدد کد
const SizedBox(
height: 24,
),
_isResendButtonEnabled
? InkWell(
onTap: () {
_handleTimer(); // ریاستارت تایمر
state.sendOtpToken(); // ارسال مجدد کد
},
borderRadius: DesignConfig.lowBorderRadius,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0, vertical: 4.0),
child: DidvanText(
'دریافت مجدد کد',
style: Theme.of(context).textTheme.titleSmall,
fontWeight: FontWeight.normal,
color: const Color.fromARGB(255, 0 ,126, 167),
),
),
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset('lib/assets/icons/clock.svg',color: const Color.fromARGB(255, 0 ,126, 167) ,),
const SizedBox(width: 5,),
DidvanText(
'$_secondsRemaining ثانیه',
style: Theme.of(context).textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.normal,
color: const Color.fromARGB(255, 0 ,126, 167),
),
),
DidvanText(
' تا دریافت مجدد کد',
style: Theme.of(context).textTheme.titleSmall,
fontWeight: FontWeight.normal,
color: const Color.fromARGB(255, 0 ,126, 167),
),
],
),
const Spacer(), // دکمه را به پایین صفحه میچسباند
DidvanButton(
enabled: _isResendButtonEnabled,
onPressed: () {
_handleTimer();
state.sendOtpToken();
enabled: _isConfirmButtonEnabled,
// START: Modified onPressed
onPressed: () async {
if (_completedCode.length == 6) {
final result = await state.verifyOtpToken(_completedCode);
if (!result) {
if (mounted) setState(() => _hasError = true);
}
// در صورت موفقیت، onCompleted خودش کار را انجام میدهد
}
},
title: !_isResendButtonEnabled
? '$_secondsRemaining ثانیه دیگر'
: 'ارسال مجدد کد',
// END: Modified onPressed
title: 'تایید کد',
),
// START: Added Terms and Conditions RichText
const SizedBox(
height: 24, // فاصله بین دکمه و متن قوانین
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 60),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: Theme.of(context).textTheme.bodySmall,
children: [
const TextSpan(text: 'با ورود به اپلیکیشن دیدوان،'),
TextSpan(
text: ' شرایط ',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Theme.of(context).colorScheme.primary),
recognizer: TapGestureRecognizer()
..onTap = () => launchUrlString(
'https://didvan.com/terms-of-use#conditions',
mode: LaunchMode.inAppWebView),
),
const TextSpan(text: 'و\n'),
TextSpan(
text: ' قوانین حریم خصوصی ',
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: Theme.of(context).colorScheme.primary),
recognizer: TapGestureRecognizer()
..onTap = () => launchUrlString(
'https://didvan.com/terms-of-use#privacy',
mode: LaunchMode.inAppWebView),
),
const TextSpan(text: 'را می‌پذیرم'),
],
),
),
),
const SizedBox(
height: 48,
height: 24, // پدینگ نهایی پایین صفحه
),
// END: Added RichText
],
),
);
@ -159,4 +328,4 @@ class _VerificationState extends State<Verification> {
});
setState(() {});
}
}
}

View File

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

View File

@ -94,10 +94,10 @@ class CommentState extends State<Comment> {
children: [
DidvanText(
comment.user.fullName,
style: const TextStyle(
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
color: Color.fromARGB(255, 102, 102, 102)),
color: Theme.of(context).colorScheme.caption),
),
const SizedBox(height: 4),
DidvanText(
@ -122,7 +122,7 @@ class CommentState extends State<Comment> {
const SizedBox(height: 8),
DidvanText(
comment.text,
color: const Color.fromARGB(255, 102, 102, 102),
color: Theme.of(context).colorScheme.caption,
),
const SizedBox(height: 8),
if (comment.status == 2)
@ -180,7 +180,7 @@ class CommentState extends State<Comment> {
child: DidvanText(
'پاسخ',
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
import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/constants/assets.dart';
import 'package:didvan/models/enums.dart';
@ -137,7 +139,7 @@ class _DirectState extends State<Direct> {
.textTheme
.headlineSmall
?.copyWith(
color: const Color.fromARGB(255, 0, 53, 70),
color: DesignConfig.isDark? const Color.fromARGB(255, 0, 90, 119) : const Color.fromARGB(255, 0, 53, 70),
fontWeight: FontWeight.bold,
fontSize: 19),
),
@ -148,8 +150,8 @@ class _DirectState extends State<Direct> {
'lib/assets/icons/arrow-left.svg',
width: 30,
height: 30,
colorFilter: const ColorFilter.mode(
Color.fromARGB(255, 102, 102, 102),
colorFilter: ColorFilter.mode(
Theme.of(context).colorScheme.caption,
BlendMode.srcIn),
),
),

View File

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

View File

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

View File

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

View File

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

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

View File

@ -75,9 +75,11 @@ class _HomeState extends State<Home>
Widget build(BuildContext context) {
return Scaffold(
key: homeScaffKey,
// ignore: deprecated_member_use
backgroundColor: Theme.of(context).colorScheme.background,
resizeToAvoidBottomInset: false,
drawer: null,
// ignore: deprecated_member_use
body: WillPopScope(
onWillPop: () async {
if (context.read<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/models/home_page_content/content.dart';
import 'package:didvan/models/home_page_content/home_page_list.dart';
import 'package:didvan/models/home_page_content/swot.dart';
import 'package:didvan/services/app_initalizer.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/views/home/explore/explore.dart';
import 'package:didvan/views/home/main/main_page_state.dart';
import 'package:didvan/views/home/main/widgets/main_content.dart';
import 'package:didvan/views/home/main/widgets/story_section.dart';
import 'package:didvan/views/home/main/widgets/simple_explore_card.dart';
import 'package:didvan/views/home/main/widgets/didvan_plus_section.dart';
import 'package:didvan/views/home/new_statistic/new_statistics_state.dart';
import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
@ -18,6 +23,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:flutter/foundation.dart' show kIsWeb, defaultTargetPlatform;
@ -74,14 +80,20 @@ class _MainPageState extends State<MainPage> {
const TextDivider(text: 'دیده‌بان')
.animate()
.fadeIn(delay: 400.ms, duration: 500.ms),
// const _DidvanSignalsTitle()
// .animate()
// .fadeIn(delay: 500.ms, duration: 500.ms),
const _DidvanSignalsTitle()
.animate()
.fadeIn(delay: 500.ms, duration: 500.ms),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: StorySection(stories: state.stories),
).animate().fadeIn(delay: 600.ms, duration: 500.ms),
],
if (state.didvanPlus != null) ...[
const SizedBox(height: 16),
DidvanPlusSection(didvanPlus: state.didvanPlus!)
.animate()
.fadeIn(delay: 650.ms, duration: 500.ms),
],
const SizedBox(height: 12),
const TextDivider(text: 'پیشخوان استراتژیک')
.animate()
@ -120,38 +132,38 @@ class _MainPageState extends State<MainPage> {
}
}
// class _DidvanSignalsTitle extends StatelessWidget {
// const _DidvanSignalsTitle();
class _DidvanSignalsTitle extends StatelessWidget {
const _DidvanSignalsTitle();
// @override
// Widget build(BuildContext context) {
// return Padding(
// padding: const EdgeInsets.only(
// left: 16,
// right: 16,
// bottom: 16,
// top: 0,
// ),
// child: Row(
// children: [
// SvgPicture.asset(
// 'lib/assets/icons/voice-square.svg',
// color: Theme.of(context).colorScheme.title,
// width: 30,
// height: 30,
// ),
// const SizedBox(width: 5),
// DidvanText(
// "سیگنال‌های دیدوان",
// style: Theme.of(context).textTheme.titleMedium,
// color: const Color.fromARGB(255, 0, 89, 119),
// fontSize: 13,
// ),
// ],
// ),
// );
// }
// }
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
bottom: 16,
top: 0,
),
child: Row(
children: [
SvgPicture.asset(
'lib/assets/icons/voice-square.svg',
color: Theme.of(context).colorScheme.title,
width: 30,
height: 30,
),
const SizedBox(width: 5),
DidvanText(
"سیگنال‌های دیدوان",
style: Theme.of(context).textTheme.titleMedium,
color: const Color.fromARGB(255, 0, 89, 119),
fontSize: 13,
),
],
),
);
}
}
class _ExploreLatestTitle extends StatelessWidget {
const _ExploreLatestTitle();
@ -180,7 +192,7 @@ class _ExploreLatestTitle extends StatelessWidget {
DidvanText(
"تازه‌ترین‌های کاوش",
style: Theme.of(context).textTheme.titleMedium,
color: const Color.fromARGB(255, 0, 89, 119),
color: DesignConfig.isDark ? const Color.fromARGB(255, 0, 125, 166) : const Color.fromARGB(255, 0, 89, 119),
fontSize: 13,
),
],
@ -215,6 +227,8 @@ class _ExploreLatestSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
final List<Widget> items = [];
final List<({String type, MainPageContentType? content, SwotItem? swotItem})> itemsData = [];
for (var list in lists) {
if (list.type == 'video' ||
list.type == 'podcast' ||
@ -233,6 +247,7 @@ class _ExploreLatestSlider extends StatelessWidget {
),
),
);
itemsData.add((type: list.type, content: newestContent, swotItem: null));
}
}
@ -245,6 +260,7 @@ class _ExploreLatestSlider extends StatelessWidget {
),
),
);
itemsData.add((type: 'swot', content: null, swotItem: swotItems.first));
}
if (items.isEmpty) {
@ -259,6 +275,23 @@ class _ExploreLatestSlider extends StatelessWidget {
onItemChanged: (index) {
// Optional: Handle item change if needed
},
onItemTap: (index) {
final data = itemsData[index];
if (data.swotItem != null) {
AppInitializer.openWebLink(
context,
'http://opportunity-threat.didvan.com/posts/${data.swotItem!.id}/?accessToken=${RequestService.token}',
mode: LaunchMode.inAppWebView,
);
} else if (data.content != null) {
context.read<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/models/didvan_plus_model.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/home_page_content/content.dart';
import 'package:didvan/models/home_page_content/home_page_content.dart';
@ -22,6 +23,7 @@ class MainPageState extends CoreProvier {
int unread = 0;
List<UserStories> stories = [];
List<SwotItem> swotItems = [];
DidvanPlusModel? didvanPlus;
Future<void> _getMainPageContent() async {
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 {
try {
stories = await StoryService.getStories();
@ -60,7 +85,7 @@ class MainPageState extends CoreProvier {
}
void init() {
print("DEBUG: MainPageState init called");
debugPrint("🏠 MainPageState init called");
Future.delayed(Duration.zero, () async {
appState = AppState.busy;
try {
@ -68,9 +93,12 @@ class MainPageState extends CoreProvier {
_getMainPageContent(),
_fetchStories(),
_getSwotItems(),
_getDidvanPlus(),
]);
debugPrint("✅ All main page data loaded");
appState = AppState.idle;
} catch (e) {
debugPrint("❌ Main page init failed: $e");
appState = AppState.failed;
}
});
@ -139,6 +167,17 @@ class MainPageState extends CoreProvier {
};
break;
}
case 'monthly':
{
Navigator.of(navigatorKey.currentContext!).pushNamed(
Routes.pdfViewer,
arguments: {
'pdfUrl': link,
'title': description ?? 'ماهنامه تحلیلی دیدوان',
},
);
return;
}
}
if (link == '') {
return;

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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/providers/user.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),
));
_fadeAnimation = Tween<double>(
begin: 0.0,
end: 1.0,
@ -136,7 +137,7 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
key: _formKey,
child: DidvanScaffold(
padding: const EdgeInsets.only(
top: 16,
top: 0,
left: 0,
right: 0,
),
@ -169,10 +170,14 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
opacity: _buttonFadeAnimation,
child: IconButton(
onPressed: () {
Navigator.of(context).pushNamed(Routes.bookmarks);
Navigator.of(context)
.pushNamed(Routes.bookmarks);
},
icon: SvgPicture.asset(
'lib/assets/icons/hugeicons_telescope-01.svg')),
'lib/assets/icons/hugeicons_telescope-01.svg',
color: DesignConfig.isDark
? Theme.of(context).colorScheme.caption
: null)),
),
),
SlideTransition(
@ -183,7 +188,7 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
onPressed: () => Navigator.of(context).pop(),
icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg',
color: const Color.fromARGB(255, 102, 102, 102),
color: Theme.of(context).colorScheme.caption,
),
),
),
@ -219,10 +224,9 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
.textTheme
.headlineSmall
?.copyWith(
fontWeight: FontWeight.bold,
fontSize: 18
),
textAlign: TextAlign.start,
fontWeight: FontWeight.bold,
fontSize: 18),
textAlign: TextAlign.start,
),
),
],
@ -230,7 +234,9 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
),
),
),
const SizedBox(height: 5,),
const SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: Column(
@ -374,11 +380,11 @@ class _NewPasswordScreenState extends State<NewPasswordScreen>
final changePasswordState =
context.read<ChangePasswordState>();
changePasswordState.newPassword = _newPassword;
final userProvider = context.read<UserProvider>();
final success =
await changePasswordState.changePassword(userProvider);
final success = await changePasswordState
.changePassword(userProvider);
if (success && mounted) {
Navigator.of(context).pushNamedAndRemoveUntil(
Routes.profile,

View File

@ -1,8 +1,12 @@
// ignore_for_file: deprecated_member_use
import 'dart:async';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/assets.dart';
import 'package:didvan/config/design_config.dart';
import 'package:didvan/providers/user.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/utils/extension.dart';
import 'package:didvan/views/profile/change_password/change_password_state.dart';
import 'package:didvan/views/widgets/didvan/button.dart';
import 'package:didvan/views/widgets/didvan/scaffold.dart';
@ -170,7 +174,7 @@ class _VerifyOtpScreenState extends State<VerifyOtpScreen>
padding: const EdgeInsets.only(bottom: 150),
child: DidvanScaffold(
padding: const EdgeInsets.only(
top: 16,
top: 0,
left: 0,
right: 0,
),
@ -202,11 +206,15 @@ class _VerifyOtpScreenState extends State<VerifyOtpScreen>
child: FadeTransition(
opacity: _buttonFadeAnimation,
child: IconButton(
onPressed: () {
Navigator.of(context).pushNamed(Routes.bookmarks);
},
icon: SvgPicture.asset(
'lib/assets/icons/hugeicons_telescope-01.svg')),
onPressed: () {
Navigator.of(context).pushNamed(Routes.bookmarks);
},
icon: SvgPicture.asset(
'lib/assets/icons/hugeicons_telescope-01.svg',
color: DesignConfig.isDark
? Theme.of(context).colorScheme.caption
: null),
),
),
),
SlideTransition(
@ -217,7 +225,7 @@ class _VerifyOtpScreenState extends State<VerifyOtpScreen>
onPressed: () => Navigator.of(context).pop(),
icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg',
color: const Color.fromARGB(255, 102, 102, 102),
color: Theme.of(context).colorScheme.caption,
),
),
),
@ -270,7 +278,7 @@ class _VerifyOtpScreenState extends State<VerifyOtpScreen>
const TextSpan(
text: 'ما یک کد تأیید 6 رقمی به شماره '),
TextSpan(
text: phoneNumber,
text: phoneNumber.convertToPersianDigits(),
style: TextStyle(
color:
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/models/enums.dart';
import 'package:didvan/routes/routes.dart';
@ -105,12 +109,16 @@ class _DirectListState extends State<DirectList>
Navigator.of(context).pushNamed(Routes.bookmarks);
},
icon: SvgPicture.asset(
'lib/assets/icons/hugeicons_telescope-01.svg')),
'lib/assets/icons/hugeicons_telescope-01.svg',
color: DesignConfig.isDark
? Theme.of(context).colorScheme.caption
: null,
)),
IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: SvgPicture.asset(
'lib/assets/icons/arrow-left.svg',
color: const Color.fromARGB(255, 102, 102, 102),
color: Theme.of(context).colorScheme.caption,
)),
const SizedBox(width: 8),
],

View File

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

View File

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

View File

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

View File

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

View File

@ -1,16 +1,17 @@
// ignore_for_file: deprecated_member_use
import 'dart:async';
import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class Carousel3D extends StatefulWidget {
final List<Widget> items;
final double height;
final Duration autoPlayDuration;
final Function(int)? onItemChanged;
final bool showControls;
final void Function(int index)? onItemTap;
const Carousel3D({
super.key,
@ -19,17 +20,23 @@ class Carousel3D extends StatefulWidget {
this.autoPlayDuration = const Duration(seconds: 4),
this.onItemChanged,
this.showControls = true,
this.onItemTap,
});
@override
State<Carousel3D> createState() => _Carousel3DState();
}
class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateMixin {
class _Carousel3DState extends State<Carousel3D>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
Timer? _autoPlayTimer;
int _currentIndex = 0;
int _targetIndex = 0;
double _dragDelta = 0.0;
static const double _dragDistanceToComplete = 120.0;
static const double _dragDistanceThreshold = 20.0; // was 40
static const double _dragVelocityThreshold = 150.0; // was 300
@override
void initState() {
@ -75,7 +82,6 @@ class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateM
_goToIndex((_currentIndex - 1 + widget.items.length) % widget.items.length);
}
@override
void dispose() {
_autoPlayTimer?.cancel();
@ -89,87 +95,180 @@ class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateM
return Column(
children: [
SizedBox(
height: widget.height,
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Stack(
alignment: Alignment.center,
children: List.generate(widget.items.length, (index) {
final double currentRelativePos = (index - _currentIndex).toDouble();
final double targetRelativePos = (index - _targetIndex).toDouble();
final double relativePos = Tween<double>(
begin: currentRelativePos,
end: targetRelativePos,
).transform(CurvedAnimation(parent: _controller, curve: Curves.easeInOutCubic).value);
GestureDetector(
behavior: HitTestBehavior.opaque,
onHorizontalDragStart: (_) {
_autoPlayTimer?.cancel();
_dragDelta = 0.0;
_controller.stop();
_controller.value = 0.0;
},
onHorizontalDragUpdate: (details) {
_dragDelta += details.delta.dx;
final len = widget.items.length;
final bool dragLeft = _dragDelta < 0;
final int newTarget = dragLeft
? (_currentIndex - 1 + len) % len
: (_currentIndex + 1) % len;
if (newTarget != _targetIndex) {
setState(() => _targetIndex = newTarget);
}
final double progress =
(_dragDelta.abs() / _dragDistanceToComplete).clamp(0.0, 1.0);
_controller.value = progress;
},
onHorizontalDragEnd: (details) {
final velocity = details.primaryVelocity ?? 0.0;
final bool commit = velocity.abs() > _dragVelocityThreshold ||
_dragDelta.abs() > _dragDistanceThreshold;
final bool isGrayscale = relativePos != 0;
final double absRelativePos = relativePos.abs();
if (commit) {
_controller
.animateTo(1.0,
duration: const Duration(milliseconds: 150),
curve: Curves.easeOut)
.then((_) {
setState(() {
_currentIndex = _targetIndex;
});
widget.onItemChanged?.call(_currentIndex);
_controller.value = 0.0;
_dragDelta = 0.0;
_startAutoPlay();
});
} else {
setState(() {
_targetIndex = _currentIndex;
});
_controller
.animateBack(0.0,
duration: const Duration(milliseconds: 150),
curve: Curves.easeOut)
.then((_) {
_dragDelta = 0.0;
_startAutoPlay();
});
}
},
child: SizedBox(
height: widget.height,
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Stack(
alignment: Alignment.center,
children: List.generate(widget.items.length, (index) {
final int len = widget.items.length;
final int half = len ~/ 2;
final double scale = (1 - (absRelativePos * 0.15)).clamp(0.0, 1.0);
final double translateX = relativePos * -30.0;
final double translateZ = absRelativePos * -100.0;
final double opacity = (1 - (absRelativePos * 0.3)).clamp(0.0, 1.0);
int circularDelta(int i, int center) {
int raw = i - center;
if (raw > half) raw -= len;
if (raw < -half) raw += len;
return raw;
}
Matrix4 transform = Matrix4.identity()
..setEntry(3, 2, 0.001)
..translate(translateX, 0.0, translateZ)
..scale(scale);
final double currentRelativePos =
circularDelta(index, _currentIndex).toDouble();
final double targetRelativePos =
circularDelta(index, _targetIndex).toDouble();
final double relativePos = Tween<double>(
begin: currentRelativePos,
end: targetRelativePos,
).transform(CurvedAnimation(
parent: _controller, curve: Curves.easeInOutCubic)
.value);
return Transform(
transform: transform,
alignment: Alignment.center,
child: Opacity(
opacity: opacity,
child: GestureDetector(
onTap: () {
if (relativePos != 0) {
_goToIndex(index);
}
},
child: Container(
width: screenWidth * 0.7,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(isGrayscale ? 0.1 : 0.25),
spreadRadius: 2,
blurRadius: 10,
offset: const Offset(0, 5),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: ColorFiltered(
colorFilter: isGrayscale
? const ColorFilter.matrix([
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0.2126, 0.7152, 0.0722, 0, 0,
0, 0, 0, 1, 0,
])
: const ColorFilter.mode(
Colors.transparent,
BlendMode.multiply,
),
child: widget.items[index],
),
),
),
final bool isGrayscale = relativePos != 0;
final double absRelativePos = relativePos.abs();
final double scale =
(1 - (absRelativePos * 0.15)).clamp(0.0, 1.0);
final double translateX = relativePos * -30.0;
final double translateZ = absRelativePos * -100.0;
final double opacity =
(1 - (absRelativePos * 0.3)).clamp(0.0, 1.0);
Matrix4 transform = Matrix4.identity()
..setEntry(3, 2, 0.001)
..translate(translateX, 0.0, translateZ)
..scale(scale);
return Transform(
transform: transform,
alignment: Alignment.center,
child: Opacity(
opacity: opacity,
child: IgnorePointer(
ignoring: relativePos != 0,
child: GestureDetector(
onTap: relativePos == 0
? () => widget.onItemTap?.call(index)
: null,
child: Container(
width: screenWidth * 0.7,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black
.withOpacity(isGrayscale ? 0.1 : 0.25),
spreadRadius: 2,
blurRadius: 10,
offset: const Offset(0, 5),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(12),
child: ColorFiltered(
colorFilter: isGrayscale
? const ColorFilter.matrix([
0.2126,
0.7152,
0.0722,
0,
0,
0.2126,
0.7152,
0.0722,
0,
0,
0.2126,
0.7152,
0.0722,
0,
0,
0,
0,
0,
1,
0,
])
: const ColorFilter.mode(
Colors.transparent,
BlendMode.multiply,
),
child: widget.items[index],
),
),
),
),
),
),
),
);
}).toList()
..sort((a, b) {
final transformA = a.transform;
final transformB = b.transform;
return transformA.getTranslation().z.compareTo(transformB.getTranslation().z);
}),
);
},
);
}).toList()
..sort((a, b) {
final transformA = a.transform;
final transformB = b.transform;
return transformA
.getTranslation()
.z
.compareTo(transformB.getTranslation().z);
}),
);
},
),
),
),
if (widget.showControls) ...[
@ -212,4 +311,4 @@ class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateM
],
);
}
}
}

View File

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

View File

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

View File

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

View File

@ -199,7 +199,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
Color _borderColor() {
if (_focusNode.hasFocus) {
return const Color.fromARGB(255, 102, 102, 102);
return Theme.of(context).colorScheme.caption;
} else if (_error != null) {
return Theme.of(context).colorScheme.error;
}
@ -213,7 +213,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
if (_error != null) {
return Theme.of(context).colorScheme.error;
}
return const Color.fromARGB(255, 102, 102, 102);
return Theme.of(context).colorScheme.caption;
}
Color _fillColor() {
@ -247,6 +247,9 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
_hideContent
? 'lib/assets/icons/eye.svg'
: 'lib/assets/icons/eye-slash.svg',
color: DesignConfig.isDark
? Theme.of(context).colorScheme.caption
: null,
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/assets.dart';
import 'package:didvan/views/ai/history_ai_chat_state.dart';
@ -19,6 +20,7 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).colorScheme.surface,
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -80,6 +82,7 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
padding: const EdgeInsets.all(8),
child: SvgPicture.asset(
'lib/assets/icons/history.svg',
color: Theme.of(context).colorScheme.inputText,
height: 24,
),
),
@ -90,6 +93,7 @@ class HoshanAppBar extends StatelessWidget implements PreferredSizeWidget {
if (withInfo)
DidvanIconButton(
icon: DidvanIcons.angle_left_light,
color: Theme.of(context).colorScheme.inputText,
size: 32,
onPressed: () => onBack?.call(),
),

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,4 @@
import 'package:didvan/config/design_config.dart';
import 'package:flutter/material.dart';
class TextDivider extends StatelessWidget {
@ -37,7 +38,7 @@ class TextDivider extends StatelessWidget {
text,
style: textStyle ??
Theme.of(context).textTheme.bodyLarge?.copyWith(
color: const Color.fromARGB(255, 0, 53, 70),
color: DesignConfig.isDark? const Color.fromARGB(255, 0, 90, 119) : const Color.fromARGB(255, 0, 53, 70),
fontWeight: FontWeight.bold,
),
),