Skip to content

Commit

Permalink
Merge pull request #40 from juandahurt/place
Browse files Browse the repository at this point in the history
feat: add place module with basic ui
  • Loading branch information
juandahurt authored May 30, 2022
2 parents 4eccb70 + d7968b8 commit 2a558e1
Show file tree
Hide file tree
Showing 13 changed files with 346 additions and 1 deletion.
100 changes: 100 additions & 0 deletions Payan.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@
2F8D512B2800C5AD00ADCC64 /* PYFeedBusinessLogic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F8D512A2800C5AD00ADCC64 /* PYFeedBusinessLogic.swift */; };
2F8D512D2800C5E600ADCC64 /* PYFeedDataAccessLogic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F8D512C2800C5E600ADCC64 /* PYFeedDataAccessLogic.swift */; };
2F8D51342800C7B900ADCC64 /* PYFeedViewLogic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F8D51332800C7B900ADCC64 /* PYFeedViewLogic.swift */; };
2F908E332842D104003BD450 /* PYPlaceModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F908E322842D104003BD450 /* PYPlaceModule.swift */; };
2F908E372842D1B3003BD450 /* PYPlacePageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F908E362842D1B3003BD450 /* PYPlacePageView.swift */; };
2F908E3A2842D1DD003BD450 /* PYPlaceViewLogic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F908E392842D1DD003BD450 /* PYPlaceViewLogic.swift */; };
2F908E3D2842D32F003BD450 /* PYPlaceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F908E3C2842D32F003BD450 /* PYPlaceViewModel.swift */; };
2F908E402842D33F003BD450 /* PYPlaceInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F908E3F2842D33F003BD450 /* PYPlaceInteractor.swift */; };
2F908E422842D34B003BD450 /* PYPlaceBusinessLogic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F908E412842D34B003BD450 /* PYPlaceBusinessLogic.swift */; };
2F908E452843032E003BD450 /* PYPlace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F908E442843032E003BD450 /* PYPlace.swift */; };
2F908E4728430396003BD450 /* PYPlaceDataAccessLogic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F908E4628430396003BD450 /* PYPlaceDataAccessLogic.swift */; };
2F908E4A28430458003BD450 /* PYPlaceNetworkWorker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F908E4928430458003BD450 /* PYPlaceNetworkWorker.swift */; };
2F9AFADE27FA393C006DC8D6 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 2F9AFADD27FA393C006DC8D6 /* FirebaseAnalytics */; };
2FA03DF7283C51940094976A /* Purace in Frameworks */ = {isa = PBXBuildFile; productRef = 2FA03DF6283C51940094976A /* Purace */; };
2FA3BB012815E626005BF493 /* PYNetworkRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FA3BB002815E626005BF493 /* PYNetworkRequest.swift */; };
Expand Down Expand Up @@ -79,6 +88,15 @@
2F8D512A2800C5AD00ADCC64 /* PYFeedBusinessLogic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYFeedBusinessLogic.swift; sourceTree = "<group>"; };
2F8D512C2800C5E600ADCC64 /* PYFeedDataAccessLogic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYFeedDataAccessLogic.swift; sourceTree = "<group>"; };
2F8D51332800C7B900ADCC64 /* PYFeedViewLogic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYFeedViewLogic.swift; sourceTree = "<group>"; };
2F908E322842D104003BD450 /* PYPlaceModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYPlaceModule.swift; sourceTree = "<group>"; };
2F908E362842D1B3003BD450 /* PYPlacePageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYPlacePageView.swift; sourceTree = "<group>"; };
2F908E392842D1DD003BD450 /* PYPlaceViewLogic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYPlaceViewLogic.swift; sourceTree = "<group>"; };
2F908E3C2842D32F003BD450 /* PYPlaceViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYPlaceViewModel.swift; sourceTree = "<group>"; };
2F908E3F2842D33F003BD450 /* PYPlaceInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYPlaceInteractor.swift; sourceTree = "<group>"; };
2F908E412842D34B003BD450 /* PYPlaceBusinessLogic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYPlaceBusinessLogic.swift; sourceTree = "<group>"; };
2F908E442843032E003BD450 /* PYPlace.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYPlace.swift; sourceTree = "<group>"; };
2F908E4628430396003BD450 /* PYPlaceDataAccessLogic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYPlaceDataAccessLogic.swift; sourceTree = "<group>"; };
2F908E4928430458003BD450 /* PYPlaceNetworkWorker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYPlaceNetworkWorker.swift; sourceTree = "<group>"; };
2F9AFAE027FA3AFF006DC8D6 /* Emogger */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Emogger; path = Modules/Emogger; sourceTree = "<group>"; };
2FA3BB002815E626005BF493 /* PYNetworkRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYNetworkRequest.swift; sourceTree = "<group>"; };
2FA3BB022815E65A005BF493 /* PYNetworkMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PYNetworkMethod.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -252,6 +270,78 @@
path = Protocols;
sourceTree = "<group>";
};
2F908E312842D095003BD450 /* Place */ = {
isa = PBXGroup;
children = (
2F908E4828430447003BD450 /* Workers */,
2F908E432842D368003BD450 /* Entities */,
2F908E3E2842D333003BD450 /* Interactor */,
2F908E382842D1D1003BD450 /* Protocols */,
2F908E342842D1A0003BD450 /* UI */,
2F908E322842D104003BD450 /* PYPlaceModule.swift */,
);
path = Place;
sourceTree = "<group>";
};
2F908E342842D1A0003BD450 /* UI */ = {
isa = PBXGroup;
children = (
2F908E3B2842D325003BD450 /* View Model */,
2F908E352842D1A4003BD450 /* Page */,
);
path = UI;
sourceTree = "<group>";
};
2F908E352842D1A4003BD450 /* Page */ = {
isa = PBXGroup;
children = (
2F908E362842D1B3003BD450 /* PYPlacePageView.swift */,
);
path = Page;
sourceTree = "<group>";
};
2F908E382842D1D1003BD450 /* Protocols */ = {
isa = PBXGroup;
children = (
2F908E392842D1DD003BD450 /* PYPlaceViewLogic.swift */,
2F908E412842D34B003BD450 /* PYPlaceBusinessLogic.swift */,
2F908E4628430396003BD450 /* PYPlaceDataAccessLogic.swift */,
);
path = Protocols;
sourceTree = "<group>";
};
2F908E3B2842D325003BD450 /* View Model */ = {
isa = PBXGroup;
children = (
2F908E3C2842D32F003BD450 /* PYPlaceViewModel.swift */,
);
path = "View Model";
sourceTree = "<group>";
};
2F908E3E2842D333003BD450 /* Interactor */ = {
isa = PBXGroup;
children = (
2F908E3F2842D33F003BD450 /* PYPlaceInteractor.swift */,
);
path = Interactor;
sourceTree = "<group>";
};
2F908E432842D368003BD450 /* Entities */ = {
isa = PBXGroup;
children = (
2F908E442843032E003BD450 /* PYPlace.swift */,
);
path = Entities;
sourceTree = "<group>";
};
2F908E4828430447003BD450 /* Workers */ = {
isa = PBXGroup;
children = (
2F908E4928430458003BD450 /* PYPlaceNetworkWorker.swift */,
);
path = Workers;
sourceTree = "<group>";
};
2F9AFADF27FA3AFF006DC8D6 /* Packages */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -423,6 +513,7 @@
3DF708E426F2A64900FD24CF /* Domain Modules */ = {
isa = PBXGroup;
children = (
2F908E312842D095003BD450 /* Place */,
2F8C80FC28010CBA00A8E7FD /* Collection */,
3D3A3848270A53C700E2EF94 /* Feed */,
);
Expand Down Expand Up @@ -535,8 +626,12 @@
2F8789F52842846100C3A40F /* UIViewController+popGesture.swift in Sources */,
2F19514728394F3B007B0E73 /* PYPlaceCategory.swift in Sources */,
6D46485D281D9B21001FACC0 /* PYCollection.swift in Sources */,
2F908E3A2842D1DD003BD450 /* PYPlaceViewLogic.swift in Sources */,
2F908E402842D33F003BD450 /* PYPlaceInteractor.swift in Sources */,
3DB9D546277F573F00E4D45A /* FirebaseAppDelegate.swift in Sources */,
2F908E372842D1B3003BD450 /* PYPlacePageView.swift in Sources */,
2F06927D2801F6C50068AA79 /* PYCollectionModule.swift in Sources */,
2F908E452843032E003BD450 /* PYPlace.swift in Sources */,
2FA3BB092815F24D005BF493 /* PYServerResponse.swift in Sources */,
3D496F87277E353C009BFF74 /* AnalyticsEngine.swift in Sources */,
2F832F1F283D84A000702E71 /* PYHeroPreview.swift in Sources */,
Expand All @@ -545,13 +640,16 @@
2F8CADF128024AF700F166E0 /* PYCollectionNetworkWorker.swift in Sources */,
2F8D51342800C7B900ADCC64 /* PYFeedViewLogic.swift in Sources */,
2F0692752801F5770068AA79 /* PYCollectionBusinessLogic.swift in Sources */,
2F908E4A28430458003BD450 /* PYPlaceNetworkWorker.swift in Sources */,
6DB6E4F52818A96E0002A77C /* PYModule.swift in Sources */,
2F8D512D2800C5E600ADCC64 /* PYFeedDataAccessLogic.swift in Sources */,
2F63C88227FCD62500857056 /* PYFeedInteractor.swift in Sources */,
3D496F8E277E39DF009BFF74 /* FirebaseAnalytics.swift in Sources */,
2F19514928394F9A007B0E73 /* PYFeedPage.swift in Sources */,
2FC270EB2837F0AB00770B46 /* PYFeedPageView.swift in Sources */,
2FA3BB052815E707005BF493 /* PYNetworkError.swift in Sources */,
2F908E332842D104003BD450 /* PYPlaceModule.swift in Sources */,
2F908E4728430396003BD450 /* PYPlaceDataAccessLogic.swift in Sources */,
3D496F89277E357C009BFF74 /* AnalyticsManager.swift in Sources */,
3DF708BD26F2A4D200FD24CF /* AppDelegate.swift in Sources */,
2F8CADEF28024A4900F166E0 /* PYCollectionDataAccessLogic.swift in Sources */,
Expand All @@ -561,11 +659,13 @@
3D496F84277E34F3009BFF74 /* AnalyticsEvent.swift in Sources */,
2F19514C283954FB007B0E73 /* PYFeedViewModel.swift in Sources */,
3D0ECF792782496100847E0D /* Environment.swift in Sources */,
2F908E422842D34B003BD450 /* PYPlaceBusinessLogic.swift in Sources */,
2FD5786E2840512B007A6EF5 /* PYCollectionPageView.swift in Sources */,
3DF708BF26F2A4D200FD24CF /* SceneDelegate.swift in Sources */,
2F78195128170E820096E342 /* PYNetworkingAppDelegate.swift in Sources */,
2F06927B2801F6360068AA79 /* PYCollectionInteractor.swift in Sources */,
2F2B9FF328408B9200565D3E /* PYCollectionViewModel.swift in Sources */,
2F908E3D2842D32F003BD450 /* PYPlaceViewModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,16 @@ struct PYCollectionPageView: View, PYCollectionViewLogic {
.multilineTextAlignment(.center)
}.padding()
}
.contentShape(Rectangle())
.skeleton(with: viewModel.isLoading)
.shape(type: .rectangle)
.animation(type: .linear())
.appearance(type: .solid())
.frame(width: UIScreen.main.bounds.width / CGFloat(columns), height: correctHeight)
.onTapGesture {
guard let url = URL(string: element.deepLink) else { return }
PYRoutingManager.shared.open(url: url)
}
}
}
.transition(.slide)
Expand Down
19 changes: 19 additions & 0 deletions Payan/App/Domain Modules/Place/Entities/PYPlace.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// PYPlace.swift
// Payan
//
// Created by Juan Hurtado on 28/05/22.
//

import Foundation

struct PYPlace: Decodable {
var title: String
var subtitle: String
var image: String
var description: String?
}

extension PYPlace {
static let empty = PYPlace(title: "", subtitle: "", image: "")
}
28 changes: 28 additions & 0 deletions Payan/App/Domain Modules/Place/Interactor/PYPlaceInteractor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// PYPlaceInteractor.swift
// Payan
//
// Created by Juan Hurtado on 28/05/22.
//

import Foundation

class PYPlaceInteractor: PYPlaceBusinessLogic {
var worker: PYPlaceDataAccessLogic

init(worker: PYPlaceDataAccessLogic = PYPlaceNetworkWorker()) {
self.worker = worker
}

func getPlace(identifiedBy id: String, completion: @escaping (Result<PYPlace, Error>) -> Void) {
worker.fecthPlace(id: id) { res in
DispatchQueue.main.async {
switch res {
case .success(let place):
completion(.success(place))
case .failure(_): break
}
}
}
}
}
18 changes: 18 additions & 0 deletions Payan/App/Domain Modules/Place/PYPlaceModule.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// PYPlaceModule.swift
// Payan
//
// Created by Juan Hurtado on 28/05/22.
//

import Foundation
import SwiftUI

final class PYPlaceModule: PYModule {
var host: String = "place"

func getViewController(params: [URLQueryItem]) -> UIViewController? {
guard !params.isEmpty, params[0].name == "id", let placeId = params[0].value else { return nil }
return UIHostingController(rootView: PYPlacePageView(placeId: placeId))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// PYPlaceBusinessLogic.swift
// Payan
//
// Created by Juan Hurtado on 28/05/22.
//

import Foundation

protocol PYPlaceBusinessLogic {
var worker: PYPlaceDataAccessLogic { get }

func getPlace(identifiedBy id: String, completion: @escaping (Result<PYPlace,Error>) -> Void)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// PYPlaceDataAccessLogic.swift
// Payan
//
// Created by Juan Hurtado on 28/05/22.
//

import Foundation

protocol PYPlaceDataAccessLogic {
func fecthPlace(id: String, completion: @escaping (Result<PYPlace,Error>) -> Void)
}
12 changes: 12 additions & 0 deletions Payan/App/Domain Modules/Place/Protocols/PYPlaceViewLogic.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// PYPlaceViewLogic.swift
// Payan
//
// Created by Juan Hurtado on 28/05/22.
//

import Foundation

protocol PYPlaceViewLogic {
var placeId: String { get }
}
78 changes: 78 additions & 0 deletions Payan/App/Domain Modules/Place/UI/Page/PYPlacePageView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//
// PYPlacePageView.swift
// Payan
//
// Created by Juan Hurtado on 28/05/22.
//

import Foundation
import SwiftUI
import Purace

struct PYPlacePageView: View, PYPlaceViewLogic {
var placeId: String

@StateObject var viewModel = PYPlaceViewModel()

init(placeId: String) {
self.placeId = placeId
}

var navBar: some View {
HStack(alignment: .center) {
Image(systemName: "chevron.left")
.foregroundColor(.white)
.scaleEffect(1.2)
.onTapGesture {
PYRoutingManager.shared.pop()
}
Spacer()
}.padding()
.frame(height: 50)
}

var image: some View {
let url = URL(string: viewModel.place.image)
return ZStack {
PuraceImageView(url: url)
.aspectRatio(contentMode: .fill)
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height * 0.35)
.clipped()
LinearGradient(colors: [.black.opacity(0.55), .clear], startPoint: .top, endPoint: .center)
}.frame(height: UIScreen.main.bounds.height * 0.35)
}

var title: some View {
VStack(spacing: 10) {
PuraceTextView(viewModel.place.title, fontSize: 18, weight: .medium)
PuraceTextView(viewModel.place.subtitle, fontSize: 12, textColor: PuraceStyle.Color.N4)
}
}

var description: some View {
PuraceTextView(viewModel.place.description ?? "")
}

var body: some View {
ZStack {
ScrollView {
VStack {
image
title
.padding(.top)
description
.padding()
Spacer()
}
}
VStack {
navBar
Spacer()
}
}
.navigationBarHidden(true)
.onFirstAppear {
viewModel.getPlace(id: placeId)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// PYPlaceViewModel.swift
// Payan
//
// Created by Juan Hurtado on 28/05/22.
//

import Foundation

class PYPlaceViewModel: ObservableObject {
@Published var place: PYPlace = .empty
let interactor: PYPlaceBusinessLogic

init(interactor: PYPlaceBusinessLogic = PYPlaceInteractor()) {
self.interactor = interactor
}

func getPlace(id: String) {
interactor.getPlace(identifiedBy: id) { [weak self] res in
guard let self = self else { return }
switch res {
case .success(let place):
self.place = place
case .failure(_): break
}
}
}
}
Loading

0 comments on commit 2a558e1

Please sign in to comment.