LCOV - code coverage report
Current view: top level - src/providers - organizer_provider.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 68 68 100.0 %
Date: 2021-10-03 15:54:23 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:collection';
       2             : 
       3             : import 'package:flutter/material.dart';
       4             : import 'package:widgetbook/src/models/models.dart';
       5             : import 'package:widgetbook/src/models/organizers/organizer_helper/organizer_helper.dart';
       6             : import 'package:widgetbook/src/providers/organizer_state.dart';
       7             : import 'package:widgetbook/src/providers/provider.dart';
       8             : import 'package:widgetbook/src/repositories/selected_story_repository.dart';
       9             : import 'package:widgetbook/src/repositories/story_repository.dart';
      10             : 
      11             : class OrganizerBuilder extends StatefulWidget {
      12             :   final Widget child;
      13             :   final List<Category> categories;
      14             :   final StoryRepository storyRepository;
      15             :   final SelectedStoryRepository selectedStoryRepository;
      16             : 
      17           1 :   const OrganizerBuilder({
      18             :     Key? key,
      19             :     required this.child,
      20             :     required this.categories,
      21             :     required this.storyRepository,
      22             :     required this.selectedStoryRepository,
      23           1 :   }) : super(key: key);
      24             : 
      25           1 :   @override
      26           1 :   _OrganizerBuilderState createState() => _OrganizerBuilderState();
      27             : }
      28             : 
      29             : class _OrganizerBuilderState extends State<OrganizerBuilder> {
      30             :   late OrganizerState state;
      31             :   late OrganizerProvider provider;
      32           1 :   @override
      33             :   void initState() {
      34           2 :     state = OrganizerState.unfiltered(
      35           2 :       categories: widget.categories,
      36             :     );
      37           1 :     setProvider();
      38             : 
      39           5 :     widget.selectedStoryRepository.getStream().forEach((Story? story) {
      40           2 :       provider.openStory(story);
      41             :     });
      42             : 
      43           1 :     super.initState();
      44             :   }
      45             : 
      46           1 :   void setProvider() {
      47           2 :     provider = OrganizerProvider(
      48           2 :       selectedStoryRepository: widget.selectedStoryRepository,
      49           2 :       storyRepository: widget.storyRepository,
      50           1 :       state: state,
      51           1 :       onStateChanged: (OrganizerState state) {
      52           2 :         setState(() {
      53           1 :           this.state = state;
      54           1 :           setProvider();
      55             :         });
      56             :       },
      57           2 :       child: widget.child,
      58             :     );
      59             :   }
      60             : 
      61           1 :   @override
      62             :   Widget build(BuildContext context) {
      63           1 :     return provider;
      64             :   }
      65             : }
      66             : 
      67             : class OrganizerProvider extends Provider<OrganizerState> {
      68             :   final SelectedStoryRepository selectedStoryRepository;
      69             :   final StoryRepository storyRepository;
      70             : 
      71           1 :   const OrganizerProvider({
      72             :     required this.selectedStoryRepository,
      73             :     required this.storyRepository,
      74             :     required OrganizerState state,
      75             :     required ValueChanged<OrganizerState> onStateChanged,
      76             :     required Widget child,
      77             :     Key? key,
      78           1 :   }) : super(
      79             :           state: state,
      80             :           onStateChanged: onStateChanged,
      81             :           child: child,
      82             :           key: key,
      83             :         );
      84             : 
      85           1 :   static OrganizerProvider? of(BuildContext context) {
      86           1 :     return context.dependOnInheritedWidgetOfExactType<OrganizerProvider>();
      87             :   }
      88             : 
      89           1 :   void openStory(Story? story) {
      90             :     if (story == null) {
      91             :       return;
      92             :     }
      93             :     ExpandableOrganizer? currentOrganizer =
      94           1 :         story.parent as ExpandableOrganizer?;
      95             :     while (currentOrganizer != null) {
      96           1 :       currentOrganizer.isExpanded = true;
      97           1 :       currentOrganizer = currentOrganizer.parent as ExpandableOrganizer?;
      98             :     }
      99             :   }
     100             : 
     101           1 :   void _updateFolders(List<Category> categories) {
     102           1 :     var oldFolders = FolderHelper.getAllFoldersFromCategories(
     103           2 :       state.allCategories,
     104             :     );
     105           1 :     var newFolders = FolderHelper.getAllFoldersFromCategories(
     106             :       categories,
     107             :     );
     108           1 :     var oldFolderMap = HashMap<String, Folder>.fromIterable(
     109             :       oldFolders,
     110           2 :       key: (k) => k.path,
     111           1 :       value: (v) => v,
     112             :     );
     113             : 
     114           2 :     for (var folder in newFolders) {
     115           1 :       var path = folder.path;
     116           1 :       if (oldFolderMap.containsKey(path)) {
     117           3 :         folder.isExpanded = oldFolderMap[path]!.isExpanded;
     118             :       }
     119             :     }
     120             :   }
     121             : 
     122           1 :   void _updateWidgets(List<Category> categories) {
     123           1 :     var oldWidgets = WidgetHelper.getAllWidgetElementsFromCategories(
     124           2 :       state.allCategories,
     125             :     );
     126           1 :     var newWidgets = WidgetHelper.getAllWidgetElementsFromCategories(
     127             :       categories,
     128             :     );
     129           1 :     var oldFolderMap = HashMap<String, WidgetElement>.fromIterable(
     130             :       oldWidgets,
     131           2 :       key: (k) => k.path,
     132           1 :       value: (v) => v,
     133             :     );
     134             : 
     135           2 :     for (var widget in newWidgets) {
     136           1 :       var path = widget.path;
     137           1 :       if (oldFolderMap.containsKey(path)) {
     138           3 :         widget.isExpanded = oldFolderMap[path]!.isExpanded;
     139             :       }
     140             :     }
     141             :   }
     142             : 
     143           1 :   void update(List<Category> categories) {
     144           1 :     _updateFolders(categories);
     145           1 :     _updateWidgets(categories);
     146           1 :     emit(
     147           1 :       OrganizerState.unfiltered(categories: categories),
     148             :     );
     149             : 
     150           1 :     var stories = StoryHelper.getAllStoriesFromCategories(categories);
     151           2 :     storyRepository.deleteAll();
     152           2 :     storyRepository.addAll(stories);
     153             :   }
     154             : 
     155             :   // The filter methods are used to implement a search of organizer elements
     156             :   // since no UI element and no tests exist, this functionality
     157             :   // is currently disabled
     158             :   //
     159             :   // void resetFilter() {
     160             :   //   emit(
     161             :   //     OrganizerState.unfiltered(
     162             :   //       categories: state.allCategories,
     163             :   //     ),
     164             :   //   );
     165             :   // }
     166             : 
     167             :   // void filter(RegExp regExp) {
     168             :   //   var categories = _filterCategories(
     169             :   //     regExp,
     170             :   //     state.allCategories,
     171             :   //   );
     172             : 
     173             :   //   emit(
     174             :   //     OrganizerState(
     175             :   //       allCategories: state.allCategories,
     176             :   //       filteredCategories: categories,
     177             :   //       searchTerm: regExp.pattern,
     178             :   //     ),
     179             :   //   );
     180             :   // }
     181             : 
     182             :   // List<Category> _filterCategories(
     183             :   //   RegExp regExp,
     184             :   //   List<Category> categories,
     185             :   // ) {
     186             :   //   List<Category> matchingOrganizers = <Category>[];
     187             :   //   for (var category in categories) {
     188             :   //     Category? result = _filterOrganizer(regExp, category) as Category?;
     189             :   //     if (_isMatch(result)) {
     190             :   //       matchingOrganizers.add(result!);
     191             :   //     }
     192             :   //   }
     193             :   //   return matchingOrganizers;
     194             :   // }
     195             : 
     196             :   // ExpandableOrganizer? _filterOrganizer(
     197             :   //     RegExp regExp, ExpandableOrganizer organizer) {
     198             :   //   if (organizer.name.contains(regExp)) {
     199             :   //     return organizer;
     200             :   //   }
     201             : 
     202             :   //   List<Folder> matchingFolders = <Folder>[];
     203             :   //   for (var subOrganizer in organizer.folders) {
     204             :   //     ExpandableOrganizer? result = _filterOrganizer(regExp, subOrganizer);
     205             :   //     if (_isMatch(result)) {
     206             :   //       matchingFolders.add(result! as Folder);
     207             :   //     }
     208             :   //   }
     209             : 
     210             :   //   List<WidgetElement> matchingWidgets = <WidgetElement>[];
     211             :   //   for (var subOrganizer in organizer.widgets) {
     212             :   //     ExpandableOrganizer? result = _filterOrganizer(regExp, subOrganizer);
     213             :   //     if (_isMatch(result)) {
     214             :   //       matchingWidgets.add(result! as WidgetElement);
     215             :   //     }
     216             :   //   }
     217             : 
     218             :   //   if (matchingFolders.isNotEmpty) {
     219             :   //     return _createFilteredSubtree(
     220             :   //       organizer,
     221             :   //       matchingFolders,
     222             :   //       matchingWidgets,
     223             :   //     );
     224             :   //   }
     225             : 
     226             :   //   return null;
     227             :   // }
     228             : 
     229             :   // ExpandableOrganizer _createFilteredSubtree(
     230             :   //   ExpandableOrganizer organizer,
     231             :   //   List<Folder> folders,
     232             :   //   List<WidgetElement> widgets,
     233             :   // ) {
     234             :   //   if (organizer is Category) {
     235             :   //     return Category(
     236             :   //       name: organizer.name,
     237             :   //       widgets: widgets,
     238             :   //       folders: folders,
     239             :   //     );
     240             :   //   }
     241             :   //   if (organizer is Folder) {
     242             :   //     return Folder(
     243             :   //       name: organizer.name,
     244             :   //       widgets: widgets,
     245             :   //       folders: folders,
     246             :   //     );
     247             :   //   } else {
     248             :   //     // TODO remove this when tested
     249             :   //     // ignore: avoid_print
     250             :   //     print('This message should never appear - BUG!');
     251             :   //     return Folder(name: 'If you see this, you have found a bug');
     252             :   //   }
     253             :   // }
     254             : 
     255             :   // bool _isMatch(ExpandableOrganizer? organizer) {
     256             :   //   return organizer != null;
     257             :   // }
     258             : 
     259           1 :   void toggleExpander(ExpandableOrganizer organizer) {
     260           2 :     organizer.isExpanded = !organizer.isExpanded;
     261           1 :     emit(
     262           1 :       OrganizerState(
     263           2 :         allCategories: state.allCategories,
     264           2 :         filteredCategories: state.filteredCategories,
     265           2 :         searchTerm: state.searchTerm,
     266             :       ),
     267             :     );
     268             :   }
     269             : }

Generated by: LCOV version 1.15