From c323e5f98bc2424e393e1b253fec5b08bb2e56ac Mon Sep 17 00:00:00 2001 From: maxwell Date: Thu, 26 Aug 2021 14:04:55 -0500 Subject: [PATCH 1/7] Updated Post model to support like state and like count --- Secretly/Models/Post.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Secretly/Models/Post.swift b/Secretly/Models/Post.swift index eba5ff0..1b83b32 100644 --- a/Secretly/Models/Post.swift +++ b/Secretly/Models/Post.swift @@ -21,6 +21,8 @@ struct Post: Restable { let longitude: Double? let createdAt: Date? let updatedAt: Date? + var likesCount: Int? + var liked: Bool? init(content: String, backgroundColor: String, latitude: Double? = nil, longitude: Double? = nil, image: UIImage? = nil) { self.content = content @@ -34,6 +36,8 @@ struct Post: Restable { self.commentsCount = nil self.createdAt = nil self.updatedAt = nil + self.likesCount = nil + self.liked = nil } func encode(to encoder: Encoder) throws { @@ -44,4 +48,16 @@ struct Post: Restable { try container.encode(latitude, forKey: .latitude) try container.encode(longitude, forKey: .longitude) } + + mutating func toggleLike(state:String){ + if state == "inc"{ + likesCount = (likesCount ?? 0) + 1 + liked = true + } else if state == "dec"{ + likesCount = (likesCount ?? 0) - 1 + liked = false + } else { + print("Estado no reconocido") + } + } } From 97dcd1526eb9156975b51d80536dd28ef92ca3c2 Mon Sep 17 00:00:00 2001 From: rhodstar Date: Thu, 26 Aug 2021 14:09:51 -0500 Subject: [PATCH 2/7] Added functions to allow nil payload to the server --- Secretly/Network/RestClient.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Secretly/Network/RestClient.swift b/Secretly/Network/RestClient.swift index 3048ccf..ca89158 100644 --- a/Secretly/Network/RestClient.swift +++ b/Secretly/Network/RestClient.swift @@ -58,6 +58,13 @@ struct RestClient { complete(newResult) } } + + func create(complete: @escaping (Result)-> Void) throws { + 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) @@ -73,6 +80,13 @@ struct RestClient { complete(newResult) } } + + func delete(complete: @escaping (Result) -> Void) { + client.delete(path: path) { result in + let newResult = result.flatMap { parse(data: $0) } + complete(newResult) + } + } private func parseList(data: Data?) -> Result<[T], Error> { if let data = data { From e60329e72796589caebb4998959563998df434ec Mon Sep 17 00:00:00 2001 From: rhodstar Date: Thu, 26 Aug 2021 14:14:23 -0500 Subject: [PATCH 3/7] Added Model and Service for Like and Dislike interaction --- Secretly/Models/Like.swift | 17 ++++++++++++++ Secretly/Services/LikeService.swift | 36 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 Secretly/Models/Like.swift create mode 100644 Secretly/Services/LikeService.swift diff --git a/Secretly/Models/Like.swift b/Secretly/Models/Like.swift new file mode 100644 index 0000000..74b144f --- /dev/null +++ b/Secretly/Models/Like.swift @@ -0,0 +1,17 @@ +// +// Like.swift +// Secretly +// +// Created by maxwell on 25/08/21. +// Copyright © 2021 3zcurdia. All rights reserved. +// + +import Foundation + +struct Like: Restable { + var id: Int + let likeableType: String + let likeableId: Int + let createdAt, updatedAt: String + var user: User +} diff --git a/Secretly/Services/LikeService.swift b/Secretly/Services/LikeService.swift new file mode 100644 index 0000000..cfc1bc7 --- /dev/null +++ b/Secretly/Services/LikeService.swift @@ -0,0 +1,36 @@ +// +// LikeService.swift +// Secretly +// +// Created by maxwell on 25/08/21. +// Copyright © 2021 3zcurdia. All rights reserved. +// + +import Foundation + +struct LikeService { + let endPoint: RestClient? + var active = false + + init(post: Post?) { + guard let post = post, let postId = post.id else { + self.endPoint = nil + return + } + self.endPoint = RestClient(client: AmacaConfig.shared.httpClient, path: "/api/v1/posts/\(postId)/likes") + self.active = post.liked ?? false + } + + mutating func action(complete: @escaping (Result)-> Void){ + if self.active { + endPoint?.delete{ result in + DispatchQueue.main.async { complete(result) } + } + } else { + try? endPoint?.create{ result in + DispatchQueue.main.async { complete(result) } + } + } + active = !active + } +} From e3c5c8ef6b2c35b15a7f60eb776081b60fcb72ce Mon Sep 17 00:00:00 2001 From: rhodstar Date: Thu, 26 Aug 2021 14:59:00 -0500 Subject: [PATCH 4/7] Change Like Image View into a Button Also added tap gesture to update like interface --- Secretly.xcodeproj/project.pbxproj | 8 ++++++ Secretly/Views/PostCollectionViewCell.swift | 26 +++++++++++++++-- Secretly/Views/PostCollectionViewCell.xib | 31 +++++++++++++-------- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/Secretly.xcodeproj/project.pbxproj b/Secretly.xcodeproj/project.pbxproj index 8dd4829..dfa6c3b 100644 --- a/Secretly.xcodeproj/project.pbxproj +++ b/Secretly.xcodeproj/project.pbxproj @@ -56,6 +56,8 @@ 30C77CB6266AF48300A888DC /* CurrentUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30C77CB5266AF48300A888DC /* CurrentUser.swift */; }; 30C77CB8266BD44300A888DC /* CreatePostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30C77CB7266BD44300A888DC /* CreatePostViewController.swift */; }; 30FD0E722659645A006E309A /* Faker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30FD0E712659645A006E309A /* Faker.swift */; }; + CF00550026D7054000585549 /* Like.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF0054FF26D7054000585549 /* Like.swift */; }; + CFF9124926D7232C0001E9FF /* LikeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFF9124826D7232C0001E9FF /* LikeService.swift */; }; E021984723FA35E00025C28E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E021984623FA35E00025C28E /* AppDelegate.swift */; }; E021984923FA35E00025C28E /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E021984823FA35E00025C28E /* SceneDelegate.swift */; }; E021984B23FA35E00025C28E /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E021984A23FA35E00025C28E /* WelcomeViewController.swift */; }; @@ -125,6 +127,8 @@ 30C77CB5266AF48300A888DC /* CurrentUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentUser.swift; sourceTree = ""; }; 30C77CB7266BD44300A888DC /* CreatePostViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatePostViewController.swift; sourceTree = ""; }; 30FD0E712659645A006E309A /* Faker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Faker.swift; sourceTree = ""; }; + CF0054FF26D7054000585549 /* Like.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Like.swift; sourceTree = ""; }; + CFF9124826D7232C0001E9FF /* LikeService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LikeService.swift; sourceTree = ""; }; E021984323FA35E00025C28E /* Secretly.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Secretly.app; sourceTree = BUILT_PRODUCTS_DIR; }; E021984623FA35E00025C28E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; E021984823FA35E00025C28E /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -222,6 +226,7 @@ 30C77CAF266AD69700A888DC /* CurrentUserService.swift */, 304E06C726742BDA00A99128 /* CreatePostService.swift */, 304E06C926742CC500A99128 /* FeedService.swift */, + CFF9124826D7232C0001E9FF /* LikeService.swift */, ); path = Services; sourceTree = ""; @@ -248,6 +253,7 @@ 307A30572661AD540020DF8B /* User.swift */, 30C77CB3266AF47300A888DC /* Credentials.swift */, 30C77CB5266AF48300A888DC /* CurrentUser.swift */, + CF0054FF26D7054000585549 /* Like.swift */, ); path = Models; sourceTree = ""; @@ -428,6 +434,7 @@ E021984B23FA35E00025C28E /* WelcomeViewController.swift in Sources */, 3072FBDF2680FA5A00B35C8C /* ImageProcessor.swift in Sources */, 302BB622267E38E800FD74F5 /* PostInputViewController+UIImagePickerControllerDelegate.swift in Sources */, + CF00550026D7054000585549 /* Like.swift in Sources */, 302B5845267E658E007133E6 /* HttpResponse.swift in Sources */, 302B584A267E658E007133E6 /* RestClient.swift in Sources */, 302B5848267E658E007133E6 /* HttpClient.swift in Sources */, @@ -466,6 +473,7 @@ 30C77CB6266AF48300A888DC /* CurrentUser.swift in Sources */, 302BB624267E3A8700FD74F5 /* PostInputViewController+UIColorPickerViewControllerDelegate.swift in Sources */, 304E06CF267468DA00A99128 /* UIColor+Pastel.swift in Sources */, + CFF9124926D7232C0001E9FF /* LikeService.swift in Sources */, 304E06C42674133D00A99128 /* String+isBlank.swift in Sources */, 30BC8BA42662BDEF00F7E6A5 /* ImageStore.swift in Sources */, 3033795B267537490066D94A /* FeedCollectionViewController+UICollectionViewDataSourcePrefetching.swift in Sources */, diff --git a/Secretly/Views/PostCollectionViewCell.swift b/Secretly/Views/PostCollectionViewCell.swift index ee08d53..5386aed 100644 --- a/Secretly/Views/PostCollectionViewCell.swift +++ b/Secretly/Views/PostCollectionViewCell.swift @@ -10,17 +10,19 @@ import UIKit class PostCollectionViewCell: UICollectionViewCell { static let reuseIdentifier = "feedPostCell" + var likeService: LikeService? var post: Post? { didSet { updateView() + likeService = LikeService(post: post) } } @IBOutlet weak var authorView: AuthorView! @IBOutlet weak var contentLabel: UILabel! @IBOutlet weak var imageView: UIImageView! - @IBOutlet weak var likeState: UIImageView! + @IBOutlet weak var likeState: UIButton! @IBOutlet weak var commentCounter: UILabel! - + override func awakeFromNib() { super.awakeFromNib() } @@ -37,5 +39,25 @@ class PostCollectionViewCell: UICollectionViewCell { ImageLoader.load(postImg.mediumUrl) { img in self.imageView.image = img } } self.authorView.author = post.user + + let imageName = post.liked ?? false ? "heart.fill" : "heart" + likeState.setImage(UIImage(systemName: imageName), for: .normal) + + } + + @IBAction func likeOnTap(_ sender: UIButton) { + likeService?.action{ [unowned self] result in + var imageName = "heart" + switch result { + case .success(nil): + post?.toggleLike(state: "dec") + case .success: + imageName = "heart.fill" + post?.toggleLike(state: "inc") + case .failure: + print("No se pudo actualizar el like") + } + likeState.setImage(UIImage(systemName: imageName ),for: .normal) + } } } diff --git a/Secretly/Views/PostCollectionViewCell.xib b/Secretly/Views/PostCollectionViewCell.xib index 7b3a4e2..796418d 100644 --- a/Secretly/Views/PostCollectionViewCell.xib +++ b/Secretly/Views/PostCollectionViewCell.xib @@ -3,6 +3,7 @@ + @@ -19,6 +20,7 @@ + @@ -30,14 +32,6 @@ - - - - - - - - @@ -69,10 +75,11 @@ + + - @@ -81,7 +88,6 @@ - @@ -89,7 +95,7 @@ - + @@ -97,6 +103,9 @@ + + + From 4d2ce982733972e33e13b519175143ca451ced91 Mon Sep 17 00:00:00 2001 From: rhodstar Date: Thu, 26 Aug 2021 23:27:47 -0500 Subject: [PATCH 5/7] Fix case for empty data response --- Secretly/Network/HttpResponse.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Secretly/Network/HttpResponse.swift b/Secretly/Network/HttpResponse.swift index eb0543a..115effd 100644 --- a/Secretly/Network/HttpResponse.swift +++ b/Secretly/Network/HttpResponse.swift @@ -20,6 +20,10 @@ struct HttpResponse { } func result(for data: Data?) -> Result { - return status.result().map { _ in data } + if let data = data, !data.isEmpty { + return status.result().map { _ in data } + } else { + return status.result().map { _ in nil } + } } } From ed629428579d5f296b88b0fd08bf519235232a3b Mon Sep 17 00:00:00 2001 From: rhodstar Date: Thu, 26 Aug 2021 23:28:48 -0500 Subject: [PATCH 6/7] Erase unused properties and added like attribues to encoder func --- Secretly/Models/Like.swift | 3 ++- Secretly/Models/Post.swift | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Secretly/Models/Like.swift b/Secretly/Models/Like.swift index 74b144f..10a77bf 100644 --- a/Secretly/Models/Like.swift +++ b/Secretly/Models/Like.swift @@ -12,6 +12,7 @@ struct Like: Restable { var id: Int let likeableType: String let likeableId: Int - let createdAt, updatedAt: String + let createdAt: String + let updatedAt: String var user: User } diff --git a/Secretly/Models/Post.swift b/Secretly/Models/Post.swift index 1b83b32..c316248 100644 --- a/Secretly/Models/Post.swift +++ b/Secretly/Models/Post.swift @@ -19,8 +19,6 @@ struct Post: Restable { let commentsCount: Int? let latitude: Double? let longitude: Double? - let createdAt: Date? - let updatedAt: Date? var likesCount: Int? var liked: Bool? @@ -34,8 +32,6 @@ struct Post: Restable { self.longitude = longitude self.user = nil self.commentsCount = nil - self.createdAt = nil - self.updatedAt = nil self.likesCount = nil self.liked = nil } @@ -47,6 +43,9 @@ struct Post: Restable { try container.encode(imageData, forKey: .imageData) try container.encode(latitude, forKey: .latitude) try container.encode(longitude, forKey: .longitude) + try container.encode(likesCount, forKey: .likesCount) + try container.encode(liked, forKey: .liked) + } mutating func toggleLike(state:String){ From 81ad44dec5ba91a5086080c2561aae650c2842cf Mon Sep 17 00:00:00 2001 From: rhodstar Date: Thu, 26 Aug 2021 23:29:46 -0500 Subject: [PATCH 7/7] Added counter likes label in Post Cell --- Secretly/Views/PostCollectionViewCell.swift | 5 ++++- Secretly/Views/PostCollectionViewCell.xib | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Secretly/Views/PostCollectionViewCell.swift b/Secretly/Views/PostCollectionViewCell.swift index 5386aed..4edf422 100644 --- a/Secretly/Views/PostCollectionViewCell.swift +++ b/Secretly/Views/PostCollectionViewCell.swift @@ -22,7 +22,8 @@ class PostCollectionViewCell: UICollectionViewCell { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var likeState: UIButton! @IBOutlet weak var commentCounter: UILabel! - + @IBOutlet weak var likeCounter: UILabel! + override func awakeFromNib() { super.awakeFromNib() } @@ -43,6 +44,8 @@ class PostCollectionViewCell: UICollectionViewCell { let imageName = post.liked ?? false ? "heart.fill" : "heart" likeState.setImage(UIImage(systemName: imageName), for: .normal) + self.likeCounter.text = "\(self.post?.likesCount ?? 0 ) likes" + } @IBAction func likeOnTap(_ sender: UIButton) { diff --git a/Secretly/Views/PostCollectionViewCell.xib b/Secretly/Views/PostCollectionViewCell.xib index 796418d..5a63c0e 100644 --- a/Secretly/Views/PostCollectionViewCell.xib +++ b/Secretly/Views/PostCollectionViewCell.xib @@ -68,6 +68,12 @@ + @@ -80,6 +86,8 @@ + + @@ -95,6 +103,7 @@ +