Skip to content

Commit

Permalink
setup ios navigation (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
ry-itto authored Jul 9, 2024
1 parent 2358605 commit c7bf478
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 92 deletions.
7 changes: 5 additions & 2 deletions app-ios/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,15 @@ let package = Package(
name: "App",
dependencies: [
.aboutFeature,
.contributorFeature,
.favoriteFeature,
.staffFeature,
.sponsorFeature,
.timetableFeature,
.timetableDetailFeature,
.tca,
"KMPClient",
.product(name: "LicenseList", package: "LicenseList"),
]
),
.testTarget(
Expand Down Expand Up @@ -120,8 +124,7 @@ let package = Package(
name: "AboutFeature",
dependencies: [
.tca,
.product(name: "LicenseList", package: "LicenseList"),
.commonComponents
.commonComponents,
]
),
.testTarget(
Expand Down
31 changes: 3 additions & 28 deletions app-ios/Sources/AboutFeature/AboutReducer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,12 @@ public struct AboutReducer {

@ObservableState
public struct State: Equatable {
var path = StackState<Path.State>()
@Presents var destination: Destination.State?

public init(path: StackState<Path.State> = .init()) {
self.path = path
}
public init() {}
}

public enum Action: ViewAction {
case path(StackAction<Path.State, Path.Action>)
case view(View)
case presentation(PresentationAction<Destination.Action>)

Expand All @@ -42,32 +38,12 @@ public struct AboutReducer {
case medium
}

@Reducer(state: .equatable)
public enum Path {
case staffs
case contributers
case sponsors
case acknowledgements
}

public var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .view(.staffsTapped):
state.path.append(.staffs)
return .none
case .view(.contributersTapped):
state.path.append(.contributers)
return .none
case .view(.sponsorsTapped):
state.path.append(.sponsors)
return .none
case .view(.codeOfConductTapped):
state.destination = .codeOfConduct
return .none
case .view(.acknowledgementsTapped):
state.path.append(.acknowledgements)
return .none
case .view(.privacyPolicyTapped):
state.destination = .privacyPolicy
return .none
Expand All @@ -80,12 +56,11 @@ public struct AboutReducer {
case .view(.mediumTapped):
state.destination = .medium
return .none
case .presentation:
case .view:
return .none
case .path:
case .presentation:
return .none
}
}
.forEach(\.path, action: \.path)
}
}
55 changes: 21 additions & 34 deletions app-ios/Sources/AboutFeature/AboutView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,27 @@ public struct AboutView: View {
}

public var body: some View {
NavigationStack(path: $store.scope(state: \.path, action: \.path)) {
content
} destination: { store in
switch store.state {
case .staffs:
Text("Staffs")
case .contributers:
Text("Contributers")
case .sponsors:
Text("Sponsors")
case .acknowledgements:
LicenseListView()
}
}
.sheet(item: $store.scope(state: \.destination?.codeOfConduct, action: \.presentation.codeOfConduct), content: { _ in
SafariView(url: .codeOfConduct)
.ignoresSafeArea()
})
.sheet(item: $store.scope(state: \.destination?.privacyPolicy, action: \.presentation.privacyPolicy), content: { _ in
SafariView(url: .privacyPolicy)
.ignoresSafeArea()
})
.sheet(item: $store.scope(state: \.destination?.youtube, action: \.presentation.youtube), content: { _ in
SafariView(url: .youtube)
.ignoresSafeArea()
})
.sheet(item: $store.scope(state: \.destination?.xcom, action: \.presentation.xcom), content: { _ in
SafariView(url: .xcom)
.ignoresSafeArea()
})
.sheet(item: $store.scope(state: \.destination?.medium, action: \.presentation.medium), content: { _ in
SafariView(url: .medium)
.ignoresSafeArea()
})
content
.sheet(item: $store.scope(state: \.destination?.codeOfConduct, action: \.presentation.codeOfConduct), content: { _ in
SafariView(url: .codeOfConduct)
.ignoresSafeArea()
})
.sheet(item: $store.scope(state: \.destination?.privacyPolicy, action: \.presentation.privacyPolicy), content: { _ in
SafariView(url: .privacyPolicy)
.ignoresSafeArea()
})
.sheet(item: $store.scope(state: \.destination?.youtube, action: \.presentation.youtube), content: { _ in
SafariView(url: .youtube)
.ignoresSafeArea()
})
.sheet(item: $store.scope(state: \.destination?.xcom, action: \.presentation.xcom), content: { _ in
SafariView(url: .xcom)
.ignoresSafeArea()
})
.sheet(item: $store.scope(state: \.destination?.medium, action: \.presentation.medium), content: { _ in
SafariView(url: .medium)
.ignoresSafeArea()
})
}

@ViewBuilder var content: some View {
Expand Down
60 changes: 60 additions & 0 deletions app-ios/Sources/App/RootReducer.swift
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
import AboutFeature
import ComposableArchitecture
import ContributorFeature
import FavoriteFeature
import StaffFeature
import SponsorFeature
import TimetableFeature
import TimetableDetailFeature

@Reducer
public struct RootReducer {
public init() {}

public enum Path {
@Reducer(state: .equatable)
public enum Timetable {
case timetableDetail(TimetableDetailReducer)
}

@Reducer(state: .equatable)
public enum About {
case staff(StaffReducer)
case contributor(ContributorReducer)
case sponsor(SponsorReducer)
case acknowledgements
}
}

@ObservableState
public struct State: Equatable {
public var appDelegate: AppDelegateReducer.State
public var timetable: TimetableReducer.State
public var favorite: FavoriteReducer.State
public var about: AboutReducer.State
public var paths: Paths = .init()

public struct Paths: Equatable {
public var timetable = StackState<Path.Timetable.State>()
public var about = StackState<Path.About.State>()
}

public init(
appDelegate: AppDelegateReducer.State = .init(),
Expand All @@ -32,6 +57,13 @@ public struct RootReducer {
case timetable(TimetableReducer.Action)
case favorite(FavoriteReducer.Action)
case about(AboutReducer.Action)
case paths(Paths)

@CasePathable
public enum Paths {
case timetable(StackActionOf<RootReducer.Path.Timetable>)
case about(StackActionOf<RootReducer.Path.About>)
}
}

public var body: some ReducerOf<Self> {
Expand All @@ -47,5 +79,33 @@ public struct RootReducer {
Scope(state: \.about, action: \.about) {
AboutReducer()
}
navigationReducer
}

private var navigationReducer: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .about(.view(.staffsTapped)):
state.paths.about.append(.staff(.init()))
return .none

case .about(.view(.contributersTapped)):
state.paths.about.append(.contributor(.init(text: "")))
return .none

case .about(.view(.sponsorsTapped)):
state.paths.about.append(.sponsor(.init(text: "")))
return .none

case .about(.view(.acknowledgementsTapped)):
state.paths.about.append(.acknowledgements)
return .none

default:
return .none
}
}
.forEach(\.paths.about, action: \.paths.about)
.forEach(\.paths.timetable, action: \.paths.timetable)
}
}
104 changes: 76 additions & 28 deletions app-ios/Sources/App/RootView.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import AboutFeature
import FavoriteFeature
import ComposableArchitecture
import ContributorFeature
import FavoriteFeature
import LicenseList
import SponsorFeature
import StaffFeature
import SwiftUI
import TimetableDetailFeature
import TimetableFeature

private enum Tab {
Expand All @@ -13,7 +18,7 @@ private enum Tab {
}

public struct RootView: View {
private let store: StoreOf<RootReducer>
@Bindable private var store: StoreOf<RootReducer>
@State private var selection: Tab = .timetable

public init(store: StoreOf<RootReducer>) {
Expand All @@ -22,19 +27,14 @@ public struct RootView: View {

public var body: some View {
TabView(selection: $selection) {
TimetableView(
store: store.scope(
state: \.timetable,
action: \.timetable
)
)
.tag(Tab.timetable)
.tabItem {
Label(
title: { Text("Timetable") },
icon: { Image(systemName: "42.circle") }
)
}
timetableTab
.tag(Tab.timetable)
.tabItem {
Label(
title: { Text("Timetable") },
icon: { Image(systemName: "42.circle") }
)
}

Text("Map Feature")
.tag(Tab.map)
Expand All @@ -59,19 +59,14 @@ public struct RootView: View {
)
}

AboutView(
store: store.scope(
state: \.about,
action: \.about
)
)
.tag(Tab.about)
.tabItem {
Label(
title: { Text("About") },
icon: { Image(systemName: "42.circle") }
)
}
aboutTab
.tag(Tab.about)
.tabItem {
Label(
title: { Text("About") },
icon: { Image(systemName: "42.circle") }
)
}

Text("ID Card Feature")
.tag(Tab.idCard)
Expand All @@ -83,6 +78,59 @@ public struct RootView: View {
}
}
}

@MainActor
private var timetableTab: some View {
NavigationStack(
path: $store.scope(
state: \.paths.timetable,
action: \.paths.timetable
)
) {
TimetableView(
store: store.scope(
state: \.timetable,
action: \.timetable
)
)
} destination: { store in
switch store.case {
case let .timetableDetail(store):
TimetableDetailView(store: store)
}
}
}

@MainActor
private var aboutTab: some View {
NavigationStack(
path: $store.scope(
state: \.paths.about,
action: \.paths.about
)
) {
AboutView(
store: store.scope(
state: \.about,
action: \.about
)
)
} destination: { store in
switch store.case {
case let .staff(store):
StaffView(store: store)

case let .contributor(store):
ContributorView(store: store)

case let .sponsor(store):
SponsorView(store: store)

case .acknowledgements:
LicenseListView()
}
}
}
}

#Preview {
Expand Down
4 changes: 4 additions & 0 deletions app-ios/Sources/ContributorFeature/ContributorReducer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ public struct ContributorReducer {
@ObservableState
public struct State: Equatable {
var text: String

public init(text: String) {
self.text = text
}
}

public enum Action {
Expand Down
Loading

0 comments on commit c7bf478

Please sign in to comment.