Files
fluttergram/lib/image_post.dart

361 lines
9.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'main.dart';
import 'dart:async';
import 'profile_page.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'comment_screen.dart';
class ImagePost extends StatefulWidget {
const ImagePost(
{this.mediaUrl,
this.username,
this.location,
this.description,
this.likes,
this.postId,
this.ownerId});
factory ImagePost.fromDocument(DocumentSnapshot document) {
return new ImagePost(
username: document['username'],
location: document['location'],
mediaUrl: document['mediaUrl'],
likes: document['likes'],
description: document['description'],
postId: document.documentID,
ownerId: document['ownerId'],
);
}
factory ImagePost.fromJSON(Map data) {
return new ImagePost(
username: data['username'],
location: data['location'],
mediaUrl: data['mediaUrl'],
likes: data['likes'],
description: data['description'],
ownerId: data['ownerId'],
postId: data['postId'],
);
}
int getLikeCount(var likes) {
if (likes == null) {
return 0;
}
// issue is below
var vals = likes.values;
int count = 0;
for (var val in vals) {
if (val == true) {
count = count + 1;
}
}
return count;
}
final String mediaUrl;
final String username;
final String location;
final String description;
final likes;
final String postId;
final String ownerId;
_ImagePost createState() => new _ImagePost(
mediaUrl: this.mediaUrl,
username: this.username,
location: this.location,
description: this.description,
likes: this.likes,
likeCount: getLikeCount(this.likes),
ownerId: this.ownerId,
postId: this.postId,
);
}
class _ImagePost extends State<ImagePost> {
final String mediaUrl;
final String username;
final String location;
final String description;
Map likes;
int likeCount;
final String postId;
bool liked;
final String ownerId;
bool showHeart = false;
TextStyle boldStyle = new TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
);
var reference = Firestore.instance.collection('insta_posts');
_ImagePost(
{this.mediaUrl,
this.username,
this.location,
this.description,
this.likes,
this.postId,
this.likeCount,
this.ownerId});
GestureDetector buildLikeIcon() {
Color color;
IconData icon;
if (liked) {
color = Colors.pink;
icon = FontAwesomeIcons.solidHeart;
} else {
icon = FontAwesomeIcons.heart;
}
return new GestureDetector(
child: new Icon(
icon,
size: 25.0,
color: color,
),
onTap: () {
_likePost(postId);
});
}
GestureDetector buildLikeableImage() {
return new GestureDetector(
onDoubleTap: () => _likePost(postId),
child: new Stack(
alignment: Alignment.center,
children: <Widget>[
// new FadeInImage.memoryNetwork(placeholder: kTransparentImage, image: mediaUrl),
new CachedNetworkImage(
imageUrl: mediaUrl,
fit: BoxFit.fitWidth,
placeholder: (context, url) => loadingPlaceHolder,
errorWidget: (context, url, error) => Icon(Icons.error),
),
showHeart
? new Positioned(
child: new Opacity(
opacity: 0.85,
child: new Icon(
FontAwesomeIcons.solidHeart,
size: 80.0,
color: Colors.white,
)),
)
: new Container()
],
),
);
}
buildPostHeader({String ownerId}) {
if (ownerId == null) {
return new Text("owner error");
}
return new FutureBuilder(
future: Firestore.instance
.collection('insta_users')
.document(ownerId)
.get(),
builder: (context, snapshot) {
String imageUrl = " ";
String username = " ";
if (snapshot.data != null) {
imageUrl = snapshot.data.data['photoUrl'];
username = snapshot.data.data['username'];
}
return new ListTile(
leading: new CircleAvatar(
backgroundImage: new CachedNetworkImageProvider(imageUrl),
backgroundColor: Colors.grey,
),
title: new GestureDetector(
child: new Text(username, style: boldStyle),
onTap: () {
openProfile(context, ownerId);
},
),
subtitle: new Text(this.location),
trailing: const Icon(Icons.more_vert),
);
});
}
Container loadingPlaceHolder = Container(
height: 400.0,
child: new Center(child: new CircularProgressIndicator()),
);
@override
Widget build(BuildContext context) {
liked = (likes[googleSignIn.currentUser.id.toString()] == true);
return new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
buildPostHeader(ownerId: ownerId),
buildLikeableImage(),
new Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Padding(padding: const EdgeInsets.only(left: 20.0, top: 40.0)),
buildLikeIcon(),
new Padding(padding: const EdgeInsets.only(right: 20.0)),
new GestureDetector(
child: const Icon(
FontAwesomeIcons.comment,
size: 25.0,
),
onTap: () {
goToComments(
context: context,
postId: postId,
ownerId: ownerId,
mediaUrl: mediaUrl);
}),
],
),
new Row(
children: <Widget>[
new Container(
margin: const EdgeInsets.only(left: 20.0),
child: new Text(
"$likeCount likes",
style: boldStyle,
),
)
],
),
new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
margin: const EdgeInsets.only(left: 20.0),
child: new Text(
"$username ",
style: boldStyle,
)),
new Expanded(child: new Text(description)),
],
)
],
);
}
void _likePost(String postId2) {
var userId = googleSignIn.currentUser.id;
bool _liked = likes[userId] == true;
if (_liked) {
print('removing like');
reference.document(postId).updateData({
'likes.$userId': false
//firestore plugin doesnt support deleting, so it must be nulled / falsed
});
setState(() {
likeCount = likeCount - 1;
liked = false;
likes[userId] = false;
});
removeActivityFeedItem();
}
if (!_liked) {
print('liking');
reference.document(postId).updateData({'likes.$userId': true});
addActivityFeedItem();
setState(() {
likeCount = likeCount + 1;
liked = true;
likes[userId] = true;
showHeart = true;
});
new Timer(const Duration(milliseconds: 500), () {
setState(() {
showHeart = false;
});
});
}
}
void addActivityFeedItem() {
Firestore.instance
.collection("insta_a_feed")
.document(ownerId)
.collection("items")
.document(postId)
.setData({
"username": currentUserModel.username,
"userId": currentUserModel.id,
"type": "like",
"userProfileImg": currentUserModel.photoUrl,
"mediaUrl": mediaUrl,
"timestamp": new DateTime.now().toString(),
"postId": postId,
});
}
void removeActivityFeedItem() {
Firestore.instance
.collection("insta_a_feed")
.document(ownerId)
.collection("items")
.document(postId)
.delete();
}
}
class ImagePostFromId extends StatelessWidget {
final String id;
const ImagePostFromId({this.id});
getImagePost() async {
var document =
await Firestore.instance.collection('insta_posts').document(id).get();
return new ImagePost.fromDocument(document);
}
@override
Widget build(BuildContext context) {
return new FutureBuilder(
future: getImagePost(),
builder: (context, snapshot) {
if (!snapshot.hasData)
return new Container(
alignment: FractionalOffset.center,
padding: const EdgeInsets.only(top: 10.0),
child: new CircularProgressIndicator());
return snapshot.data;
});
}
}
void goToComments(
{BuildContext context, String postId, String ownerId, String mediaUrl}) {
Navigator.of(context)
.push(new MaterialPageRoute<bool>(builder: (BuildContext context) {
return new CommentScreen(
postId: postId,
postOwner: ownerId,
postMediaUrl: mediaUrl,
);
}));
}