mirror of
https://github.com/mdanics/fluttergram.git
synced 2025-05-21 07:56:30 +08:00
361 lines
9.2 KiB
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,
|
|
);
|
|
}));
|
|
}
|