import 'package:base_architecture/data_layer/api/api_provider.dart';
import 'package:base_architecture/data_layer/models/api_models/Dto/categories_selections.dart';
import 'package:base_architecture/data_layer/models/api_models/books_models/book_model.dart';
import 'package:base_architecture/data_layer/models/api_models/categories_model.dart';
import 'package:base_architecture/data_layer/models/api_models/translated_name_model.dart';
import 'package:base_architecture/presentation/pages/categories/widgets/all_categories.dart';
import 'package:base_architecture/presentation/pages/categories/widgets/latest_versions.dart';
import 'package:base_architecture/presentation/pages/categories/widgets/marks.dart';
import 'package:base_architecture/presentation/pages/categories/widgets/others.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:rx_shared_preferences/rx_shared_preferences.dart';
class CategoriesNotifier extends ChangeNotifier {
//Main tabs
final List<Tab> _tabs = [
const Tab(child: Text('الفئات')),
const Tab(child: Text('العلامات')),
const Tab(child: Text('أحدث الاصدارات')),
const Tab(child: Text('أخرى')),
];
CategoriesItem firstSubCategory = CategoriesItem(
id: null,
translatedName: TranslatedNameModel(
catNameAr: 'الكل',
catNameEn: 'All',
catNameHe: 'All',
),
imageFullPath: '',
soundFullPath: '',
mainCategoryBooks: [],
);
CategoriesModel _mainCategories = CategoriesModel();
CategoriesSelections _selections = CategoriesSelections();
CategoriesModel get mainCategories => _mainCategories;
CategoriesSelections get selections => _selections;
final List<Book> _moreRecentlyAdded = [];
List<Book> get moreRecentlyAdded => _moreRecentlyAdded;
final List<Book> _moreForYou = [];
List<Book> get moreForYou => _moreForYou;
final List<Book> _moreWritersChoices = [];
List<Book> get moreWritersChoices => _moreWritersChoices;
final List<Book> _moreMostRead = [];
List<Book> get moreMostRead => _moreMostRead;
final List<Book> _moreDisplayedCategoriesBooks = [];
List<Book> get moreDisplayedCategoriesBooks => _moreDisplayedCategoriesBooks;
List<Tab> get tabs => _tabs;
//Main Tabs
//Main pages
final List<Widget> _pages = [
const AllCategories(),
const Marks(),
const LatestVersions(),
const OthersPage(),
];
List<Widget> get pages => _pages;
//Main pages
//Secondary Tabs
final List<CategoriesItem> _secTabs0 = [
CategoriesItem(
id: null,
translatedName: TranslatedNameModel(
catNameAr: 'الكل',
catNameEn: 'All',
catNameHe: 'All',
),
imageFullPath: '',
soundFullPath: '',
mainCategoryBooks: [],
)
];
List<CategoriesItem> _rxAllCategoriesTab = [
CategoriesItem(
id: null,
translatedName: TranslatedNameModel(
catNameAr: 'الكل',
catNameEn: 'All',
catNameHe: 'All',
),
imageFullPath: '',
soundFullPath: '',
mainCategoryBooks: [],
)
];
List<CategoriesItem> _rxNewestCategoriesTab = [
CategoriesItem(
id: null,
translatedName: TranslatedNameModel(
catNameAr: 'الكل',
catNameEn: 'All',
catNameHe: 'All',
),
imageFullPath: '',
soundFullPath: '',
mainCategoryBooks: [],
)
];
List<CategoriesItem> get rxAllCategoriesTab => _rxAllCategoriesTab;
List<CategoriesItem> get rxNewestCategoriesTab => _rxNewestCategoriesTab;
List<CategoriesItem> get secTabs0 => _secTabs0;
final List<String> _moreCategory = [
'الكل',
'أطفال',
'رعب',
'خيال علمي',
'تنمية بشرية',
];
List<String> get moreCategory => _moreCategory;
final List<String> _secTagsAr = [
'الكل',
'أ',
'ب',
'ت',
'ث',
'ج',
'ح',
'خ',
'د',
'ذ',
'ر',
'ز',
'س',
'ش',
'ص',
'ض',
'ط',
'ظ',
'ع',
'غ',
'ف',
'ق',
'ك',
'ل',
'م',
'ن',
'ه',
'و',
'ي',
];
List<String> get secTagsAr => _secTagsAr;
final List<String> _secTagsEn = [
'All'
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
];
List<String> get secTagsEn => _secTagsEn;
final List<String> _secTabs2 = [
'أطفال',
'رعب',
'خيال علمي',
'قصص',
'تنمية بشرية',
];
List<String> get secTabs2 => _secTabs2;
final List<String> _secTabs3 = [
'الكُتّاب',
'القُرّاء',
'المترجمين',
'دور النشر',
];
List<String> get secTabs3 => _secTabs3;
//set selected indes
bool isLoading = false;
int _myIndex = 0;
int get myIndex => _myIndex;
int _categoriesTabIndex = 0;
int get categoriesTabIndex => _categoriesTabIndex;
int _tagsTabIndex = 0;
int get tagsTabIndex => _tagsTabIndex;
int _recentTabIndex = 0;
int get recentTabIndex => _recentTabIndex;
int _otherTabIndex = 0;
int get otherTabIndex => _otherTabIndex;
int _moreCategoryIndex = 0;
int get moreCategoryIndex => _moreCategoryIndex;
// There is next page or not
bool _hasNextPage = true;
bool get hasNextPage => _hasNextPage;
bool _isFirstLoadRunning = false;
bool get isFirstLoadRunning => _isFirstLoadRunning;
bool _isLoadMoreRunning = false;
bool get isLoadMoreRunning => _isLoadMoreRunning;
int _pageIndex = 0;
int get pageIndex => _pageIndex;
setIndex(int value) {
_myIndex = value;
notifyListeners();
}
setCategoriesTabIndex(int value) {
_categoriesTabIndex = value;
notifyListeners();
}
setTagsTabIndex(int value) {
_tagsTabIndex = value;
notifyListeners();
}
setRecentTabIndex(int value) {
_recentTabIndex = value;
notifyListeners();
}
setOtherTabIndex(int value) {
_otherTabIndex = value;
notifyListeners();
}
setMoreCategoryIndex(int value) {
_moreCategoryIndex = value;
notifyListeners();
}
getSeeMoreRecentBooks() async {
await ApiProvider(httpClient: Dio()).seeMoreRecentBooks().then(
(value) {
setRecentBooks(value.data!.first.books!);
},
);
}
void setRecentBooks(List<Book> books) {
_moreRecentlyAdded.clear();
for (var element in books) {
_moreRecentlyAdded.add(element);
}
notifyListeners();
}
getSeeMoreForYouBooks() async {
await ApiProvider(httpClient: Dio()).seeMoreForYouBooks().then(
(value) {
setForYouBooks(value.data!.first.books!);
},
);
}
void setForYouBooks(List<Book> books) {
_moreForYou.clear();
for (var element in books) {
_moreForYou.add(element);
}
notifyListeners();
}
getSeeMoreWriterChoicesBooks() async {
await ApiProvider(httpClient: Dio()).seeMoreWritersBooks().then(
(value) {
setWriterChoicesBooks(value.data!.first.books!);
},
);
}
void setWriterChoicesBooks(List<Book> books) {
_moreWritersChoices.clear();
for (var element in books) {
_moreWritersChoices.add(element);
}
notifyListeners();
}
getSeeMoreMostReadBooks() async {
await ApiProvider(httpClient: Dio()).seeMoreMostReadBooks().then(
(value) {
setMostReadBooks(value.data!.first.books!);
},
);
}
void setMostReadBooks(List<Book> books) {
_moreMostRead.clear();
for (var element in books) {
_moreMostRead.add(element);
}
notifyListeners();
}
ScrollController categoriesScrollController = ScrollController();
ScrollController tagsScrollController = ScrollController();
ScrollController newestScrollController = ScrollController();
ScrollController othersScrollController = ScrollController();
// There is next page or not
List<CategoriesItem> _categories = [];
List<CategoriesItem> get categories => _categories;
getAllCategories(CategoriesSelections selections) async {
isLoading = true;
WidgetsBinding.instance.addPostFrameCallback((_) {
notifyListeners();
});
await ApiProvider(httpClient: Dio())
.getAllCategories(selections, _pageIndex)
.then(
(value) {
setCategories(value.data!.categories ?? []);
_mainCategories = value;
isLoading = false;
notifyListeners();
_isFirstLoadRunning = false;
},
).catchError((error) {
isLoading = false;
notifyListeners();
});
}
void setCategories(List<CategoriesItem> newCategories) async {
_secTabs0.clear();
_secTabs0.add(firstSubCategory);
for (var element in newCategories) {
_secTabs0.add(element);
}
await saveToSP();
_pageIndex = _pageIndex + 5;
if (newCategories.isNotEmpty) {
_categories.addAll(newCategories);
_isLoadMoreRunning = false;
_hasNextPage = true;
} else {
// This means there is no more data
// and therefore, we will not send another api request
_hasNextPage = false;
_isLoadMoreRunning = false;
}
_isFirstLoadRunning = false;
}
resetPageIndex() {
_pageIndex = 0;
}
Future<void> saveToSP() async {
final rxPrefs = await RxSharedPreferences.getInstance();
if (selections.type == 'category') {
String? exist = await rxPrefs.getString('all_categories');
if (exist == null && _rxAllCategoriesTab.length != _secTabs0) {
//Store categories in Shared preferences
final String allCategoriesTabEncoded = CategoriesItem.encode(_secTabs0);
await rxPrefs.setString('all_categories', allCategoriesTabEncoded);
}
} else if (selections.type == 'newest') {
String? exist = await rxPrefs.getString('newest_category');
if (exist == null && _rxNewestCategoriesTab.length != _secTabs0) {
//Store categories in Shared preferences
final String newestCategoriesTabEncoded =
CategoriesItem.encode(_secTabs0);
await rxPrefs.setString('newest_category', newestCategoriesTabEncoded);
}
}
//extract categories from Shared preferences
final String? rxAllTab = await rxPrefs.getString('all_categories');
final String? rxNewestTab = await rxPrefs.getString('newest_category');
_rxAllCategoriesTab = CategoriesItem.decode(rxAllTab ?? '');
_rxNewestCategoriesTab = CategoriesItem.decode(rxNewestTab ?? '');
}
void setIsLoadMoreRunning(bool value) {
_isLoadMoreRunning = value;
notifyListeners();
}
}