diff --git a/Secretly.xcodeproj/project.pbxproj b/Secretly.xcodeproj/project.pbxproj index 8dd4829..9fd4fc9 100644 --- a/Secretly.xcodeproj/project.pbxproj +++ b/Secretly.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 04B404D526B6215B00B1E1FE /* LikeServices.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04B404D426B6215B00B1E1FE /* LikeServices.swift */; }; + 04B404DF26B7851100B1E1FE /* Like.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04B404DE26B7851100B1E1FE /* Like.swift */; }; 302B5845267E658E007133E6 /* HttpResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302B583D267E658E007133E6 /* HttpResponse.swift */; }; 302B5846267E658E007133E6 /* AmacaConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302B583E267E658E007133E6 /* AmacaConfig.swift */; }; 302B5847267E658E007133E6 /* StatusCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302B583F267E658E007133E6 /* StatusCode.swift */; }; @@ -76,6 +78,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 04B404D426B6215B00B1E1FE /* LikeServices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LikeServices.swift; sourceTree = ""; }; + 04B404DE26B7851100B1E1FE /* Like.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Like.swift; sourceTree = ""; }; 302B583D267E658E007133E6 /* HttpResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HttpResponse.swift; sourceTree = ""; }; 302B583E267E658E007133E6 /* AmacaConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AmacaConfig.swift; sourceTree = ""; }; 302B583F267E658E007133E6 /* StatusCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusCode.swift; sourceTree = ""; }; @@ -222,6 +226,7 @@ 30C77CAF266AD69700A888DC /* CurrentUserService.swift */, 304E06C726742BDA00A99128 /* CreatePostService.swift */, 304E06C926742CC500A99128 /* FeedService.swift */, + 04B404D426B6215B00B1E1FE /* LikeServices.swift */, ); path = Services; sourceTree = ""; @@ -248,6 +253,7 @@ 307A30572661AD540020DF8B /* User.swift */, 30C77CB3266AF47300A888DC /* Credentials.swift */, 30C77CB5266AF48300A888DC /* CurrentUser.swift */, + 04B404DE26B7851100B1E1FE /* Like.swift */, ); path = Models; sourceTree = ""; @@ -453,9 +459,11 @@ 307A305E2661CD510020DF8B /* PostCollectionViewCell.swift in Sources */, 302BB626267E447900FD74F5 /* PostInputViewController+UITextFieldDelegate.swift in Sources */, 30BC8BA02662B8A700F7E6A5 /* StorageType.swift in Sources */, + 04B404DF26B7851100B1E1FE /* Like.swift in Sources */, 307A305B2661B7A20020DF8B /* FeedCollectionViewController.swift in Sources */, 304E06CC2674442800A99128 /* UIImage+encodeBase64.swift in Sources */, 30BC8BA62662C02300F7E6A5 /* CacheImage.swift in Sources */, + 04B404D526B6215B00B1E1FE /* LikeServices.swift in Sources */, 302B5847267E658E007133E6 /* StatusCode.swift in Sources */, 302B584B267E658E007133E6 /* RequestBuilder.swift in Sources */, 307A306526629B990020DF8B /* AuthorView.swift in Sources */, diff --git a/Secretly/Base.lproj/LaunchScreen.storyboard b/Secretly/Base.lproj/LaunchScreen.storyboard index 4d082d6..006a0a1 100644 --- a/Secretly/Base.lproj/LaunchScreen.storyboard +++ b/Secretly/Base.lproj/LaunchScreen.storyboard @@ -1,8 +1,8 @@ - + - + diff --git a/Secretly/Models/Like.swift b/Secretly/Models/Like.swift new file mode 100644 index 0000000..9cbcd90 --- /dev/null +++ b/Secretly/Models/Like.swift @@ -0,0 +1,17 @@ +// +// Like.swift +// Secretly +// +// Created by mac on 31/07/21. +// Copyright © 2021 3zcurdia. All rights reserved. +// + +import Foundation + +struct Like: Restable { + var id : Int? + let createdAt : Date + let updateAt : Date + let user : User +} + diff --git a/Secretly/Models/Post.swift b/Secretly/Models/Post.swift index eba5ff0..1f92e94 100644 --- a/Secretly/Models/Post.swift +++ b/Secretly/Models/Post.swift @@ -9,6 +9,7 @@ import Foundation import UIKit + struct Post: Restable { var id: Int? let content: String @@ -21,8 +22,9 @@ struct Post: Restable { let longitude: Double? let createdAt: Date? let updatedAt: Date? + var liked: Bool? - init(content: String, backgroundColor: String, latitude: Double? = nil, longitude: Double? = nil, image: UIImage? = nil) { + init(content: String, backgroundColor: String, latitude: Double? = nil, longitude: Double? = nil, image: UIImage? = nil, liked:Bool? = nil) { self.content = content self.backgroundColor = backgroundColor self.id = nil @@ -34,6 +36,8 @@ struct Post: Restable { self.commentsCount = nil self.createdAt = nil self.updatedAt = nil + self.liked = nil + } func encode(to encoder: Encoder) throws { diff --git a/Secretly/Network/RestClient.swift b/Secretly/Network/RestClient.swift index 3048ccf..1c34a9c 100644 --- a/Secretly/Network/RestClient.swift +++ b/Secretly/Network/RestClient.swift @@ -58,7 +58,20 @@ struct RestClient { complete(newResult) } } - + func delete(_ identifier: String, complete: @escaping (Result) -> Void) { + client.delete(path: "\(path)/\(identifier)") { result in + let newResult = result.flatMap { parse(data: $0) } + complete(newResult) + } + } + + func createNoModel(_ identifier:String, complete: @escaping (Result) -> Void){ + client.post(path: path, body: nil){ result in + let newResult = result.flatMap { parse(data: $0) } + complete(newResult) + } + } + func update(model: T, complete: @escaping (Result) -> Void) throws { let data = try encoder.encode(model) client.put(path: "\(path)/\(model.id)", body: data) { result in diff --git a/Secretly/Services/LikeService.swift b/Secretly/Services/LikeService.swift new file mode 100644 index 0000000..8feb047 --- /dev/null +++ b/Secretly/Services/LikeService.swift @@ -0,0 +1,9 @@ +// +// LikeService.swift +// Secretly +// +// Created by mac on 31/07/21. +// Copyright © 2021 3zcurdia. All rights reserved. +// + +import Foundation diff --git a/Secretly/Services/LikeServices.swift b/Secretly/Services/LikeServices.swift new file mode 100644 index 0000000..efffd43 --- /dev/null +++ b/Secretly/Services/LikeServices.swift @@ -0,0 +1,24 @@ +import Foundation + +struct LikeService { + private var endpoint: RestClient + init() { + endpoint = RestClient(client: AmacaConfig.shared.httpClient, path: "/api/v1/posts") + } + func createLike(postId:Int, completion: ((Result) -> Void)? = nil ) { + let identifier = "\(postId)/likes" + endpoint.createNoModel(identifier){ + result in + completion?(result) + } + } + func deleteLike(postId:Int, completion: ((Result) -> Void)? = nil ) { + let identifier = "\(postId)/likes" + endpoint.delete(identifier){ + result in + completion?(result) + } + } + +} + diff --git a/Secretly/ViewControllers/FeedCollectionViewController+UICollectionViewDataSource .swift b/Secretly/ViewControllers/FeedCollectionViewController+UICollectionViewDataSource .swift index 15100dd..36293db 100644 --- a/Secretly/ViewControllers/FeedCollectionViewController+UICollectionViewDataSource .swift +++ b/Secretly/ViewControllers/FeedCollectionViewController+UICollectionViewDataSource .swift @@ -21,6 +21,7 @@ extension FeedCollectionViewController: UICollectionViewDataSource { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PostCollectionViewCell.reuseIdentifier, for: indexPath) as! PostCollectionViewCell cell.post = self.posts?[indexPath.row] + cell.likeDelegate = self return cell } } diff --git a/Secretly/ViewControllers/FeedCollectionViewController.swift b/Secretly/ViewControllers/FeedCollectionViewController.swift index 9180d42..4da1d7f 100644 --- a/Secretly/ViewControllers/FeedCollectionViewController.swift +++ b/Secretly/ViewControllers/FeedCollectionViewController.swift @@ -11,6 +11,7 @@ import CoreLocation class FeedCollectionViewController: UIViewController { let feedService = FeedService() + let likeService = LikeService() var posts: [Post]? { didSet { self.collectionView.reloadData() @@ -37,13 +38,16 @@ class FeedCollectionViewController: UIViewController { let nib = UINib(nibName: String(describing: PostCollectionViewCell.self), bundle: nil) collectionView.register(nib, forCellWithReuseIdentifier: PostCollectionViewCell.reuseIdentifier) collectionView.addSubview(refreshControl) - refreshControl.addTarget(self, action: #selector(self.loadPosts), for: UIControl.Event.valueChanged) } @objc func loadPosts() { - feedService.load { [unowned self] posts in self.posts = posts } + feedService.load { [unowned self] posts in + self.posts = posts + + } + } @IBAction @@ -57,5 +61,31 @@ extension FeedCollectionViewController: PostInputViewDelegate { func didCreatePost(post: Post?) { guard let upost = post else { return } self.posts?.insert(upost, at: 0) + + } +} + +protocol LikeInputDelegate{ + func likeToPost(postId: Int) + func dislikeToPost(postId: Int) +} + +extension FeedCollectionViewController : LikeInputDelegate { + + func dislikeToPost(postId: Int) { + guard let posts = self.posts else { return } + let postIndex = posts.firstIndex(where: { $0.id == postId }) + guard let index = postIndex else { return } + likeService.deleteLike(postId: postId) + self.posts?[index].liked? = false + } + + func likeToPost(postId: Int ) { + guard let posts = self.posts else { return } + let postIndex = posts.firstIndex(where: { $0.id == postId }) + guard let index = postIndex else { return } + likeService.createLike(postId: postId) + self.posts?[index].liked? = true + } } diff --git a/Secretly/Views/PostCollectionViewCell.swift b/Secretly/Views/PostCollectionViewCell.swift index ee08d53..8d4b86e 100644 --- a/Secretly/Views/PostCollectionViewCell.swift +++ b/Secretly/Views/PostCollectionViewCell.swift @@ -10,6 +10,7 @@ import UIKit class PostCollectionViewCell: UICollectionViewCell { static let reuseIdentifier = "feedPostCell" + var likeDelegate : LikeInputDelegate? var post: Post? { didSet { updateView() @@ -21,21 +22,70 @@ class PostCollectionViewCell: UICollectionViewCell { @IBOutlet weak var likeState: UIImageView! @IBOutlet weak var commentCounter: UILabel! + override func awakeFromNib() { super.awakeFromNib() + let tap = UITapGestureRecognizer(target: self, action: #selector(likeStateTapped)) + likeState.isUserInteractionEnabled = true + likeState.addGestureRecognizer(tap) } func updateView() { - imageView.image = nil - guard let post = post else { return } - if let color = UIColor(hex: post.backgroundColor) { - self.backgroundColor = color + imageView.image = nil + guard let post = post else { return } + if let color = UIColor(hex: post.backgroundColor) { + self.backgroundColor = color + } + + if let liked = post.liked{ + self.changeLikeState(liked: liked) + } + + self.contentLabel.text = post.content + self.commentCounter.text = String(describing: post.commentsCount ?? 0) + if let postImg = post.image { + ImageLoader.load(postImg.mediumUrl) { img in self.imageView.image = img } + } + self.authorView.author = post.user + + + } + //captura el tap + @objc func likeStateTapped(tapGestureRecognizer: UITapGestureRecognizer){ + print("tocando") + guard let delegate = likeDelegate else {return} + guard let liked = self.post?.liked else {return} + guard let postId = self.post?.id else {return} + if !liked { + delegate.likeToPost(postId: postId) + } else { + delegate.dislikeToPost(postId: postId) } - self.contentLabel.text = post.content - self.commentCounter.text = String(describing: post.commentsCount ?? 0) - if let postImg = post.image { - ImageLoader.load(postImg.mediumUrl) { img in self.imageView.image = img } + } + + func changeLikeState(liked:Bool){ + if liked { + likeState.image = UIImage(systemName:"heart.fill") + likeState.tintColor = .red + } else { + likeState.image = UIImage(systemName:"heart") + likeState.tintColor = .white } - self.authorView.author = post.user } + } + + + + + + + + + + + + + + +