Skip to content

Commit 137ab67

Browse files
committed
feat: calendar yee
1 parent f68956a commit 137ab67

File tree

3 files changed

+114
-32
lines changed

3 files changed

+114
-32
lines changed

lib/Screens/Calendar/Calendar.dart

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class CalendarScreen extends StatefulWidget {
1212

1313
class CalendarScreenState extends State<CalendarScreen> {
1414
final _viewModel = Get.put(CalendarViewModel());
15-
15+
bool showOnlyLibrary = false;
1616
@override
1717
void initState() {
1818
super.initState();
@@ -38,6 +38,21 @@ class CalendarScreenState extends State<CalendarScreen> {
3838
overflow: TextOverflow.ellipsis,
3939
),
4040
iconTheme: IconThemeData(color: theme.primary),
41+
actions: [
42+
IconButton(
43+
icon: Icon(
44+
showOnlyLibrary
45+
? Icons.collections_bookmark
46+
: Icons.library_books,
47+
),
48+
onPressed: () {
49+
setState(() {
50+
showOnlyLibrary = !showOnlyLibrary;
51+
});
52+
_viewModel.loadAll(showOnlyLibrary: showOnlyLibrary);
53+
},
54+
),
55+
],
4156
),
4257

4358
body: Obx((){
@@ -49,7 +64,7 @@ class CalendarScreenState extends State<CalendarScreen> {
4964
return const Center(child: Text('No data available'));
5065
}
5166

52-
return CalendarTabs(viewModel: _viewModel);
67+
return CalendarTabs(data: _viewModel.calendarData.value!,);
5368
}),
5469
);
5570
}
Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,37 @@
1-
import 'package:flutter/foundation.dart';
1+
import 'package:flutter/gestures.dart';
22
import 'package:flutter/material.dart';
3+
4+
import '../../Adaptor/Media/MediaAdaptor.dart';
5+
import '../../DataClass/Media.dart';
36
import '../../Widgets/ScrollConfig.dart';
4-
import 'CalendarViewModel.dart';
57

