Refactor code

This commit is contained in:
Vishnu Mohandas 2020-04-14 21:06:18 +05:30
parent 6e7b03a048
commit f1a696f8ee
9 changed files with 197 additions and 82 deletions

View file

@ -2,15 +2,10 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:myapp/models/photo.dart';
import 'package:myapp/photo_loader.dart';
import 'package:myapp/photo_provider.dart';
import 'package:myapp/photo_sync_manager.dart';
import 'package:myapp/ui/gallery.dart';
import 'package:myapp/ui/loading_widget.dart';
import 'package:myapp/ui/search_page.dart';
import 'package:myapp/ui/home_widget.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:provider/provider.dart';
final provider = PhotoProvider();
final logger = Logger();
@ -35,73 +30,13 @@ Future<void> init(List<AssetEntity> assets) async {
}
class MyApp extends StatelessWidget {
final PhotoLoader photoLoader = PhotoLoader.instance;
final _title = 'Orma';
@override
Widget build(BuildContext context) {
final title = 'Orma';
return FutureBuilder<bool>(
future: photoLoader.loadPhotos(),
builder: (context, snapshot) {
Widget body;
if (snapshot.hasData) {
body = HomeWidget();
} else if (snapshot.hasError) {
logger.e(snapshot.error);
body = Text("Error!");
} else {
body = loadWidget;
}
return ChangeNotifierProvider<PhotoLoader>.value(
value: photoLoader,
child: MaterialApp(
title: title,
theme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: body),
),
);
});
}
}
class HomeWidget extends StatelessWidget {
const HomeWidget({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Hero(
child: TextField(
readOnly: true,
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return SearchPage();
},
),
);
},
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Search "Paris"',
contentPadding: const EdgeInsets.all(12.0),
),
),
tag: "search"),
Flexible(
child: Gallery(),
)
],
),
return MaterialApp(
title: _title,
theme: ThemeData.dark(),
home: HomeWidget(_title),
);
}
}

View file

@ -1,6 +1,7 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:myapp/core/lru_map.dart';
import 'package:myapp/models/photo.dart';
import 'package:share_extend/share_extend.dart';
@ -12,6 +13,7 @@ class DetailPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
Logger().i(photo.localPath);
return Scaffold(
appBar: AppBar(
actions: <Widget>[

View file

@ -10,10 +10,13 @@ import 'package:myapp/utils/date_time_util.dart';
import 'package:provider/provider.dart';
import 'package:share_extend/share_extend.dart';
import 'change_notifier_builder.dart';
import 'detail_page.dart';
class Gallery extends StatefulWidget {
final List<List<Photo>> collatedPhotos;
const Gallery(this.collatedPhotos, {Key key}) : super(key: key);
@override
_GalleryState createState() {
return _GalleryState();
@ -26,19 +29,15 @@ class _GalleryState extends State<Gallery> {
@override
Widget build(BuildContext context) {
return ChangeNotifierBuilder(
value: photoLoader,
builder: (_, __) {
return ListView.builder(
itemCount: photoLoader.collatedPhotos.length,
itemBuilder: _buildListItem,
controller: _scrollController,
);
});
return ListView.builder(
itemCount: widget.collatedPhotos.length,
itemBuilder: _buildListItem,
controller: _scrollController,
);
}
Widget _buildListItem(BuildContext context, int index) {
var photos = photoLoader.collatedPhotos[index];
var photos = widget.collatedPhotos[index];
return Column(
children: <Widget>[
_getDay(photos[0].createTimestamp),

View file

@ -0,0 +1,100 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:myapp/models/photo.dart';
import 'package:myapp/ui/change_notifier_builder.dart';
import 'package:myapp/ui/search_page.dart';
import 'package:myapp/utils/camera_items_filter.dart';
import 'package:myapp/utils/gallery_items_filter.dart';
import 'package:provider/provider.dart';
import '../photo_loader.dart';
import 'gallery.dart';
import 'loading_widget.dart';
class GalleryContainer extends StatelessWidget {
final GalleryType type;
static final importantItemsFilter = CameraItemsFilter();
static final galleryItemsFilter = GalleryItemsFilter();
const GalleryContainer(
this.type, {
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final photoLoader = PhotoLoader.instance;
return Column(
children: <Widget>[
Hero(
child: TextField(
readOnly: true,
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return SearchPage();
},
),
);
},
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Search "Paris"',
contentPadding: const EdgeInsets.all(12.0),
),
),
tag: "search"),
FutureBuilder<bool>(
future: photoLoader.loadPhotos(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ChangeNotifierProvider<PhotoLoader>.value(
value: photoLoader,
child: ChangeNotifierBuilder(
value: photoLoader,
builder: (_, __) {
var collatedPhotos = photoLoader.collatedPhotos;
return Flexible(child: _getGallery(collatedPhotos));
}),
);
} else if (snapshot.hasError) {
return Text("Error!");
} else {
return loadWidget;
}
},
)
],
);
}
Gallery _getGallery(List<List<Photo>> collatedPhotos) {
return type == GalleryType.important_photos
? Gallery(getCollatedPhotos(collatedPhotos, importantItemsFilter))
: Gallery(getCollatedPhotos(collatedPhotos, galleryItemsFilter));
}
List<List<Photo>> getCollatedPhotos(
List<List<Photo>> source, GalleryItemsFilter filter) {
final List<List<Photo>> collatedList = List<List<Photo>>();
for (List<Photo> unfilteredPhotos in source) {
final List<Photo> filteredPhotos = List<Photo>();
for (Photo photo in unfilteredPhotos) {
if (filter.shouldInclude(photo)) {
filteredPhotos.add(photo);
}
}
if (filteredPhotos.isNotEmpty) {
collatedList.add(filteredPhotos);
}
}
return collatedList;
}
}
enum GalleryType {
important_photos,
all_photos,
}

54
lib/ui/home_widget.dart Normal file
View file

@ -0,0 +1,54 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'gallery_container_widget.dart';
class HomeWidget extends StatefulWidget {
final String title;
const HomeWidget(this.title, {Key key}) : super(key: key);
@override
State<StatefulWidget> createState() => _HomeWidgetState();
}
class _HomeWidgetState extends State<HomeWidget> {
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: widget.title,
theme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.photo_filter),
title: Text('Photos'),
),
BottomNavigationBarItem(
icon: Icon(Icons.photo_library),
title: Text('Gallery'),
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.yellow[800],
onTap: _onItemTapped,
),
body: GalleryContainer(_selectedIndex == 0
? GalleryType.important_photos
: GalleryType.all_photos),
),
);
}
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
}

View file

@ -0,0 +1,10 @@
import 'package:myapp/models/photo.dart';
import 'package:myapp/utils/gallery_items_filter.dart';
class CameraItemsFilter implements GalleryItemsFilter {
@override
bool shouldInclude(Photo photo) {
// TODO: Improve logic
return photo.localPath.contains("Camera");
}
}

View file

@ -0,0 +1,7 @@
import 'package:myapp/models/photo.dart';
class GalleryItemsFilter {
bool shouldInclude(Photo photo) {
return true;
}
}

View file

@ -191,6 +191,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.8"
photo_view:
dependency: "direct main"
description:
name: photo_view
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.2"
platform:
dependency: transitive
description:

View file

@ -36,6 +36,7 @@ dependencies:
image: ^2.1.4
share_extend: "^1.1.2"
draggable_scrollbar: ^0.0.4
photo_view: ^0.9.2
dev_dependencies:
flutter_test: