dev/fix-news #2

Merged
Mr.Jebelli merged 8 commits from dev/fix-news into master 2025-07-16 11:59:01 +00:00
8 changed files with 239 additions and 181 deletions
Showing only changes of commit f14be3879d - Show all commits

View File

@ -142,9 +142,10 @@ class _HomeState extends State<Home>
@override @override
void initState() { void initState() {
if (widget.showDialogs ?? false) { // Remove dialog showing logic to prevent welcome popups
_showDialog(context); // if (widget.showDialogs ?? false) {
} // _showDialog(context);
// }
final state = context.read<HomeState>(); final state = context.read<HomeState>();
DesignConfig.updateSystemUiOverlayStyle(); DesignConfig.updateSystemUiOverlayStyle();

View File

@ -42,7 +42,8 @@ class _NewsDetailsState extends State<NewsDetails> {
return Scaffold( return Scaffold(
body: Consumer<NewsDetailsState>( body: Consumer<NewsDetailsState>(
builder: (context, state, child) => StateHandler<NewsDetailsState>( builder: (context, state, child) => StateHandler<NewsDetailsState>(
onRetry: () => state.getNewsDetails(state.currentNews.id), onRetry: () =>
state.getNewsDetails(widget.pageData['id']),
state: state, state: state,
builder: (context, state) => Stack( builder: (context, state) => Stack(
children: [ children: [

View File

@ -1,5 +1,3 @@
// lib/views/news/news_details/news_details_state.dart
import 'dart:async'; import 'dart:async';
import 'dart:math'; import 'dart:math';
@ -10,8 +8,6 @@ import 'package:didvan/models/requests/news.dart';
import 'package:didvan/providers/core.dart'; import 'package:didvan/providers/core.dart';
import 'package:didvan/services/network/request.dart'; import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart'; import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/services/storage/storage.dart';
import 'package:flutter/material.dart';
class NewsDetailsState extends CoreProvier { class NewsDetailsState extends CoreProvier {
final List<NewsDetailsData?> news = []; final List<NewsDetailsData?> news = [];
@ -21,6 +17,7 @@ class NewsDetailsState extends CoreProvier {
int _trackingTimerCounter = 0; int _trackingTimerCounter = 0;
bool isFetchingNewItem = false; bool isFetchingNewItem = false;
final List<int> relatedQueue = []; final List<int> relatedQueue = [];
bool _isRequestInProgress = false;
int _currentIndex = 0; int _currentIndex = 0;
int get currentIndex => _currentIndex; int get currentIndex => _currentIndex;
@ -29,27 +26,33 @@ class NewsDetailsState extends CoreProvier {
NewsDetailsData get currentNews => news[_currentIndex]!; NewsDetailsData get currentNews => news[_currentIndex]!;
Future<void> getNewsDetails(int id, {bool? isForward}) async { Future<void> getNewsDetails(int id, {bool? isForward}) async {
debugPrint('requset token ${RequestService.token}'); // Prevent duplicate requests
// **FIX: Ensure the token is available before making a request.** if (_isRequestInProgress) {
if (RequestService.token == null) {
final token = await StorageService.getValue(key: 'token');
if (token != null) {
RequestService.token = token;
} else {
// If no token, fail gracefully. You might want to navigate
// to the login screen here in a real-world scenario.
appState = AppState.failed;
notifyListeners();
return; return;
} }
} _isRequestInProgress = true;
// Set loading state
if (isForward == null) {
appState = AppState.busy;
} else {
isFetchingNewItem = true; isFetchingNewItem = true;
notifyListeners(); notifyListeners();
}
try {
// Wait for token to be ready
if (RequestService.token == null || RequestService.token!.isEmpty) {
await Future.delayed(const Duration(milliseconds: 500));
if (RequestService.token == null || RequestService.token!.isEmpty) {
throw Exception('Token not available');
}
}
final service = RequestService(RequestHelper.newsDetails(id, args)); final service = RequestService(RequestHelper.newsDetails(id, args));
await service.httpGet(); await service.httpGet();
_handleTracking(sendRequest: isForward != null); _handleTracking(sendRequest: isForward != null);
if (service.isSuccess) { if (service.isSuccess) {
final result = service.result; final result = service.result;
final newsItem = NewsDetailsData.fromJson(result['news']); final newsItem = NewsDetailsData.fromJson(result['news']);
@ -57,7 +60,8 @@ class NewsDetailsState extends CoreProvier {
news.add(newsItem); news.add(newsItem);
initialIndex = 0; initialIndex = 0;
appState = AppState.idle; appState = AppState.idle;
notifyListeners(); // Notify listeners after state change isFetchingNewItem = false;
_isRequestInProgress = false;
return; return;
} }
NewsDetailsData? prevNews; NewsDetailsData? prevNews;
@ -94,12 +98,24 @@ class NewsDetailsState extends CoreProvier {
getRelatedContents(); getRelatedContents();
} }
appState = AppState.idle; appState = AppState.idle;
notifyListeners(); // Notify listeners after state change } else {
return; isFetchingNewItem = false;
} if (isForward == null) {
appState = AppState.failed; appState = AppState.failed;
notifyListeners(); // Notify listeners on failure } else {
notifyListeners();
}
}
} catch (e) {
print('Error fetching news details: $e');
isFetchingNewItem = false;
if (isForward == null) {
appState = AppState.failed;
}
notifyListeners();
} finally {
_isRequestInProgress = false;
}
} }
bool exists(NewsDetailsData? newsItem) => bool exists(NewsDetailsData? newsItem) =>

View File

@ -56,7 +56,8 @@ class _GeneralSettingsState extends State<GeneralSettings> {
appBarData: AppBarData(hasBack: true, title: 'تنظیمات'), appBarData: AppBarData(hasBack: true, title: 'تنظیمات'),
children: [ children: [
DidvanCard( DidvanCard(
child: MenuOption( child:
MenuOption(
title: 'زمان دریافت اعلان', title: 'زمان دریافت اعلان',
onTap: () => Navigator.of(context).pushNamed( onTap: () => Navigator.of(context).pushNamed(
Routes.notificationTime, Routes.notificationTime,

View File

@ -94,47 +94,47 @@ class _ProfilePageState extends State<ProfilePage> {
padding: const EdgeInsets.only(right: 8.0, top: 8), padding: const EdgeInsets.only(right: 8.0, top: 8),
child: Column( child: Column(
children: [ children: [
Padding( // Padding(
padding: const EdgeInsets.symmetric( // padding: const EdgeInsets.symmetric(
vertical: 12.0), // vertical: 12.0),
child: MenuOption( // child: MenuOption(
title: 'زمان دریافت اعلان', // title: 'زمان دریافت اعلان',
onTap: () => // onTap: () =>
Navigator.of(context).pushNamed( // Navigator.of(context).pushNamed(
Routes.notificationTime, // Routes.notificationTime,
arguments: { // arguments: {
"fromFav": false, // "fromFav": false,
'onTimeChanged': () => Future.delayed( // 'onTimeChanged': () => Future.delayed(
Duration.zero, // Duration.zero,
() => state.getTime(), // () => state.getTime(),
) // )
}, // },
), // ),
icon: DidvanIcons.notification_regular, // icon: DidvanIcons.notification_regular,
suffix: state.time, // suffix: state.time,
// suffix: 'از${DateTimeUtils.normalizeTimeDuration( // // suffix: 'از${DateTimeUtils.normalizeTimeDuration(
// Duration(minutes: state.notificationTimeRange[0]), // // Duration(minutes: state.notificationTimeRange[0]),
// )} تا ${DateTimeUtils.normalizeTimeDuration( // // )} تا ${DateTimeUtils.normalizeTimeDuration(
// Duration(minutes: state.notificationTimeRange[1]), // // Duration(minutes: state.notificationTimeRange[1]),
// )}', // // )}',
), // ),
), // ),
Padding( // Padding(
padding: const EdgeInsets.symmetric( // padding: const EdgeInsets.symmetric(
vertical: 12.0), // vertical: 12.0),
child: MenuOption( // child: MenuOption(
title: 'شخصی سازی محتوا', // title: 'شخصی سازی محتوا',
onTap: () => Navigator.of(context) // onTap: () => Navigator.of(context)
.pushNamed(Routes.favouritesStep, // .pushNamed(Routes.favouritesStep,
arguments: {"toTimer": false}), // arguments: {"toTimer": false}),
icon: DidvanIcons.note_regular, // icon: DidvanIcons.note_regular,
// suffix: 'از${DateTimeUtils.normalizeTimeDuration( // // suffix: 'از${DateTimeUtils.normalizeTimeDuration(
// Duration(minutes: state.notificationTimeRange[0]), // // Duration(minutes: state.notificationTimeRange[0]),
// )} تا ${DateTimeUtils.normalizeTimeDuration( // // )} تا ${DateTimeUtils.normalizeTimeDuration(
// Duration(minutes: state.notificationTimeRange[1]), // // Duration(minutes: state.notificationTimeRange[1]),
// )}', // // )}',
), // ),
), // ),
Padding( Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 12.0), vertical: 12.0),

View File

@ -18,6 +18,7 @@ class RadarDetailsState extends CoreProvier {
bool isFetchingNewItem = false; bool isFetchingNewItem = false;
final List<int> relatedQueue = []; final List<int> relatedQueue = [];
bool openComments = false; bool openComments = false;
bool _isRequestInProgress = false;
int _currentIndex = 0; int _currentIndex = 0;
int get currentIndex => _currentIndex; int get currentIndex => _currentIndex;
@ -31,15 +32,33 @@ class RadarDetailsState extends CoreProvier {
} }
Future<void> getRadarDetails(int id, {bool? isForward}) async { Future<void> getRadarDetails(int id, {bool? isForward}) async {
// Prevent duplicate requests
if (_isRequestInProgress) {
return;
}
_isRequestInProgress = true;
// Set loading state
if (isForward == null) { if (isForward == null) {
appState = AppState.busy; appState = AppState.busy;
} else { } else {
isFetchingNewItem = true; isFetchingNewItem = true;
notifyListeners(); notifyListeners();
} }
try {
// Wait for token to be ready
if (RequestService.token == null || RequestService.token!.isEmpty) {
await Future.delayed(const Duration(milliseconds: 500));
if (RequestService.token == null || RequestService.token!.isEmpty) {
throw Exception('Token not available');
}
}
final service = RequestService(RequestHelper.radarDetails(id, args)); final service = RequestService(RequestHelper.radarDetails(id, args));
await service.httpGet(); await service.httpGet();
_handleTracking(sendRequest: isForward != null); _handleTracking(sendRequest: isForward != null);
if (service.isSuccess) { if (service.isSuccess) {
final result = service.result; final result = service.result;
final radar = RadarDetailsData.fromJson(result['radar']); final radar = RadarDetailsData.fromJson(result['radar']);
@ -47,6 +66,8 @@ class RadarDetailsState extends CoreProvier {
radars.add(radar); radars.add(radar);
initialIndex = 0; initialIndex = 0;
appState = AppState.idle; appState = AppState.idle;
isFetchingNewItem = false;
_isRequestInProgress = false;
return; return;
} }
@ -86,11 +107,23 @@ class RadarDetailsState extends CoreProvier {
getRelatedContents(); getRelatedContents();
} }
appState = AppState.idle; appState = AppState.idle;
return; } else {
} isFetchingNewItem = false;
//why? total page state shouldn't die!
if (isForward == null) { if (isForward == null) {
appState = AppState.failed; appState = AppState.failed;
} else {
notifyListeners();
}
}
} catch (e) {
print('Error fetching radar details: $e');
isFetchingNewItem = false;
if (isForward == null) {
appState = AppState.failed;
}
notifyListeners();
} finally {
_isRequestInProgress = false;
} }
} }

View File

@ -135,10 +135,11 @@ class _SplashState extends State<Splash> {
await ServerDataProvider.getData(); await ServerDataProvider.getData();
} }
print("token route is $token, initalURI.path: ${initialURI?.path}, intitlPath: ${initialURI?.path}"); print("token route is $token");
String extractedPath = initialURI?.path.toString() == '/' ? Routes.home : initialURI?.path.toString() ?? Routes.home; String extractedPath = initialURI?.path.toString() == '/' ? Routes.home : initialURI?.path.toString() ?? Routes.home;
final String destinationRoute = token == null ? Routes.authenticaion : extractedPath; final String destinationRoute = token == null ? Routes.authenticaion : extractedPath;
dynamic routeArguments = token == null ? {'isResetPassword': false} : {'showDialogs': true}; // Set showDialogs to false to prevent welcome popups
dynamic routeArguments = token == null ? {'isResetPassword': false} : {'showDialogs': false};
if (destinationRoute == Routes.home) { if (destinationRoute == Routes.home) {
@ -155,7 +156,7 @@ class _SplashState extends State<Splash> {
print("destination route: $destinationRoute, route args: $routeArguments"); print("destination route: $destinationRoute, route args: $routeArguments");
await navigatorKey.currentState!.pushReplacementNamed( await navigatorKey.currentState!.pushReplacementNamed(
destinationRoute, destinationRoute,
arguments: token == null ? false : null, arguments: routeArguments,
); );
} catch (e) { } catch (e) {
setState(() { setState(() {

View File

@ -26,12 +26,14 @@ class _WebViewState extends State<WebView> {
}; };
void _onProgress(int progress) { void _onProgress(int progress) {
print('🌐 WebView loading progress: $progress%'); // Add logging
setState(() { setState(() {
this.progress = progress; this.progress = progress;
}); });
} }
void _onPageFinished(String url) async { void _onPageFinished(String url) async {
print('✅ WebView finished loading: $url'); // Add logging
await Future.delayed(const Duration(seconds: 2)); await Future.delayed(const Duration(seconds: 2));
setState(() { setState(() {
if (progress == 100) loading = false; if (progress == 100) loading = false;
@ -40,21 +42,24 @@ class _WebViewState extends State<WebView> {
@override @override
void initState() { void initState() {
print('🔄 Initializing WebView with URL: ${widget.src}'); // Add logging
controller = WebViewController() controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted) ..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate( ..setNavigationDelegate(
NavigationDelegate( NavigationDelegate(
onProgress: _onProgress, onProgress: _onProgress,
onPageStarted: (String url) {}, onPageStarted: (String url) {
print('▶️ WebView started loading: $url'); // Add logging
},
onPageFinished: _onPageFinished, onPageFinished: _onPageFinished,
onHttpError: (HttpResponseError error) {}, onHttpError: (HttpResponseError error) {
// print('❌ WebView HTTP error: ${error.statusCode} on ${error.url}'); // Add logging
},
onWebResourceError: (WebResourceError error) { onWebResourceError: (WebResourceError error) {
// navigatorKey.currentState!.pop(); // print('❌ WebView resource error: ${error.description} on ${error.failingUrl}'); // Add logging
}, },
onNavigationRequest: (NavigationRequest request) { onNavigationRequest: (NavigationRequest request) {
// if (request.url.startsWith('https://www.youtube.com/')) { print('🔀 WebView navigation request to: ${request.url}'); // Add logging
// return NavigationDecision.prevent;
// }
return NavigationDecision.navigate; return NavigationDecision.navigate;
}, },
), ),
@ -77,7 +82,7 @@ class _WebViewState extends State<WebView> {
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
title: const DidvanText( title: const DidvanText(
'بازگشت به دیدوان', 'بازگشت',
), ),
leading: const BackButton(), leading: const BackButton(),
), ),