Sonnat Project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
3.1 KiB

1 year ago
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:math';
  4. import 'package:flutter/services.dart';
  5. import 'package:flutter_bloc/flutter_bloc.dart';
  6. import 'package:sonnat/core/utils/base_cubit_type.dart';
  7. import 'package:sonnat/features/single_post/view_models/post.dart';
  8. class PostsCubit extends Cubit<BaseCubitType<PostsState>> {
  9. List<Post> allData = [];
  10. List<Post> postList = [];
  11. List<Post> searchedList = [];
  12. bool hasReachedMax = false;
  13. String _query = '';
  14. PostsCubit() : super(BaseCubitType(eventName: PostsState.empty));
  15. void empty() => emit(BaseCubitType(eventName: PostsState.empty));
  16. Future<void> getData() async {
  17. if (hasReachedMax) {
  18. return;
  19. }
  20. if (postList.isNotEmpty) {
  21. emit(BaseCubitType(eventName: PostsState.loadingPagination));
  22. } else {
  23. emit(BaseCubitType(eventName: PostsState.loading));
  24. }
  25. String data = await rootBundle.loadString('assets/meta/data.json');
  26. allData = List<Post>.from(
  27. jsonDecode(data)['posts'].map(
  28. (post) => Post.fromJson(post).copyWith(DateTime.now().millisecondsSinceEpoch),
  29. ),
  30. );
  31. if (allData.isNotEmpty) {
  32. List<Post> posts = allData.getRange(postList.length, min(postList.length + 20, allData.length)).toList();
  33. hasReachedMax = posts.length < 20;
  34. postList += posts;
  35. emit(BaseCubitType(eventName: PostsState.data));
  36. } else {
  37. emit(BaseCubitType(eventName: PostsState.data));
  38. }
  39. }
  40. Future<void> search({required String query}) async {
  41. if (query.isEmpty) {
  42. unawaited(getData());
  43. _query = '';
  44. searchedList.clear();
  45. emit(BaseCubitType(eventName: PostsState.data));
  46. return;
  47. }
  48. if (_query != query) {
  49. hasReachedMax = false;
  50. searchedList.clear();
  51. _query = query;
  52. }
  53. if (hasReachedMax) {
  54. return;
  55. }
  56. if (searchedList.isNotEmpty) {
  57. emit(BaseCubitType(eventName: PostsState.loadingPagination));
  58. } else {
  59. emit(BaseCubitType(eventName: PostsState.loading));
  60. }
  61. await Future.delayed(Duration(milliseconds: Random().nextInt(1000)));
  62. String data = await rootBundle.loadString('assets/meta/data.json');
  63. allData = List<Post>.from(
  64. jsonDecode(data)['posts'].map(
  65. (post) => Post.fromJson(post).copyWith(
  66. DateTime.now().millisecondsSinceEpoch,
  67. ),
  68. ),
  69. );
  70. if (allData.isNotEmpty) {
  71. List<Post> posts = allData.where((element) => element.name.contains(query.trim())).toList();
  72. hasReachedMax = posts.length < 20;
  73. searchedList += posts;
  74. emit(BaseCubitType(eventName: PostsState.data));
  75. } else {
  76. emit(BaseCubitType(eventName: PostsState.data));
  77. }
  78. }
  79. String get query => _query;
  80. void clearSearch() {
  81. unawaited(getData());
  82. _query = '';
  83. searchedList.clear();
  84. emit(BaseCubitType(eventName: PostsState.data));
  85. }
  86. Future<void> changeFilter(int index) async {
  87. emit(BaseCubitType(eventName: PostsState.changeFilterIndex, data: index));
  88. await Future.delayed(Duration(milliseconds: Random().nextInt(1000)));
  89. await getData();
  90. }
  91. }
  92. enum PostsState {
  93. empty,
  94. data,
  95. loading,
  96. loadingPagination,
  97. changeFilterIndex,
  98. }