6-
class CalendarTabs extends StatefulWidget{
7-
final CalendarViewModel viewModel;
8+
class CalendarTabs extends StatefulWidget {
9+
final Map<String, List<media>> data;
810

9-
const CalendarTabs({super.key,required this.viewModel});
11+
const CalendarTabs({super.key, required this.data});
1012

1113
@override
1214
CalendarTabsState createState() => CalendarTabsState();
1315
}
1416

15-
16-
class CalendarTabsState extends State<CalendarTabs> with TickerProviderStateMixin {
17+
class CalendarTabsState extends State<CalendarTabs>
18+
with TickerProviderStateMixin {
1719
TabController? _tabController;
1820

1921
@override
2022
void initState() {
2123
super.initState();
2224
_tabController = TabController(
23-
length: widget.viewModel.calendarData.value!.length,
25+
length: widget.data.keys.length,
2426
vsync: this,
2527
);
2628
}
2729

2830
@override
2931
void didUpdateWidget(CalendarTabs oldWidget) {
3032
super.didUpdateWidget(oldWidget);
31-
var mediaListOld = oldWidget.viewModel.calendarData.value!;
32-
var mediaListNew = widget.viewModel.calendarData.value!;
33+
var mediaListOld = oldWidget.data.values;
34+
var mediaListNew = widget.data.values;
3335
if (mediaListOld.length != mediaListNew.length) {
3436
_tabController?.dispose();
3537
_tabController = TabController(
@@ -39,26 +41,54 @@ class CalendarTabsState extends State<CalendarTabs> with TickerProviderStateMixi
3941
}
4042
}
4143

42-
4344
@override
4445
Widget build(BuildContext context) {
45-
var calendarData = widget.viewModel.calendarData.value!;
46-
if (kDebugMode) {
47-
print(calendarData);
48-
49-
}var theme = Theme.of(context).colorScheme;
50-
return ScrollConfig(
51-
context,
46+
var calendarData = widget.data;
47+
var theme = Theme.of(context).colorScheme;
48+
return ScrollConfig(context,
5249
child: DefaultTabController(
53-
length: calendarData.length,
54-
child: const Column(
50+
length: calendarData.keys.length,
51+
child: Column(
5552
crossAxisAlignment: CrossAxisAlignment.center,
5653
mainAxisAlignment: MainAxisAlignment.center,
5754
children: [
58-
Text("tabs")
55+
TabBar(
56+
indicatorSize: TabBarIndicatorSize.label,
57+
isScrollable: true,
58+
dragStartBehavior: DragStartBehavior.start,
59+
controller: _tabController,
60+
labelStyle: const TextStyle(
61+
fontFamily: 'Poppins',
62+
fontWeight: FontWeight.bold,
63+
fontSize: 14.0,
64+
),
65+
unselectedLabelStyle: TextStyle(
66+
fontFamily: 'Poppins',
67+
fontWeight: FontWeight.bold,
68+
fontSize: 14.0,
69+
color: theme.onSurface.withOpacity(0.48),
70+
),
71+
tabs: calendarData.keys.map((String tabTitle) {
72+
return Tab(
73+
text:
74+
'${tabTitle.toUpperCase()} (${calendarData[tabTitle]!.length})');
75+
}).toList(),
76+
),
77+
Expanded(
78+
child: TabBarView(
79+
controller: _tabController,
80+
children: calendarData.keys.map((String tabTitle) {
81+
return SingleChildScrollView(
82+
child: MediaAdaptor(
83+
mediaList: calendarData[tabTitle]!,
84+
type: 3,
85+
isLarge: true,
86+
),
87+
);
88+
}).toList(),
89+
),
90+
),
5991
],
60-
)
61-
)
62-
);
92+
)));
6393
}
6494
}
Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,58 @@
11
import 'package:get/get_rx/src/rx_types/rx_types.dart';
22
import 'package:get/get_state_manager/src/simple/get_controllers.dart';
3+
import 'package:intl/intl.dart';
34

45
import '../../DataClass/Media.dart';
56
import '../../api/Anilist/Anilist.dart';
67

78
class CalendarViewModel extends GetxController {
8-
var calendarData = Rxn<List<media>>();
9+
var calendarData = Rxn<Map<String, List<media>>>();
10+
var calendar = RxMap<String, List<media>>();
11+
12+
Map<String, List<media>>? cachedAllCalendarData;
13+
Map<String, List<media>>? cachedLibraryCalendarData;
914
var isLoading = false.obs;
10-
Future<void> loadAll() async {
15+
Future<void> loadAll({bool showOnlyLibrary = false}) async {
1116
try{
1217
isLoading.value = true;
13-
var res = await Anilist.query
14-
.getCalendarData();
15-
calendarData.value = res;
16-
// print(res);
18+
if (cachedAllCalendarData == null || cachedLibraryCalendarData == null) {
19+
final res = await Anilist.query.getCalendarData();
20+
21+
final DateFormat df = DateFormat.yMMMMEEEEd();
22+
final Map<String, List<media>> allMap = {};
23+
final Map<String, List<media>> libraryMap = {};
24+
final Map<String, List<int>> idMap = {};
25+
26+
final int userId = Anilist.userid ?? 0;
27+
final userLibrary = await Anilist.query.getMediaLists(userId: userId, anime: true);
28+
final libraryMediaIds = userLibrary.values.expand((list) => list).map((m) => m.id).toList();
29+
30+
for (var item in res) {
31+
final List<int> v = item.relation?.split(",").map((e) => int.parse(e)).toList() ?? [];
32+
final String dateInfo = df.format(DateTime.fromMillisecondsSinceEpoch(v[1] * 1000));
33+
34+
final list = allMap.putIfAbsent(dateInfo, () => []);
35+
final List<media>? libraryList = libraryMediaIds.contains(item.id) ? libraryMap.putIfAbsent(dateInfo, () => []) : null;
36+
final idList = idMap.putIfAbsent(dateInfo, () => []);
37+
38+
item.relation = "Episode ${v[0]}";
39+
if (!idList.contains(item.id)) {
40+
idList.add(item.id);
41+
list.add(item);
42+
libraryList?.add(item);
43+
}
44+
}
45+
46+
cachedAllCalendarData = allMap;
47+
cachedLibraryCalendarData = libraryMap;
48+
}
49+
50+
calendarData.value = (showOnlyLibrary ? cachedLibraryCalendarData ?? {} : cachedAllCalendarData ?? {});
1751
}finally{
1852
isLoading.value = false;
1953
}
2054
}
55+
56+
57+
2158
}

0 commit comments

Comments
 (0)