Compare commits
No commits in common. "0aec835d8a55f8fe615e1629674c75ecacbb3eda" and "86913a973bad96c060ec92a12176dbc512558236" have entirely different histories.
0aec835d8a
...
86913a973b
|
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
// Use IntelliSense to learn about possible attributes.
|
|
||||||
// Hover to view descriptions of existing attributes.
|
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"type": "chrome",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Launch Chrome against localhost",
|
|
||||||
"url": "http://localhost:8080",
|
|
||||||
"webRoot": "${workspaceFolder}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
180
lib/main.dart
180
lib/main.dart
|
|
@ -1,5 +1,3 @@
|
||||||
// lib/main.dart
|
|
||||||
|
|
||||||
// ignore_for_file: deprecated_member_use
|
// ignore_for_file: deprecated_member_use
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
@ -9,8 +7,6 @@ import 'package:bot_toast/bot_toast.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/firebase_options.dart';
|
import 'package:didvan/firebase_options.dart';
|
||||||
import 'package:didvan/models/notification_message.dart';
|
import 'package:didvan/models/notification_message.dart';
|
||||||
import 'package:didvan/models/requests/news.dart';
|
|
||||||
import 'package:didvan/models/requests/radar.dart';
|
|
||||||
import 'package:didvan/providers/media.dart';
|
import 'package:didvan/providers/media.dart';
|
||||||
import 'package:didvan/providers/theme.dart';
|
import 'package:didvan/providers/theme.dart';
|
||||||
import 'package:didvan/providers/user.dart';
|
import 'package:didvan/providers/user.dart';
|
||||||
|
|
@ -36,56 +32,56 @@ import 'package:home_widget/home_widget.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter_downloader/flutter_downloader.dart';
|
import 'package:flutter_downloader/flutter_downloader.dart';
|
||||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||||
|
|
||||||
|
// پکیج جدید برای Deep Linking
|
||||||
import 'package:app_links/app_links.dart';
|
import 'package:app_links/app_links.dart';
|
||||||
|
|
||||||
import 'services/network/request.dart';
|
|
||||||
|
|
||||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
|
||||||
|
// متغیر استاتیک برای نگهداری لینک اولیه
|
||||||
Uri? initialURI;
|
Uri? initialURI;
|
||||||
|
|
||||||
@pragma('vm:entry-point')
|
@pragma('vm:entry-point')
|
||||||
Future<void> _backgroundCallbackHomeWidget(Uri? uri) async {
|
Future<void> _backgroundCallbackHomeWidget(Uri? uri) async {
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
await HomeWidget.saveWidgetData("uri", uri.host);
|
await HomeWidget.saveWidgetData("uri", uri.host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
runZonedGuarded(
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
() async {
|
try {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
if (!kIsWeb) {
|
||||||
|
HomeWidget.registerBackgroundCallback(_backgroundCallbackHomeWidget);
|
||||||
|
HomeWidget.registerInteractivityCallback(_backgroundCallbackHomeWidget);
|
||||||
|
await NotificationService.initializeNotification();
|
||||||
try {
|
try {
|
||||||
if (!kIsWeb) {
|
if (Platform.isAndroid) {
|
||||||
HomeWidget.registerBackgroundCallback(_backgroundCallbackHomeWidget);
|
await FlutterDownloader.initialize(
|
||||||
HomeWidget.registerInteractivityCallback(_backgroundCallbackHomeWidget);
|
debug: true,
|
||||||
await NotificationService.initializeNotification();
|
ignoreSsl: true
|
||||||
try {
|
);
|
||||||
if (Platform.isAndroid) {
|
|
||||||
await FlutterDownloader.initialize(debug: true, ignoreSsl: true);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
e.printError();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
|
|
||||||
await FirebaseApi().initNotification();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint(e.toString());
|
e.printError();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await SentryFlutter.init(
|
await Firebase.initializeApp(
|
||||||
(options) {
|
options: DefaultFirebaseOptions.currentPlatform);
|
||||||
options.dsn = 'https://a4cfcaa7d67471240d295c25c968d91d@o4508585857384448.ingest.de.sentry.io/4508585886548048';
|
await FirebaseApi().initNotification();
|
||||||
options.tracesSampleRate = 1.0;
|
} catch (e) {
|
||||||
options.profilesSampleRate = 1.0;
|
debugPrint(e.toString());
|
||||||
},
|
}
|
||||||
appRunner: () => runApp(const Didvan()),
|
|
||||||
);
|
await SentryFlutter.init(
|
||||||
},
|
(options) {
|
||||||
(error, stack) {
|
options.dsn =
|
||||||
Sentry.captureException(error, stackTrace: stack);
|
'https://a4cfcaa7d67471240d295c25c968d91d@o4508585857384448.ingest.de.sentry.io/4508585886548048';
|
||||||
|
options.tracesSampleRate = 1.0;
|
||||||
|
options.profilesSampleRate = 1.0;
|
||||||
},
|
},
|
||||||
|
appRunner: () => runApp(const Didvan()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,57 +100,41 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
WidgetsBinding.instance.addObserver(this);
|
WidgetsBinding.instance.addObserver(this);
|
||||||
|
// مقداردهی اولیه و گوش دادن به لینکها در اینجا انجام میشود
|
||||||
_initDeepLinks();
|
_initDeepLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
WidgetsBinding.instance.removeObserver(this);
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
_linkSubscription?.cancel();
|
_linkSubscription?.cancel(); // لغو کردن subscription
|
||||||
if (MediaService.currentPodcast != null) {
|
if (MediaService.currentPodcast != null) {
|
||||||
MediaService.audioPlayer.dispose();
|
MediaService.audioPlayer.dispose();
|
||||||
}
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// منطق جدید برای مدیریت لینکها با app_links
|
||||||
Future<void> _initDeepLinks() async {
|
Future<void> _initDeepLinks() async {
|
||||||
_appLinks = AppLinks();
|
_appLinks = AppLinks();
|
||||||
|
|
||||||
|
// لینک اولیه را فقط در متغیر ذخیره میکنیم
|
||||||
initialURI = await _appLinks.getInitialLink();
|
initialURI = await _appLinks.getInitialLink();
|
||||||
|
|
||||||
|
// به لینکهای جدید زمانی که اپلیکیشن باز است گوش میدهیم
|
||||||
_linkSubscription = _appLinks.uriLinkStream.listen((uri) {
|
_linkSubscription = _appLinks.uriLinkStream.listen((uri) {
|
||||||
_navigateTo(uri);
|
_navigateTo(uri);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// تابع کمکی برای ناوبری
|
||||||
void _navigateTo(Uri uri) {
|
void _navigateTo(Uri uri) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
String path = uri.path;
|
String path = uri.path;
|
||||||
final Map<String, String> params = uri.queryParameters;
|
if (uri.fragment.isNotEmpty) {
|
||||||
|
path = "/${uri.fragment}";
|
||||||
final String? token = params['token'];
|
|
||||||
|
|
||||||
if (token != null) {
|
|
||||||
//todo: this didnt work
|
|
||||||
print("DEBUG: received token in url, token: $token, path: $path");
|
|
||||||
RequestService.token = token;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.startsWith('/news/')) {
|
|
||||||
final id = path.split('/news/').last;
|
|
||||||
if (id.isNotEmpty) {
|
|
||||||
navigatorKey.currentState?.pushNamed(
|
|
||||||
Routes.newsDetails,
|
|
||||||
arguments: {'id': int.parse(id), 'args': const NewsRequestArgs(page: 0)},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if (path.startsWith('/radar/')) {
|
|
||||||
final id = path.split('/radar/').last;
|
|
||||||
if (id.isNotEmpty) {
|
|
||||||
navigatorKey.currentState?.pushNamed(
|
|
||||||
Routes.radarDetails,
|
|
||||||
arguments: {'id': int.parse(id), 'args': const RadarRequestArgs(page: 0)},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
navigatorKey.currentState?.pushNamed(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,9 +143,11 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
|
||||||
if (!kIsWeb) {
|
if (!kIsWeb) {
|
||||||
if (state == AppLifecycleState.resumed) {
|
if (state == AppLifecycleState.resumed) {
|
||||||
var r = await HomeWidget.getWidgetData("cRoute", defaultValue: '');
|
var r = await HomeWidget.getWidgetData("cRoute", defaultValue: '');
|
||||||
if (r.toString() != Routes.splash) {
|
if (r!.toString() != Routes.splash) {
|
||||||
await HomeWidgetRepository.decideWhereToGo();
|
await HomeWidgetRepository.decideWhereToGo();
|
||||||
|
|
||||||
NotificationMessage? data = HomeWidgetRepository.data;
|
NotificationMessage? data = HomeWidgetRepository.data;
|
||||||
|
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
await HomeWidgetRepository.decideWhereToGoNotif();
|
await HomeWidgetRepository.decideWhereToGoNotif();
|
||||||
}
|
}
|
||||||
|
|
@ -193,41 +175,41 @@ class _DidvanState extends State<Didvan> with WidgetsBindingObserver {
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
scrollBehavior: MyCustomScrollBehavior(),
|
scrollBehavior: MyCustomScrollBehavior(),
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
title: 'Didvan',
|
title: 'Didvan',
|
||||||
theme: LightThemeConfig.themeData.copyWith(
|
theme: LightThemeConfig.themeData.copyWith(
|
||||||
bottomSheetTheme: const BottomSheetThemeData(
|
bottomSheetTheme: const BottomSheetThemeData(
|
||||||
surfaceTintColor: Colors.transparent,
|
surfaceTintColor: Colors.transparent,
|
||||||
backgroundColor: Colors.transparent),
|
backgroundColor: Colors.transparent),
|
||||||
textTheme: LightThemeConfig.themeData.textTheme.apply(
|
textTheme: LightThemeConfig.themeData.textTheme.apply(
|
||||||
fontFamily: themeProvider.fontFamily,
|
fontFamily: themeProvider.fontFamily,
|
||||||
)),
|
)),
|
||||||
darkTheme: DarkThemeConfig.themeData.copyWith(
|
darkTheme: DarkThemeConfig.themeData.copyWith(
|
||||||
bottomSheetTheme: const BottomSheetThemeData(
|
bottomSheetTheme: const BottomSheetThemeData(
|
||||||
surfaceTintColor: Colors.transparent,
|
surfaceTintColor: Colors.transparent,
|
||||||
backgroundColor: Colors.transparent),
|
backgroundColor: Colors.transparent),
|
||||||
textTheme: DarkThemeConfig.themeData.textTheme.apply(
|
textTheme: DarkThemeConfig.themeData.textTheme.apply(
|
||||||
fontFamily: themeProvider.fontFamily,
|
fontFamily: themeProvider.fontFamily,
|
||||||
)),
|
)),
|
||||||
color: LightThemeConfig.themeData.primaryColor,
|
color: LightThemeConfig.themeData.primaryColor,
|
||||||
themeMode: themeProvider.themeMode,
|
themeMode: themeProvider.themeMode,
|
||||||
onGenerateRoute: (settings) =>
|
onGenerateRoute: (settings) =>
|
||||||
RouteGenerator.generateRoute(settings),
|
RouteGenerator.generateRoute(settings),
|
||||||
builder: BotToastInit(),
|
builder: BotToastInit(),
|
||||||
navigatorObservers: [BotToastNavigatorObserver()],
|
navigatorObservers: [BotToastNavigatorObserver()],
|
||||||
initialRoute: "/",
|
initialRoute: "/",
|
||||||
localizationsDelegates: const [
|
localizationsDelegates: const [
|
||||||
GlobalCupertinoLocalizations.delegate,
|
GlobalCupertinoLocalizations.delegate,
|
||||||
GlobalMaterialLocalizations.delegate,
|
GlobalMaterialLocalizations.delegate,
|
||||||
GlobalWidgetsLocalizations.delegate,
|
GlobalWidgetsLocalizations.delegate,
|
||||||
],
|
],
|
||||||
supportedLocales: const [
|
supportedLocales: const [
|
||||||
Locale("fa", "IR"),
|
Locale("fa", "IR"),
|
||||||
],
|
],
|
||||||
locale: const Locale("fa", "IR"),
|
locale: const Locale("fa", "IR"),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
// lib/services/network/request.dart
|
|
||||||
|
|
||||||
// ignore_for_file: empty_catches
|
// ignore_for_file: empty_catches
|
||||||
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
@ -17,7 +15,7 @@ import 'package:mime/mime.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
class RequestService {
|
class RequestService {
|
||||||
static String? token; // Made token nullable
|
static late String token;
|
||||||
int? statusCode;
|
int? statusCode;
|
||||||
|
|
||||||
dynamic data(String s) {
|
dynamic data(String s) {
|
||||||
|
|
@ -50,9 +48,12 @@ class RequestService {
|
||||||
}) {
|
}) {
|
||||||
if (body != null) _requestBody = body;
|
if (body != null) _requestBody = body;
|
||||||
if (requestHeaders != null) _headers.addAll(requestHeaders);
|
if (requestHeaders != null) _headers.addAll(requestHeaders);
|
||||||
if (useAutherization && token != null) { // Check if token is not null
|
if (useAutherization) _headers.addAll({'Authorization': 'Bearer $token'});
|
||||||
_headers.addAll({'Authorization': 'Bearer $token'});
|
// if (kDebugMode) {
|
||||||
}
|
// try {
|
||||||
|
// print('Authorization : Bearer $token');
|
||||||
|
// } catch (e) {}
|
||||||
|
// }
|
||||||
if (body != null) _requestBody = body;
|
if (body != null) _requestBody = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ class _AuthenticationState extends State<Authentication> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
body: Consumer<AuthenticationState>(
|
body: Consumer<AuthenticationState>(
|
||||||
builder: (context, state, child) => WillPopScope(
|
builder: (context, state, child) => WillPopScope(
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,7 @@ class AuthenticationLayout extends StatelessWidget {
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||||
sliver: SliverFillRemaining(
|
sliver: SliverFillRemaining(
|
||||||
hasScrollBody: true,
|
hasScrollBody: false,
|
||||||
fillOverscroll: true,
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
for (var i = 0; i < children.length; i++) children[i],
|
for (var i = 0; i < children.length; i++) children[i],
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ class CustomizeCategoryState extends CoreProvier {
|
||||||
|
|
||||||
Future<void> getFavourites() async {
|
Future<void> getFavourites() async {
|
||||||
appState = AppState.busy;
|
appState = AppState.busy;
|
||||||
update();
|
|
||||||
|
|
||||||
final service = RequestService(
|
final service = RequestService(
|
||||||
RequestHelper.favourites(),
|
RequestHelper.favourites(),
|
||||||
|
|
@ -32,19 +31,13 @@ class CustomizeCategoryState extends CoreProvier {
|
||||||
await service.httpGet();
|
await service.httpGet();
|
||||||
if (service.isSuccess) {
|
if (service.isSuccess) {
|
||||||
faves.clear();
|
faves.clear();
|
||||||
final favouritesData = service.data('types');
|
final favourites = service.data('types');
|
||||||
if (favouritesData is List) {
|
for (var i = 0; i < favourites.length; i++) {
|
||||||
for (var i = 0; i < favouritesData.length; i++) {
|
faves.add(FavoritesResponse.fromJson(favourites[i]));
|
||||||
faves.add(FavoritesResponse.fromJson(favouritesData[i]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// اضافه کردن مستقیم بخش فرصت و تهدید
|
|
||||||
faves.add(FavoritesResponse(id: 999, name: 'فرصت و تهدید', selected: false));
|
|
||||||
|
|
||||||
selectedFavIds.clear();
|
selectedFavIds.clear();
|
||||||
for (var element in faves) {
|
for (var element in faves) {
|
||||||
if (element.selected == true) {
|
if (element.selected!) {
|
||||||
selectedFavIds.add(element.id!);
|
selectedFavIds.add(element.id!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,38 +78,29 @@ class _FavoritesStepState extends State<FavoritesStep> {
|
||||||
asset: Assets.emptyChat,
|
asset: Assets.emptyChat,
|
||||||
title: 'اولین نظر را بنویسید...',
|
title: 'اولین نظر را بنویسید...',
|
||||||
),
|
),
|
||||||
builder: (context, state, index) => Column(
|
builder: (context, state, index) => Center(
|
||||||
children: [
|
child: Container(
|
||||||
Center(
|
height: 48,
|
||||||
child: Container(
|
decoration: BoxDecoration(
|
||||||
height: 48,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
width: 1,
|
width: 1,
|
||||||
color: state.faves[index].selected!
|
color: state.faves[index].selected!
|
||||||
? Theme.of(context).colorScheme.focusedBorder
|
? Theme.of(context)
|
||||||
: Theme.of(context).colorScheme.cardBorder
|
.colorScheme
|
||||||
),
|
.focusedBorder
|
||||||
|
: Theme.of(context).colorScheme.cardBorder),
|
||||||
color: state.faves[index].selected!
|
color: state.faves[index].selected!
|
||||||
? Theme.of(context).colorScheme.focused
|
? Theme.of(context).colorScheme.focused
|
||||||
: Theme.of(context).colorScheme.cardBorder
|
: Theme.of(context).colorScheme.cardBorder),
|
||||||
),
|
child: CustomizeCategoryCheckbox(
|
||||||
child: CustomizeCategoryCheckbox(
|
|
||||||
title: state.faves[index].name!,
|
title: state.faves[index].name!,
|
||||||
value: state.faves[index].selected,
|
value: state.faves[index].selected,
|
||||||
checkColor: Theme.of(context).colorScheme.checkFav,
|
checkColor: Theme.of(context).colorScheme.checkFav,
|
||||||
onChanged: (val) {
|
onChanged: (val) {
|
||||||
state.changeSelected(
|
state.changeSelected(
|
||||||
index, state.faves, state.selectedFavIds);
|
index, state.faves, state.selectedFavIds);
|
||||||
}
|
})),
|
||||||
)
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// Add extra bottom padding for the last item
|
|
||||||
if (index == state.faves.length - 1)
|
|
||||||
const SizedBox(height: 80),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -142,10 +142,9 @@ class _HomeState extends State<Home>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
// Remove dialog showing logic to prevent welcome popups
|
if (widget.showDialogs ?? false) {
|
||||||
// if (widget.showDialogs ?? false) {
|
_showDialog(context);
|
||||||
// _showDialog(context);
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
final state = context.read<HomeState>();
|
final state = context.read<HomeState>();
|
||||||
DesignConfig.updateSystemUiOverlayStyle();
|
DesignConfig.updateSystemUiOverlayStyle();
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,6 @@ class HomeState extends CoreProvier {
|
||||||
);
|
);
|
||||||
await service.httpGet();
|
await service.httpGet();
|
||||||
if (service.isSuccess) {
|
if (service.isSuccess) {
|
||||||
print("DEBUG : Homestate is succes");
|
|
||||||
lastPage = service.result['lastPage'];
|
lastPage = service.result['lastPage'];
|
||||||
results.addAll(
|
results.addAll(
|
||||||
List<OverviewData>.from(
|
List<OverviewData>.from(
|
||||||
|
|
@ -95,14 +94,12 @@ class HomeState extends CoreProvier {
|
||||||
appState = AppState.idle;
|
appState = AppState.idle;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
print("DEBUG : Homestate is NOT succes");
|
|
||||||
appState = AppState.failed;
|
appState = AppState.failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> searchAll({required int page}) async {
|
Future<void> searchAll({required int page}) async {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
if (page == 1) {
|
if (page == 1) {
|
||||||
print("DEBUG : serach is busy");
|
|
||||||
results.clear();
|
results.clear();
|
||||||
appState = AppState.busy;
|
appState = AppState.busy;
|
||||||
}
|
}
|
||||||
|
|
@ -118,7 +115,6 @@ class HomeState extends CoreProvier {
|
||||||
);
|
);
|
||||||
await service.httpGet();
|
await service.httpGet();
|
||||||
if (service.isSuccess) {
|
if (service.isSuccess) {
|
||||||
print("DEBUG : HTTPget Home is succes");
|
|
||||||
lastPage = service.result['lastPage'];
|
lastPage = service.result['lastPage'];
|
||||||
unreadCount = service.result['unread'] ?? unreadCount;
|
unreadCount = service.result['unread'] ?? unreadCount;
|
||||||
results.addAll(
|
results.addAll(
|
||||||
|
|
@ -132,7 +128,6 @@ class HomeState extends CoreProvier {
|
||||||
appState = AppState.idle;
|
appState = AppState.idle;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
print("DEBUG : Homestate is faild");
|
|
||||||
appState = AppState.failed;
|
appState = AppState.failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,36 +33,22 @@ class MainPage extends StatefulWidget {
|
||||||
class _MainPageState extends State<MainPage> {
|
class _MainPageState extends State<MainPage> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
context.read<MainPageState>().init();
|
||||||
print("DEBUG: _MainPageState initstate called");
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
print("DEBUG: addPostFrameCallback called");
|
|
||||||
context.read<MainPageState>().init();
|
|
||||||
});
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
print("DEBUG: _MainPageState build called");
|
|
||||||
return StateHandler<MainPageState>(
|
return StateHandler<MainPageState>(
|
||||||
onRetry: () => {
|
onRetry: context.read<MainPageState>().init,
|
||||||
print("DEBUG: _MainPageState onRetry called"),
|
|
||||||
context.read<MainPageState>().init
|
|
||||||
},
|
|
||||||
state: context.watch<MainPageState>(),
|
state: context.watch<MainPageState>(),
|
||||||
builder: (context, state) {
|
builder: (context, state) => ListView(
|
||||||
print("DEBUG: FutureBuilder waiting");
|
|
||||||
print("DEBUG: FutureBuilder state.stories.isNotEmpty: ${state.stories.isNotEmpty}");
|
|
||||||
print("DEBUG: FutureBuilder state.content: ${state.content!.lists}");
|
|
||||||
print("DEBUG: FutureBuilder state.content != null: ${state.content != null}");
|
|
||||||
print("DEBUG: FutureBuilder state.content!.lists.isNotEmpty: ${state.content!.lists.isNotEmpty}");
|
|
||||||
return ListView(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
children: [
|
children: [
|
||||||
if (state.stories.isNotEmpty) StorySection(stories: state.stories),
|
if (state.stories.isNotEmpty) StorySection(stories: state.stories),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
const MainPageMainContent(),
|
const MainPageMainContent(),
|
||||||
|
|
||||||
Builder(builder: (context) {
|
Builder(builder: (context) {
|
||||||
final List<Widget> pageContent = [];
|
final List<Widget> pageContent = [];
|
||||||
if (state.content != null && state.content!.lists.isNotEmpty) {
|
if (state.content != null && state.content!.lists.isNotEmpty) {
|
||||||
|
|
@ -132,12 +118,10 @@ class _MainPageState extends State<MainPage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print("DEBUG: FutureBuilder error");
|
|
||||||
return Column(children: pageContent);
|
return Column(children: pageContent);
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -305,6 +289,7 @@ class _MainPageSection extends StatelessWidget {
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This condition handles the "Soha" module, which should not display the Opportunity/Threat module.
|
||||||
if (list.type == 'delphi') {
|
if (list.type == 'delphi') {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -314,6 +299,7 @@ class _MainPageSection extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For all other modules, display as before.
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
_buildSectionHeader(context, icon),
|
_buildSectionHeader(context, icon),
|
||||||
|
|
|
||||||
|
|
@ -24,19 +24,12 @@ class MainPageState extends CoreProvier {
|
||||||
List<SwotItem> swotItems = [];
|
List<SwotItem> swotItems = [];
|
||||||
|
|
||||||
Future<void> _getMainPageContent() async {
|
Future<void> _getMainPageContent() async {
|
||||||
print("DEBUG: _getMainPageContent started");
|
|
||||||
final service = RequestService(RequestHelper.mainPageContent);
|
final service = RequestService(RequestHelper.mainPageContent);
|
||||||
await service.httpGet();
|
await service.httpGet();
|
||||||
if (service.isSuccess) {
|
if (service.isSuccess) {
|
||||||
print("DEBUG: _getMainPageContent success");
|
|
||||||
content = MainPageContent.fromJson(service.result);
|
content = MainPageContent.fromJson(service.result);
|
||||||
print("DEBUG: _getMainPageContent service.result: ${service.result}");
|
|
||||||
unread = service.result['unread'];
|
unread = service.result['unread'];
|
||||||
print("DEBUG: __getMainPageContent unread: $unread, content: $content");
|
|
||||||
notifyListeners();
|
|
||||||
} else {
|
} else {
|
||||||
print("DEBUG: _getMainPageContent failed state");
|
|
||||||
notifyListeners();
|
|
||||||
throw Exception('Failed to load main page content');
|
throw Exception('Failed to load main page content');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -50,14 +43,14 @@ class MainPageState extends CoreProvier {
|
||||||
try {
|
try {
|
||||||
swotItems = await SwotService.fetchSwotItems();
|
swotItems = await SwotService.fetchSwotItems();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _fetchStories() async {
|
Future<void> _fetchStories() async {
|
||||||
try {
|
try {
|
||||||
stories = await StoryService.getStories();
|
stories = await StoryService.getStories();
|
||||||
// print("Fetched ${stories.length} stories.");
|
print("Fetched ${stories.length} stories.");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
stories = [];
|
stories = [];
|
||||||
debugPrint("Could not fetch stories: $e");
|
debugPrint("Could not fetch stories: $e");
|
||||||
|
|
@ -65,7 +58,6 @@ class MainPageState extends CoreProvier {
|
||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
print("DEBUG: MainPageState init called");
|
|
||||||
Future.delayed(Duration.zero, () async {
|
Future.delayed(Duration.zero, () async {
|
||||||
appState = AppState.busy;
|
appState = AppState.busy;
|
||||||
try {
|
try {
|
||||||
|
|
@ -79,7 +71,6 @@ class MainPageState extends CoreProvier {
|
||||||
appState = AppState.failed;
|
appState = AppState.failed;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_getMainPageContent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void markChangeHandler(String type, int id, bool value) {
|
void markChangeHandler(String type, int id, bool value) {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ class _NewsDetailsState extends State<NewsDetails> {
|
||||||
Future.delayed(Duration.zero, () {
|
Future.delayed(Duration.zero, () {
|
||||||
state.getNewsDetails(widget.pageData['id']);
|
state.getNewsDetails(widget.pageData['id']);
|
||||||
});
|
});
|
||||||
if (widget.pageData['goToComment'] != null) {
|
if(widget.pageData['goToComment'] != null){
|
||||||
state.openComments = widget.pageData['goToComment'];
|
state.openComments = widget.pageData['goToComment'];
|
||||||
}
|
}
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
@ -42,8 +42,7 @@ 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: () =>
|
onRetry: () => state.getNewsDetails(state.currentNews.id),
|
||||||
state.getNewsDetails(widget.pageData['id']),
|
|
||||||
state: state,
|
state: state,
|
||||||
builder: (context, state) => Stack(
|
builder: (context, state) => Stack(
|
||||||
children: [
|
children: [
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ 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;
|
||||||
|
|
@ -26,95 +25,62 @@ 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 {
|
||||||
// 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();
|
||||||
}
|
}
|
||||||
|
final service = RequestService(RequestHelper.newsDetails(id, args));
|
||||||
try {
|
await service.httpGet();
|
||||||
// Wait for token to be ready
|
_handleTracking(sendRequest: isForward != null);
|
||||||
if (RequestService.token == null || RequestService.token!.isEmpty) {
|
if (service.isSuccess) {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
final result = service.result;
|
||||||
if (RequestService.token == null || RequestService.token!.isEmpty) {
|
final newsItem = NewsDetailsData.fromJson(result['news']);
|
||||||
throw Exception('Token not available');
|
if (args.page == 0) {
|
||||||
}
|
news.add(newsItem);
|
||||||
}
|
initialIndex = 0;
|
||||||
|
|
||||||
final service = RequestService(RequestHelper.newsDetails(id, args));
|
|
||||||
await service.httpGet();
|
|
||||||
_handleTracking(sendRequest: isForward != null);
|
|
||||||
|
|
||||||
if (service.isSuccess) {
|
|
||||||
final result = service.result;
|
|
||||||
final newsItem = NewsDetailsData.fromJson(result['news']);
|
|
||||||
if (args.page == 0) {
|
|
||||||
news.add(newsItem);
|
|
||||||
initialIndex = 0;
|
|
||||||
appState = AppState.idle;
|
|
||||||
isFetchingNewItem = false;
|
|
||||||
_isRequestInProgress = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NewsDetailsData? prevNews;
|
|
||||||
if (result['prevNews'].isNotEmpty) {
|
|
||||||
prevNews = NewsDetailsData.fromJson(result['prevNews']);
|
|
||||||
}
|
|
||||||
NewsDetailsData? nextNews;
|
|
||||||
if (result['nextNews'].isNotEmpty) {
|
|
||||||
nextNews = NewsDetailsData.fromJson(result['nextNews']);
|
|
||||||
}
|
|
||||||
if (isForward == null) {
|
|
||||||
news.addAll(List.generate(max(newsItem.order - 2, 0), (index) => null));
|
|
||||||
if (prevNews != null) {
|
|
||||||
news.add(prevNews);
|
|
||||||
}
|
|
||||||
news.add(newsItem);
|
|
||||||
if (nextNews != null) {
|
|
||||||
news.add(nextNews);
|
|
||||||
}
|
|
||||||
_currentIndex = initialIndex = newsItem.order - 1;
|
|
||||||
} else if (isForward) {
|
|
||||||
if (!exists(nextNews) && nextNews != null) {
|
|
||||||
news.add(nextNews);
|
|
||||||
}
|
|
||||||
_currentIndex++;
|
|
||||||
} else if (!isForward) {
|
|
||||||
if (!exists(prevNews) && prevNews != null) {
|
|
||||||
news[_currentIndex - 2] = prevNews;
|
|
||||||
}
|
|
||||||
_currentIndex--;
|
|
||||||
}
|
|
||||||
isFetchingNewItem = false;
|
|
||||||
if (currentNews.contents.length == 1) {
|
|
||||||
getRelatedContents();
|
|
||||||
}
|
|
||||||
appState = AppState.idle;
|
appState = AppState.idle;
|
||||||
} else {
|
return;
|
||||||
isFetchingNewItem = false;
|
}
|
||||||
if (isForward == null) {
|
NewsDetailsData? prevNews;
|
||||||
appState = AppState.failed;
|
if (result['prevNews'].isNotEmpty) {
|
||||||
} else {
|
prevNews = NewsDetailsData.fromJson(result['prevNews']);
|
||||||
notifyListeners();
|
}
|
||||||
}
|
NewsDetailsData? nextNews;
|
||||||
|
if (result['nextNews'].isNotEmpty) {
|
||||||
|
nextNews = NewsDetailsData.fromJson(result['nextNews']);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
print('Error fetching news details: $e');
|
|
||||||
isFetchingNewItem = false;
|
|
||||||
if (isForward == null) {
|
if (isForward == null) {
|
||||||
appState = AppState.failed;
|
news.addAll(List.generate(max(newsItem.order - 2, 0), (index) => null));
|
||||||
|
if (prevNews != null) {
|
||||||
|
news.add(prevNews);
|
||||||
|
}
|
||||||
|
news.add(newsItem);
|
||||||
|
if (nextNews != null) {
|
||||||
|
news.add(nextNews);
|
||||||
|
}
|
||||||
|
_currentIndex = initialIndex = newsItem.order - 1;
|
||||||
|
} else if (isForward) {
|
||||||
|
if (!exists(nextNews) && nextNews != null) {
|
||||||
|
news.add(nextNews);
|
||||||
|
}
|
||||||
|
_currentIndex++;
|
||||||
|
} else if (!isForward) {
|
||||||
|
if (!exists(prevNews) && prevNews != null) {
|
||||||
|
news[_currentIndex - 2] = prevNews;
|
||||||
|
}
|
||||||
|
_currentIndex--;
|
||||||
}
|
}
|
||||||
notifyListeners();
|
isFetchingNewItem = false;
|
||||||
} finally {
|
if (currentNews.contents.length == 1) {
|
||||||
_isRequestInProgress = false;
|
getRelatedContents();
|
||||||
|
}
|
||||||
|
appState = AppState.idle;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isForward == null) {
|
||||||
|
appState = AppState.failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,7 @@ class _GeneralSettingsState extends State<GeneralSettings> {
|
||||||
appBarData: AppBarData(hasBack: true, title: 'تنظیمات'),
|
appBarData: AppBarData(hasBack: true, title: 'تنظیمات'),
|
||||||
children: [
|
children: [
|
||||||
DidvanCard(
|
DidvanCard(
|
||||||
child:
|
child: MenuOption(
|
||||||
MenuOption(
|
|
||||||
title: 'زمان دریافت اعلان',
|
title: 'زمان دریافت اعلان',
|
||||||
onTap: () => Navigator.of(context).pushNamed(
|
onTap: () => Navigator.of(context).pushNamed(
|
||||||
Routes.notificationTime,
|
Routes.notificationTime,
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ 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;
|
||||||
|
|
@ -32,98 +31,66 @@ 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();
|
||||||
}
|
}
|
||||||
|
final service = RequestService(RequestHelper.radarDetails(id, args));
|
||||||
try {
|
await service.httpGet();
|
||||||
// Wait for token to be ready
|
_handleTracking(sendRequest: isForward != null);
|
||||||
if (RequestService.token == null || RequestService.token!.isEmpty) {
|
if (service.isSuccess) {
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
final result = service.result;
|
||||||
if (RequestService.token == null || RequestService.token!.isEmpty) {
|
final radar = RadarDetailsData.fromJson(result['radar']);
|
||||||
throw Exception('Token not available');
|
if (args.page == 0) {
|
||||||
}
|
radars.add(radar);
|
||||||
}
|
initialIndex = 0;
|
||||||
|
|
||||||
final service = RequestService(RequestHelper.radarDetails(id, args));
|
|
||||||
await service.httpGet();
|
|
||||||
_handleTracking(sendRequest: isForward != null);
|
|
||||||
|
|
||||||
if (service.isSuccess) {
|
|
||||||
final result = service.result;
|
|
||||||
final radar = RadarDetailsData.fromJson(result['radar']);
|
|
||||||
if (args.page == 0) {
|
|
||||||
radars.add(radar);
|
|
||||||
initialIndex = 0;
|
|
||||||
appState = AppState.idle;
|
|
||||||
isFetchingNewItem = false;
|
|
||||||
_isRequestInProgress = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RadarDetailsData? prevRadar;
|
|
||||||
if (result['prevRadar'].isNotEmpty) {
|
|
||||||
prevRadar = RadarDetailsData.fromJson(result['prevRadar']);
|
|
||||||
}
|
|
||||||
|
|
||||||
RadarDetailsData? nextRadar;
|
|
||||||
if (result['nextRadar'].isNotEmpty) {
|
|
||||||
nextRadar = RadarDetailsData.fromJson(result['nextRadar']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isForward == null) {
|
|
||||||
radars.addAll(List.generate(max(radar.order - 2, 0), (index) => null));
|
|
||||||
if (prevRadar != null) {
|
|
||||||
radars.add(prevRadar);
|
|
||||||
}
|
|
||||||
radars.add(radar);
|
|
||||||
if (nextRadar != null) {
|
|
||||||
radars.add(nextRadar);
|
|
||||||
}
|
|
||||||
_currentIndex = initialIndex = radar.order - 1;
|
|
||||||
} else if (isForward) {
|
|
||||||
if (!exists(nextRadar) && nextRadar != null) {
|
|
||||||
radars.add(nextRadar);
|
|
||||||
}
|
|
||||||
_currentIndex++;
|
|
||||||
} else if (!isForward) {
|
|
||||||
if (!exists(prevRadar) && prevRadar != null) {
|
|
||||||
radars[_currentIndex - 2] = prevRadar;
|
|
||||||
}
|
|
||||||
_currentIndex--;
|
|
||||||
}
|
|
||||||
isFetchingNewItem = false;
|
|
||||||
if (currentRadar.contents.length == 1) {
|
|
||||||
getRelatedContents();
|
|
||||||
}
|
|
||||||
appState = AppState.idle;
|
appState = AppState.idle;
|
||||||
} else {
|
return;
|
||||||
isFetchingNewItem = false;
|
|
||||||
if (isForward == null) {
|
|
||||||
appState = AppState.failed;
|
|
||||||
} else {
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
print('Error fetching radar details: $e');
|
RadarDetailsData? prevRadar;
|
||||||
isFetchingNewItem = false;
|
if (result['prevRadar'].isNotEmpty) {
|
||||||
|
prevRadar = RadarDetailsData.fromJson(result['prevRadar']);
|
||||||
|
}
|
||||||
|
|
||||||
|
RadarDetailsData? nextRadar;
|
||||||
|
if (result['nextRadar'].isNotEmpty) {
|
||||||
|
nextRadar = RadarDetailsData.fromJson(result['nextRadar']);
|
||||||
|
}
|
||||||
|
|
||||||
if (isForward == null) {
|
if (isForward == null) {
|
||||||
appState = AppState.failed;
|
radars.addAll(List.generate(max(radar.order - 2, 0), (index) => null));
|
||||||
|
if (prevRadar != null) {
|
||||||
|
radars.add(prevRadar);
|
||||||
|
}
|
||||||
|
radars.add(radar);
|
||||||
|
if (nextRadar != null) {
|
||||||
|
radars.add(nextRadar);
|
||||||
|
}
|
||||||
|
_currentIndex = initialIndex = radar.order - 1;
|
||||||
|
} else if (isForward) {
|
||||||
|
if (!exists(nextRadar) && nextRadar != null) {
|
||||||
|
radars.add(nextRadar);
|
||||||
|
}
|
||||||
|
_currentIndex++;
|
||||||
|
} else if (!isForward) {
|
||||||
|
if (!exists(prevRadar) && prevRadar != null) {
|
||||||
|
radars[_currentIndex - 2] = prevRadar;
|
||||||
|
}
|
||||||
|
_currentIndex--;
|
||||||
}
|
}
|
||||||
notifyListeners();
|
isFetchingNewItem = false;
|
||||||
} finally {
|
if (currentRadar.contents.length == 1) {
|
||||||
_isRequestInProgress = false;
|
getRelatedContents();
|
||||||
|
}
|
||||||
|
appState = AppState.idle;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//why? total page state shouldn't die!
|
||||||
|
if (isForward == null) {
|
||||||
|
appState = AppState.failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,7 @@ class _SplashState extends State<Splash> {
|
||||||
Future<void> _initialize(ThemeProvider themeProvider,
|
Future<void> _initialize(ThemeProvider themeProvider,
|
||||||
UserProvider userProvider, MediaProvider mediaProvider) async {
|
UserProvider userProvider, MediaProvider mediaProvider) async {
|
||||||
try {
|
try {
|
||||||
print("checking if is in browser");
|
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
print("detected browser");
|
|
||||||
html.window.onBeforeUnload.listen((event) {
|
html.window.onBeforeUnload.listen((event) {
|
||||||
StorageService.webStorage
|
StorageService.webStorage
|
||||||
.removeWhere((key, value) => key == 'image-cache');
|
.removeWhere((key, value) => key == 'image-cache');
|
||||||
|
|
@ -105,22 +103,20 @@ class _SplashState extends State<Splash> {
|
||||||
await AppInitializer.setupServices(navigatorKey.currentContext!);
|
await AppInitializer.setupServices(navigatorKey.currentContext!);
|
||||||
|
|
||||||
final String? token = await userProvider.setAndGetToken();
|
final String? token = await userProvider.setAndGetToken();
|
||||||
print("detected token as $token");
|
|
||||||
|
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
RequestService.token = token;
|
|
||||||
if (!kIsWeb) {
|
if (!kIsWeb) {
|
||||||
await mediaProvider.getDownloadsList();
|
await mediaProvider.getDownloadsList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RequestService.token = token;
|
||||||
|
|
||||||
final result = await userProvider.getUserInfo();
|
final result = await userProvider.getUserInfo();
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
print("no results were returned for user info");
|
|
||||||
try {
|
try {
|
||||||
StorageService.delete(key: 'token');
|
StorageService.delete(key: 'token');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print("error in case of no user info result: $e");
|
|
||||||
// catch
|
// catch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,33 +127,28 @@ class _SplashState extends State<Splash> {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
print("got results for user info: $result");
|
|
||||||
await ServerDataProvider.getData();
|
await ServerDataProvider.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
print("token route is $token");
|
// --- بخش اصلاح شده ---
|
||||||
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 : Routes.home;
|
||||||
// Set showDialogs to false to prevent welcome popups
|
final dynamic routeArguments = token == null ? false : {'showDialogs': true};
|
||||||
dynamic routeArguments = token == null ? {'isResetPassword': false} : {'showDialogs': false};
|
|
||||||
|
|
||||||
|
// اگر لینک ورودی وجود داشت، آن را به عنوان آرگومان به صفحه Home میفرستیم
|
||||||
if (destinationRoute == Routes.home) {
|
if (destinationRoute == Routes.home && initialURI != null) {
|
||||||
print("destination route was home and init uri is $initialURI");
|
(routeArguments as Map)['deepLinkUri'] = initialURI;
|
||||||
// (routeArguments as Map)['deepLinkUri'] = initialURI;
|
initialURI = null; // لینک را مصرف میکنیم تا دوباره استفاده نشود
|
||||||
initialURI = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(destinationRoute == Routes.authenticaion){
|
// در نهایت به مسیر تعیین شده میرویم
|
||||||
print("destination route is auth route");
|
|
||||||
routeArguments = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
print("destination route: $destinationRoute, route args: $routeArguments");
|
|
||||||
await navigatorKey.currentState!.pushReplacementNamed(
|
await navigatorKey.currentState!.pushReplacementNamed(
|
||||||
destinationRoute,
|
destinationRoute,
|
||||||
arguments: routeArguments,
|
arguments: routeArguments,
|
||||||
);
|
);
|
||||||
|
// --- پایان بخش اصلاح شده ---
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_errorOccured = true;
|
_errorOccured = true;
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,12 @@ 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;
|
||||||
|
|
@ -42,24 +40,21 @@ 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) {
|
||||||
// print('❌ WebView resource error: ${error.description} on ${error.failingUrl}'); // Add logging
|
// navigatorKey.currentState!.pop();
|
||||||
},
|
},
|
||||||
onNavigationRequest: (NavigationRequest request) {
|
onNavigationRequest: (NavigationRequest request) {
|
||||||
print('🔀 WebView navigation request to: ${request.url}'); // Add logging
|
// if (request.url.startsWith('https://www.youtube.com/')) {
|
||||||
|
// return NavigationDecision.prevent;
|
||||||
|
// }
|
||||||
return NavigationDecision.navigate;
|
return NavigationDecision.navigate;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -82,7 +77,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(),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ class _DidvanTextFieldState extends State<DidvanTextField> {
|
||||||
? TextDirection.ltr
|
? TextDirection.ltr
|
||||||
: TextDirection.rtl,
|
: TextDirection.rtl,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(kIsWeb?8:4,kIsWeb?4:4,kIsWeb?8:0,kIsWeb?0:8),
|
padding: const EdgeInsets.fromLTRB(kIsWeb?8:8,kIsWeb?4:8,kIsWeb?8:0,kIsWeb?0:8),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
inputFormatters: <TextInputFormatter>[
|
inputFormatters: <TextInputFormatter>[
|
||||||
|
|
|
||||||
7
makefile
7
makefile
|
|
@ -1,9 +1,2 @@
|
||||||
update_js:
|
update_js:
|
||||||
cp ./lib/assets/js/main.js ./build/flutter_assets/lib/assets/js/main.js
|
cp ./lib/assets/js/main.js ./build/flutter_assets/lib/assets/js/main.js
|
||||||
|
|
||||||
zip_web:
|
|
||||||
powershell Compress-Archive -Path build\web\* -DestinationPath build.zip -Force
|
|
||||||
|
|
||||||
build_web:
|
|
||||||
flutter build web
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue