348 lines
9.3 KiB
Dart
348 lines
9.3 KiB
Dart
// ignore_for_file: avoid_print
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:didvan/constants/assets.dart';
|
|
import 'package:didvan/models/category.dart';
|
|
import 'package:didvan/models/enums.dart';
|
|
import 'package:didvan/models/overview_data.dart';
|
|
import 'package:didvan/providers/core.dart';
|
|
import 'package:didvan/routes/routes.dart';
|
|
import 'package:didvan/services/network/request.dart';
|
|
import 'package:didvan/services/network/request_helper.dart';
|
|
import 'package:didvan/services/swot_service.dart'; // اضافه کردن ایمپورت سرویس جدید
|
|
import 'package:flutter/material.dart';
|
|
|
|
class MenuItemType {
|
|
final String label;
|
|
final String asset;
|
|
final String link;
|
|
|
|
MenuItemType({
|
|
required this.label,
|
|
required this.asset,
|
|
required this.link,
|
|
});
|
|
}
|
|
|
|
class HomeState extends CoreProvier {
|
|
int _currentPageIndex = 0;
|
|
String search = '';
|
|
String lastSearch = '';
|
|
Timer? _debounce;
|
|
String? startDate;
|
|
String? endDate;
|
|
int page = 1;
|
|
int lastPage = 1;
|
|
final List<CategoryData> selectedCats = [];
|
|
final List<OverviewData> results = [];
|
|
late TabController tabController;
|
|
int unreadCount = 0;
|
|
final FocusNode searchFieldFocusNode = FocusNode();
|
|
|
|
void onSearchChanged(String query) {
|
|
if (_debounce?.isActive ?? false) _debounce?.cancel();
|
|
|
|
_debounce = Timer(const Duration(milliseconds: 1500), () {
|
|
if (lastSearch != query && query.length >= 2) {
|
|
search = query;
|
|
searchAll(page: 1);
|
|
}
|
|
});
|
|
}
|
|
|
|
void clearSearch() {
|
|
if (_debounce?.isActive ?? false) _debounce?.cancel();
|
|
|
|
search = '';
|
|
lastSearch = '';
|
|
results.clear();
|
|
notifyListeners();
|
|
}
|
|
|
|
|
|
void resetFilters(bool isInit) {
|
|
startDate = null;
|
|
endDate = null;
|
|
selectedCats.clear();
|
|
search = '';
|
|
lastSearch = '';
|
|
if (!isInit) {
|
|
searchAll(page: 1);
|
|
}
|
|
}
|
|
|
|
set currentPageIndex(int value) {
|
|
_currentPageIndex = value;
|
|
notifyListeners();
|
|
}
|
|
|
|
int get currentPageIndex => _currentPageIndex;
|
|
|
|
List<MenuItemType> menuItems = [];
|
|
List<CategoryData> categories = [];
|
|
|
|
bool get filtering =>
|
|
selectedCats.isNotEmpty ||
|
|
startDate != null ||
|
|
endDate != null ||
|
|
search.isNotEmpty;
|
|
|
|
Future<void> searchMarks({required int page}) async {
|
|
this.page = page;
|
|
if (page == 1) {
|
|
results.clear();
|
|
appState = AppState.busy;
|
|
}
|
|
lastSearch = search;
|
|
final service = RequestService(
|
|
RequestHelper.searchAll(
|
|
page: page,
|
|
search: search,
|
|
endDate: endDate,
|
|
types: selectedCats.map((e) => e.id).toList(),
|
|
startDate: startDate,
|
|
),
|
|
);
|
|
await service.httpGet();
|
|
if (service.isSuccess) {
|
|
print("DEBUG : Homestate is succes");
|
|
lastPage = service.result['lastPage'];
|
|
results.addAll(
|
|
List<OverviewData>.from(
|
|
service.result['contents'].map(
|
|
(e) => OverviewData.fromJson(e),
|
|
),
|
|
),
|
|
);
|
|
lastPage = service.result['lastPage'];
|
|
appState = AppState.idle;
|
|
return;
|
|
}
|
|
print("DEBUG : Homestate is NOT succes");
|
|
appState = AppState.failed;
|
|
}
|
|
|
|
Future<void> searchAll({required int page}) async {
|
|
this.page = page;
|
|
if (page == 1) {
|
|
print("DEBUG : serach is busy");
|
|
results.clear();
|
|
appState = AppState.busy;
|
|
}
|
|
lastSearch = search;
|
|
|
|
// بررسی اینکه آیا دسته بندی "بایدها و نبایدها" انتخاب شده است یا خیر
|
|
final isSwotSelected = selectedCats.any((element) => element.id == 8);
|
|
|
|
if (isSwotSelected) {
|
|
// فراخوانی API جدید برای بایدها و نبایدها
|
|
try {
|
|
final swotItems = await SwotService.fetchSwotItems(
|
|
page: page - 1, // API از صفر شروع میشود اما صفحه بندی اپلیکیشن از یک
|
|
title: search,
|
|
size: 15, // هماهنگ با pagination لیست ویو
|
|
);
|
|
|
|
results.addAll(swotItems.map((e) => OverviewData(
|
|
id: e.id,
|
|
title: e.title,
|
|
image: e.imageUrl,
|
|
description: e.description,
|
|
createdAt: e.createdAt,
|
|
type: 'swot', // نوع جدید برای شناسایی در UI
|
|
marked: false,
|
|
liked: false,
|
|
likes: 0,
|
|
comments: 0,
|
|
forManagers: false,
|
|
link: e.imageUrl, // موقتا لینک تصویر را میگذاریم
|
|
)));
|
|
|
|
// منطق ساده برای تشخیص صفحه آخر (اگر تعداد آیتمها کمتر از حد درخواست بود یعنی صفحه آخر است)
|
|
if (swotItems.length < 15) {
|
|
lastPage = page;
|
|
} else {
|
|
lastPage = page + 1;
|
|
}
|
|
|
|
appState = AppState.idle;
|
|
} catch (e) {
|
|
print("Error fetching SWOT items: $e");
|
|
appState = AppState.failed;
|
|
}
|
|
return;
|
|
}
|
|
|
|
// فراخوانی API قدیمی برای سایر موارد
|
|
final service = RequestService(
|
|
RequestHelper.searchAll(
|
|
page: page,
|
|
search: search,
|
|
endDate: endDate,
|
|
types: selectedCats.map((e) => e.id).toList(),
|
|
startDate: startDate,
|
|
),
|
|
);
|
|
await service.httpGet();
|
|
if (service.isSuccess) {
|
|
print("DEBUG : HTTPget Home is succes");
|
|
lastPage = service.result['lastPage'];
|
|
unreadCount = service.result['unread'] ?? unreadCount;
|
|
results.addAll(
|
|
List<OverviewData>.from(
|
|
service.result['contents'].map(
|
|
(e) => OverviewData.fromJson(e),
|
|
),
|
|
),
|
|
);
|
|
lastPage = service.result['lastPage'];
|
|
appState = AppState.idle;
|
|
return;
|
|
}
|
|
print("DEBUG : Homestate is faild");
|
|
appState = AppState.failed;
|
|
}
|
|
|
|
final categoryFilters = [
|
|
CategoryData(id: 1, label: 'پویش افق'),
|
|
CategoryData(id: 2, label: 'دنیای فولاد'),
|
|
CategoryData(id: 3, label: 'رسانه'),
|
|
CategoryData(id: 5, label: 'رادارهای استراتژیک'),
|
|
// CategoryData(id: 6, label: 'سها'), // حذف شده
|
|
CategoryData(id: 8, label: 'بایدها و نبایدها'), // اضافه شده
|
|
CategoryData(id: 7, label: 'ماهنامه تحلیلی'),
|
|
];
|
|
|
|
void refresh() async {
|
|
menuItems = [
|
|
MenuItemType(
|
|
label: 'آمار و داده',
|
|
asset: Assets.stats,
|
|
link: 'tab-3',
|
|
),
|
|
MenuItemType(
|
|
label: 'دنیای فولاد',
|
|
asset: Assets.fooladWorld,
|
|
link: Routes.news,
|
|
),
|
|
MenuItemType(
|
|
label: 'پویش افق',
|
|
asset: Assets.ofogh,
|
|
link: Routes.radars,
|
|
),
|
|
MenuItemType(
|
|
label: 'ویدیوکست',
|
|
asset: Assets.videocast,
|
|
link: Routes.videocasts,
|
|
),
|
|
MenuItemType(
|
|
label: 'پادکست',
|
|
asset: Assets.podcast,
|
|
link: Routes.podcasts,
|
|
),
|
|
MenuItemType(
|
|
label: 'اینفوگرافی',
|
|
asset: Assets.infography,
|
|
link: Routes.infography,
|
|
),
|
|
MenuItemType(
|
|
label: 'رادار روند',
|
|
asset: Assets.trend,
|
|
link: 'https://trend.didvan.app/',
|
|
),
|
|
MenuItemType(
|
|
label: 'رادار تکنولوژی',
|
|
asset: Assets.tech,
|
|
link: 'https://tech.didvan.app/',
|
|
),
|
|
MenuItemType(
|
|
label: 'رادار ریسک',
|
|
asset: Assets.risk,
|
|
link: 'https://risk.didvan.app/',
|
|
),
|
|
MenuItemType(
|
|
label: 'رادار استارتآپ',
|
|
asset: Assets.startup,
|
|
link: 'https://startup.didvan.app/',
|
|
),
|
|
MenuItemType(
|
|
label: 'سها',
|
|
asset: Assets.saha,
|
|
link: 'https://saha.didvan.app/app',
|
|
),
|
|
MenuItemType(
|
|
label: 'هوشان',
|
|
asset: Assets.ai,
|
|
link: Routes.aiSection,
|
|
),
|
|
MenuItemType(
|
|
label: 'فرصت و تهدید',
|
|
asset: Assets.hugeideas,
|
|
link:
|
|
'http://opportunity-threat.didvan.com/?accessToken=${RequestService.token}',
|
|
),
|
|
];
|
|
|
|
categories = [
|
|
CategoryData(
|
|
id: 1,
|
|
label: 'اقتصادی',
|
|
asset: Assets.economicCategoryIcon,
|
|
),
|
|
CategoryData(
|
|
id: 2,
|
|
label: 'سیاسی',
|
|
asset: Assets.politicalCategoryIcon,
|
|
),
|
|
CategoryData(
|
|
id: 3,
|
|
label: 'فناوری',
|
|
asset: Assets.techCategoryIcon,
|
|
),
|
|
CategoryData(
|
|
id: 4,
|
|
label: 'کسب و کار',
|
|
asset: Assets.businessCategoryIcon,
|
|
),
|
|
CategoryData(
|
|
id: 5,
|
|
label: 'زیستمحیطی',
|
|
asset: Assets.enviromentalCategoryIcon,
|
|
),
|
|
CategoryData(
|
|
id: 6,
|
|
label: 'اجتماعی',
|
|
asset: Assets.socialCategoryIcon,
|
|
),
|
|
CategoryData(
|
|
id: 1,
|
|
label: 'اقتصادی',
|
|
asset: Assets.economicCategoryIcon,
|
|
),
|
|
CategoryData(
|
|
id: 2,
|
|
label: 'سیاسی',
|
|
asset: Assets.politicalCategoryIcon,
|
|
),
|
|
CategoryData(
|
|
id: 3,
|
|
label: 'فناوری',
|
|
asset: Assets.techCategoryIcon,
|
|
),
|
|
CategoryData(
|
|
id: 4,
|
|
label: 'کسب و کار',
|
|
asset: Assets.businessCategoryIcon,
|
|
),
|
|
];
|
|
Future.delayed(Duration.zero, notifyListeners);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_debounce?.cancel();
|
|
searchFieldFocusNode.dispose();
|
|
super.dispose();
|
|
}
|
|
} |