diff --git a/Secretly.xcodeproj/project.pbxproj b/Secretly.xcodeproj/project.pbxproj index 8dd4829..0370a87 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 */; }; + 92CC860426E33B7F00BE71F5 /* Like.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92CC860326E33B7F00BE71F5 /* Like.swift */; }; + 92CC860826E34AF700BE71F5 /* LikeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92CC860726E34AF700BE71F5 /* 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 = ""; }; + 92CC860326E33B7F00BE71F5 /* Like.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Like.swift; sourceTree = ""; }; + 92CC860726E34AF700BE71F5 /* 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 */, + 92CC860726E34AF700BE71F5 /* LikeService.swift */, ); path = Services; sourceTree = ""; @@ -248,6 +253,7 @@ 307A30572661AD540020DF8B /* User.swift */, 30C77CB3266AF47300A888DC /* Credentials.swift */, 30C77CB5266AF48300A888DC /* CurrentUser.swift */, + 92CC860326E33B7F00BE71F5 /* 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 */, + 92CC860426E33B7F00BE71F5 /* 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 */, + 92CC860826E34AF700BE71F5 /* 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.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Secretly.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Secretly.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Secretly/Base.lproj/Main.storyboard b/Secretly/Base.lproj/Main.storyboard index 4ed5b13..9cbb258 100644 --- a/Secretly/Base.lproj/Main.storyboard +++ b/Secretly/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + diff --git a/Secretly/Models/Like.swift b/Secretly/Models/Like.swift new file mode 100644 index 0000000..7935035 --- /dev/null +++ b/Secretly/Models/Like.swift @@ -0,0 +1,22 @@ +// +// Like.swift +// Secretly +// +// Created by Berenice Medel on 04/09/21. +// Copyright © 2021 3zcurdia. All rights reserved. +// + +import Foundation + +struct Like: Restable { + let id, userID, postId: Int? + let createdAt, updatedAt: String? + + init(postId: Int){ + self.id = nil + self.postId = postId + self.createdAt = nil + self.updatedAt = nil + self.userID = nil + } +} diff --git a/Secretly/Models/Post.swift b/Secretly/Models/Post.swift index eba5ff0..9940a8d 100644 --- a/Secretly/Models/Post.swift +++ b/Secretly/Models/Post.swift @@ -17,10 +17,12 @@ struct Post: Restable { var imageData: String? let user: User? let commentsCount: Int? + let likesCount: Int? let latitude: Double? 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) { self.content = content @@ -32,8 +34,10 @@ struct Post: Restable { self.longitude = longitude self.user = nil self.commentsCount = nil + self.likesCount = nil self.createdAt = nil self.updatedAt = nil + self.liked = nil } func encode(to encoder: Encoder) throws { diff --git a/Secretly/Network/HttpResponse.swift b/Secretly/Network/HttpResponse.swift index eb0543a..e20f847 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 udata = data, !udata.isEmpty { + return status.result().map { _ in data } + } else { + return status.result().map { _ in nil } + } } } diff --git a/Secretly/Network/RestClient.swift b/Secretly/Network/RestClient.swift index 3048ccf..ffc4580 100644 --- a/Secretly/Network/RestClient.swift +++ b/Secretly/Network/RestClient.swift @@ -68,7 +68,7 @@ struct RestClient { } func delete(model: T, complete: @escaping (Result) -> Void) { - client.delete(path: "\(path)/\(model.id)") { result in + client.delete(path: "\(path)") { result in let newResult = result.flatMap { parse(data: $0) } complete(newResult) } diff --git a/Secretly/Services/LikeService.swift b/Secretly/Services/LikeService.swift new file mode 100644 index 0000000..1658f01 --- /dev/null +++ b/Secretly/Services/LikeService.swift @@ -0,0 +1,30 @@ +// +// LikeService.swift +// Secretly +// +// Created by Berenice Medel on 04/09/21. +// Copyright © 2021 3zcurdia. All rights reserved. +// + +import Foundation + + +struct LikeService { + private var endpoint: RestClient + + init(post: Post) { + self.endpoint = RestClient(client: AmacaConfig.shared.httpClient, path: "/api/v1/posts/\(post.id!)/likes") + } + + func create(_ model: Like, complete: @escaping (Result) -> Void ) { + try? endpoint.create(model: model) { result in + DispatchQueue.main.async { complete(result) } + } + } + + func delete(_ model: Like, complete: @escaping (Result) -> Void ) { + try? endpoint.delete(model: model) { result in + DispatchQueue.main.async { complete(result) } + } + } +} diff --git a/Secretly/Views/PostCollectionViewCell.swift b/Secretly/Views/PostCollectionViewCell.swift index ee08d53..6694a48 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 post: Post? { didSet { updateView() @@ -18,13 +19,63 @@ class PostCollectionViewCell: UICollectionViewCell { @IBOutlet weak var authorView: AuthorView! @IBOutlet weak var contentLabel: UILabel! @IBOutlet weak var imageView: UIImageView! - @IBOutlet weak var likeState: UIImageView! @IBOutlet weak var commentCounter: UILabel! - + @IBOutlet weak var likeState: UIButton! + @IBOutlet weak var likeCounter: UILabel! + override func awakeFromNib() { super.awakeFromNib() } + @IBAction func onLikeClicked(_ sender: Any) { + let like = Like(postId: (self.post?.id)!) + let likeService = LikeService(post: post!) + if (post?.liked)!{ + deleteLike(like: like, likeService: likeService) + }else{ + createLike(like: like, likeService: likeService) + } + } + + func createLike(like: Like, likeService: LikeService){ + likeService.create(like) { + [unowned self] result in + switch result { + case .success(let like): + print("there is a new like \(like?.id ?? 0)") + DispatchQueue.main.async { + self.post!.liked = true + self.likeState.tintColor = .red + self.likeState.setImage(UIImage(systemName: "heart.fill"), for: .normal) + let newCounter = + Int(self.likeCounter.text!)! + 1 + self.likeCounter.text = String(newCounter) + } + case .failure(let err): + print(err.localizedDescription) + } + } + } + + func deleteLike(like: Like, likeService: LikeService){ + likeService.delete(like) { + [unowned self] result in + switch result { + case .success(let _): + print("like deleted") + DispatchQueue.main.async { + let newCounter = + Int(self.likeCounter.text!)! - 1 + self.likeCounter.text = String(newCounter) + self.likeState.tintColor = .white + self.likeState.setImage(UIImage(systemName: "heart"), for: .normal) + self.post!.liked = false + } + case .failure(let err): + print(err.localizedDescription) + } + } + } func updateView() { imageView.image = nil guard let post = post else { return } @@ -33,9 +84,18 @@ class PostCollectionViewCell: UICollectionViewCell { } self.contentLabel.text = post.content self.commentCounter.text = String(describing: post.commentsCount ?? 0) + self.likeCounter.text = String(describing: post.likesCount ?? 0) if let postImg = post.image { ImageLoader.load(postImg.mediumUrl) { img in self.imageView.image = img } } self.authorView.author = post.user + if post.liked!{ + self.likeState.tintColor = .red + self.likeState.setImage(UIImage(systemName: "heart.fill"), for: .normal) + }else{ + self.likeState.tintColor = .white + self.likeState.setImage(UIImage(systemName: "heart"), for: .normal) + } } + } diff --git a/Secretly/Views/PostCollectionViewCell.xib b/Secretly/Views/PostCollectionViewCell.xib index 7b3a4e2..9d35e57 100644 --- a/Secretly/Views/PostCollectionViewCell.xib +++ b/Secretly/Views/PostCollectionViewCell.xib @@ -1,8 +1,8 @@ - + - + @@ -30,14 +30,6 @@ - - - - - - - -