home_widget.dart 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import 'dart:async';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter/widgets.dart';
  5. import 'package:photos/core/event_bus.dart';
  6. import 'package:photos/events/local_photos_updated_event.dart';
  7. import 'package:photos/models/filters/important_items_filter.dart';
  8. import 'package:photos/models/file.dart';
  9. import 'package:photos/file_repository.dart';
  10. import 'package:photos/models/selected_files.dart';
  11. import 'package:photos/photo_sync_manager.dart';
  12. import 'package:photos/ui/device_folders_gallery_widget.dart';
  13. import 'package:photos/ui/gallery.dart';
  14. import 'package:photos/ui/gallery_app_bar_widget.dart';
  15. import 'package:photos/ui/loading_photos_widget.dart';
  16. import 'package:photos/ui/loading_widget.dart';
  17. import 'package:photos/ui/memories_widget.dart';
  18. import 'package:photos/ui/remote_folder_gallery_widget.dart';
  19. import 'package:photos/ui/search_page.dart';
  20. import 'package:photos/utils/logging_util.dart';
  21. import 'package:shake/shake.dart';
  22. import 'package:logging/logging.dart';
  23. class HomeWidget extends StatefulWidget {
  24. final String title;
  25. const HomeWidget(this.title, {Key key}) : super(key: key);
  26. @override
  27. State<StatefulWidget> createState() => _HomeWidgetState();
  28. }
  29. class _HomeWidgetState extends State<HomeWidget> {
  30. static final importantItemsFilter = ImportantItemsFilter();
  31. final _logger = Logger("HomeWidgetState");
  32. final _remoteFolderGalleryWidget = RemoteFolderGalleryWidget();
  33. final _deviceFolderGalleryWidget = DeviceFolderGalleryWidget();
  34. final _selectedFiles = SelectedFiles();
  35. final _memoriesWidget = MemoriesWidget();
  36. ShakeDetector _detector;
  37. int _selectedNavBarItem = 0;
  38. StreamSubscription<LocalPhotosUpdatedEvent>
  39. _localPhotosUpdatedEventSubscription;
  40. @override
  41. void initState() {
  42. _detector = ShakeDetector.autoStart(
  43. shakeThresholdGravity: 3,
  44. onPhoneShake: () {
  45. _logger.info("Emailing logs");
  46. LoggingUtil.instance.emailLogs();
  47. });
  48. _localPhotosUpdatedEventSubscription =
  49. Bus.instance.on<LocalPhotosUpdatedEvent>().listen((event) {
  50. setState(() {});
  51. });
  52. super.initState();
  53. }
  54. @override
  55. Widget build(BuildContext context) {
  56. return Scaffold(
  57. appBar: GalleryAppBarWidget(
  58. GalleryAppBarType.homepage,
  59. widget.title,
  60. _selectedFiles,
  61. "/",
  62. ),
  63. bottomNavigationBar: _buildBottomNavigationBar(),
  64. body: IndexedStack(
  65. children: <Widget>[
  66. PhotoSyncManager.instance.hasScannedDisk()
  67. ? _getMainGalleryWidget()
  68. : LoadingPhotosWidget(),
  69. _deviceFolderGalleryWidget,
  70. _remoteFolderGalleryWidget,
  71. ],
  72. index: _selectedNavBarItem,
  73. ),
  74. floatingActionButton: FloatingActionButton(
  75. onPressed: () {
  76. Navigator.of(context).push(
  77. MaterialPageRoute(
  78. builder: (BuildContext context) {
  79. return SearchPage();
  80. },
  81. ),
  82. );
  83. },
  84. child: Icon(
  85. Icons.search,
  86. size: 28,
  87. ),
  88. elevation: 1,
  89. backgroundColor: Colors.black38,
  90. foregroundColor: Theme.of(context).accentColor,
  91. ),
  92. );
  93. }
  94. Widget _getMainGalleryWidget() {
  95. return FutureBuilder(
  96. future: FileRepository.instance.loadFiles().then((files) {
  97. return _getFilteredPhotos(files);
  98. }),
  99. builder: (context, snapshot) {
  100. if (snapshot.hasData) {
  101. return Gallery(
  102. syncLoader: () {
  103. return _getFilteredPhotos(FileRepository.instance.files);
  104. },
  105. reloadEvent: Bus.instance.on<LocalPhotosUpdatedEvent>(),
  106. onRefresh: PhotoSyncManager.instance.sync,
  107. tagPrefix: "home_gallery",
  108. selectedFiles: _selectedFiles,
  109. headerWidget: _memoriesWidget,
  110. );
  111. } else if (snapshot.hasError) {
  112. return Center(child: Text(snapshot.error.toString()));
  113. } else {
  114. return loadWidget;
  115. }
  116. },
  117. );
  118. }
  119. BottomNavigationBar _buildBottomNavigationBar() {
  120. return BottomNavigationBar(
  121. items: const <BottomNavigationBarItem>[
  122. BottomNavigationBarItem(
  123. icon: Icon(Icons.photo_library),
  124. title: Text('Photos'),
  125. ),
  126. BottomNavigationBarItem(
  127. icon: Icon(Icons.folder),
  128. title: Text('Folders'),
  129. ),
  130. BottomNavigationBarItem(
  131. icon: Icon(Icons.folder_shared),
  132. title: Text('Shared'),
  133. ),
  134. ],
  135. currentIndex: _selectedNavBarItem,
  136. selectedItemColor: Theme.of(context).accentColor,
  137. onTap: (index) {
  138. setState(() {
  139. _selectedNavBarItem = index;
  140. });
  141. },
  142. );
  143. }
  144. List<File> _getFilteredPhotos(List<File> unfilteredFiles) {
  145. _logger.info("Filtering " + unfilteredFiles.length.toString());
  146. final List<File> filteredPhotos = List<File>();
  147. for (File file in unfilteredFiles) {
  148. if (importantItemsFilter.shouldInclude(file)) {
  149. filteredPhotos.add(file);
  150. }
  151. }
  152. _logger.info("Filtered down to " + filteredPhotos.length.toString());
  153. return filteredPhotos;
  154. }
  155. @override
  156. void dispose() {
  157. _detector.stopListening();
  158. _localPhotosUpdatedEventSubscription.cancel();
  159. super.dispose();
  160. }
  161. }