Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions HotSpot/Sources/App/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import UIKit

class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
let sceneConfig = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
sceneConfig.delegateClass = SceneDelegate.self
return sceneConfig
}
}
12 changes: 4 additions & 8 deletions HotSpot/Sources/App/HotSpotApp.swift
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import SwiftUI
import ComposableArchitecture

@main
struct HotSpotApp: App {
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate

var body: some Scene {
WindowGroup {
AppCoordinatorView(
store: Store(
initialState: AppCoordinator.State(),
reducer: { AppCoordinator() }
)
)
Color.clear
}
}
}
}
19 changes: 19 additions & 0 deletions HotSpot/Sources/App/SceneDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import SwiftUI
import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
private var coordinator: AppCoordinator?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }

UINavigationBar.configureAppearance()

let window = UIWindow(windowScene: windowScene)
self.window = window

coordinator = AppCoordinator(window: window)
coordinator?.start()
}
}
2 changes: 1 addition & 1 deletion HotSpot/Sources/Domain/Model/PaginationState.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

struct PaginationState {
struct PaginationState: Equatable {
var currentPage: Int
var isLastPage: Bool
var isLoading: Bool
Expand Down
148 changes: 71 additions & 77 deletions HotSpot/Sources/Presentation/Coordinator/AppCoordinator.swift
Original file line number Diff line number Diff line change
@@ -1,84 +1,78 @@
import SwiftUI
import UIKit
import ComposableArchitecture

@Reducer
struct AppCoordinator {
struct State: Equatable {
var map: MapStore.State = .init()
var search: SearchStore.State?
var shopDetail: ShopDetailStore.State?
var selectedShop: ShopModel?
var isDetailPresented: Bool = false
final class AppCoordinator {
private let window: UIWindow
private let navigationController: UINavigationController

init(window: UIWindow) {
self.window = window
self.navigationController = CustomNavigationController()
}

enum Action {
case map(MapStore.Action)
case search(SearchStore.Action)
case shopDetail(ShopDetailStore.Action)

case showShopDetail(ShopModel)
case showSearch
case dismissSearch
case dismissDetail

func start() {
let mapView = MapView(
store: Store(
initialState: MapStore.State(),
reducer: { MapStore() }
)
)
.environment(\.coordinator, self)

let hostingController = UIHostingController(rootView: mapView)
navigationController.viewControllers = [hostingController]

window.rootViewController = navigationController
window.makeKeyAndVisible()
}

var body: some ReducerOf<Self> {
Scope(state: \.map, action: \.map) {
MapStore()
}

func showSearch() {
let searchView = SearchView(
store: Store(
initialState: SearchStore.State(),
reducer: { SearchStore() }
)
)
.environment(\.coordinator, self)

push(searchView)
}

func showSearchFilter() {
let searchFilterView = SearchFilterView(
store: Store(
initialState: SearchFilterStore.State(),
reducer: { SearchFilterStore() }
)
)
.environment(\.coordinator, self)

push(searchFilterView)
}

func showShopDetail(_ shop: ShopModel) {
let shopDetailView = ShopDetailView(
store: Store(
initialState: ShopDetailStore.State(shop: shop),
reducer: { ShopDetailStore() }
)
)
.environment(\.coordinator, self)

Reduce { state, action in
switch action {
case .map(.showSearch), .showSearch:
state.search = .init()
return .none

case .search(.pop), .dismissSearch:
state.search = nil
return .none

case let .search(.selectShop(shop)):
state.selectedShop = shop
state.isDetailPresented = true
return .send(.showShopDetail(shop))

case let .showShopDetail(shop):
state.shopDetail = .init(shop: shop)
state.isDetailPresented = true
return .none

case .shopDetail(.pop):
state.shopDetail = nil
state.selectedShop = nil
state.isDetailPresented = false
return .none

case .dismissDetail:
state.shopDetail = nil
state.selectedShop = nil
state.isDetailPresented = false
return .none

case let .map(.showShopDetail(shop)):
state.selectedShop = shop
state.isDetailPresented = true
return .send(.showShopDetail(shop))

case .map:
return .none

case .search:
return .none

case .shopDetail:
return .none
}
}
.ifLet(\.search, action: \.search) {
SearchStore()
}
.ifLet(\.shopDetail, action: \.shopDetail) {
ShopDetailStore()
}
push(shopDetailView)
}

private func push<Content: View>(_ view: Content, animated: Bool = true) {
let hostingController = UIHostingController(rootView: view)
navigationController.pushViewController(hostingController, animated: animated)
}

func pop(animated: Bool = true) {
navigationController.popViewController(animated: animated)
}

func popToRoot(animated: Bool = true) {
navigationController.popToRootViewController(animated: animated)
}
}
}
85 changes: 0 additions & 85 deletions HotSpot/Sources/Presentation/Coordinator/AppCoordinatorView.swift

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import UIKit

class CustomNavigationController: UINavigationController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
interactivePopGestureRecognizer?.isEnabled = true
isNavigationBarHidden = true
}

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
34 changes: 34 additions & 0 deletions HotSpot/Sources/Presentation/Coordinator/NavigationConfig.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import SwiftUI
import UIKit

extension UINavigationBar {
static func configureAppearance() {
let appearance = UINavigationBarAppearance()
appearance.configureWithTransparentBackground()
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
UINavigationBar.appearance().isTranslucent = true
}
}

struct NavigationControllerKey: EnvironmentKey {
static let defaultValue: UINavigationController = UINavigationController()
}

extension EnvironmentValues {
var navigationController: UINavigationController {
get { self[NavigationControllerKey.self] }
set { self[NavigationControllerKey.self] = newValue }
}
}

struct CoordinatorKey: EnvironmentKey {
static let defaultValue: AppCoordinator? = nil
}

extension EnvironmentValues {
var coordinator: AppCoordinator? {
get { self[CoordinatorKey.self] }
set { self[CoordinatorKey.self] = newValue }
}
}
11 changes: 0 additions & 11 deletions HotSpot/Sources/Presentation/Map/MapStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
import ComposableArchitecture
import MapKit

@Reducer

Check failure on line 6 in HotSpot/Sources/Presentation/Map/MapStore.swift

View workflow job for this annotation

GitHub Actions / run-unitTest

circular reference resolving attached macro 'Reducer'

Check failure on line 6 in HotSpot/Sources/Presentation/Map/MapStore.swift

View workflow job for this annotation

GitHub Actions / run-unitTest

circular reference resolving attached macro 'Reducer'
struct MapStore {

Check failure on line 7 in HotSpot/Sources/Presentation/Map/MapStore.swift

View workflow job for this annotation

GitHub Actions / run-unitTest

circular reference

Check failure on line 7 in HotSpot/Sources/Presentation/Map/MapStore.swift

View workflow job for this annotation

GitHub Actions / run-unitTest

circular reference

Check failure on line 7 in HotSpot/Sources/Presentation/Map/MapStore.swift

View workflow job for this annotation

GitHub Actions / run-unitTest

circular reference

Check failure on line 7 in HotSpot/Sources/Presentation/Map/MapStore.swift

View workflow job for this annotation

GitHub Actions / run-unitTest

circular reference

Check failure on line 7 in HotSpot/Sources/Presentation/Map/MapStore.swift

View workflow job for this annotation

GitHub Actions / run-unitTest

circular reference

Check failure on line 7 in HotSpot/Sources/Presentation/Map/MapStore.swift

View workflow job for this annotation

GitHub Actions / run-unitTest

circular reference
@Dependency(\.shopRepository) var shopRepository

struct State: Equatable {
var shops: [ShopModel] = []
var visibleShops: [ShopModel] = []
var selectedShop: ShopModel? = nil
var region: MKCoordinateRegion = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 35.6762, longitude: 139.6503),
span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
Expand All @@ -24,8 +23,6 @@
case fetchShops
case updateShops([ShopModel])
case handleError(Error)
case showSearch
case showShopDetail(ShopModel)
}

var body: some ReducerOf<Self> {
Expand Down Expand Up @@ -64,13 +61,6 @@
case let .handleError(error):
state.error = error.localizedDescription
return .none

case .showSearch:
return .none

case let .showShopDetail(shop):
state.selectedShop = shop
return .none
}
}
}
Expand Down Expand Up @@ -104,11 +94,10 @@
}

// MARK: - Equatable
extension MapStore.State {

Check failure on line 97 in HotSpot/Sources/Presentation/Map/MapStore.swift

View workflow job for this annotation

GitHub Actions / run-unitTest

'State' is not a member type of struct 'HotSpot.MapStore'

Check failure on line 97 in HotSpot/Sources/Presentation/Map/MapStore.swift

View workflow job for this annotation

GitHub Actions / run-unitTest

'State' is not a member type of struct 'HotSpot.MapStore'
static func == (lhs: MapStore.State, rhs: MapStore.State) -> Bool {
lhs.shops == rhs.shops &&
lhs.visibleShops == rhs.visibleShops &&
lhs.selectedShop == rhs.selectedShop &&
lhs.region.center.latitude == rhs.region.center.latitude &&
lhs.region.center.longitude == rhs.region.center.longitude &&
lhs.region.span.latitudeDelta == rhs.region.span.latitudeDelta &&
Expand Down
Loading
Loading