Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iOS] Implement SponsorView base #590

Merged
merged 1 commit into from
Aug 17, 2023
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
18 changes: 15 additions & 3 deletions app-ios/Modules/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ var package = Package(
.library(name: "Component", targets: ["Component"]),
.library(name: "FloorMap", targets: ["FloorMap"]),
.library(name: "Session", targets: ["Session"]),
.library(name: "Sponsor", targets: ["Sponsor"]),
.library(name: "Timetable", targets: ["Timetable"]),
.library(name: "Navigation", targets: ["Navigation"]),
],
Expand Down Expand Up @@ -58,6 +59,17 @@ var package = Package(
]
),

.target(
name: "Contributor",
dependencies: [
"Assets",
"Component",
"Model",
"shared",
"Theme",
]
),

.target(
name: "FloorMap",
dependencies: [
Expand Down Expand Up @@ -91,10 +103,9 @@ var package = Package(
),

.target(
name: "Contributor",
name: "Sponsor",
dependencies: [
"Assets",
"Component",
"Model",
"shared",
"Theme",
Expand Down Expand Up @@ -137,10 +148,11 @@ var package = Package(
dependencies: [
"About",
"Assets",
"Contributor",
"FloorMap",
"Session",
"Sponsor",
"Stamps",
"Contributor",
"Theme",
"Timetable",
]
Expand Down
25 changes: 18 additions & 7 deletions app-ios/Modules/Sources/About/AboutView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@ import Theme

enum AboutRouting: Hashable {
case contributors
case sponsors
}

public struct AboutView<ContributorView: View>: View {
public struct AboutView<ContributorView: View, SponsorView: View>: View {
private let contributorViewProvider: ViewProvider<Void, ContributorView>
private let sponsorViewProvider: ViewProvider<Void, SponsorView>

public init(contributorViewProvider: @escaping ViewProvider<Void, ContributorView>) {
public init(
contributorViewProvider: @escaping ViewProvider<Void, ContributorView>,
sponsorViewProvider: @escaping ViewProvider<Void, SponsorView>
) {
self.contributorViewProvider = contributorViewProvider
self.sponsorViewProvider = sponsorViewProvider
}

public var body: some View {
Expand Down Expand Up @@ -60,10 +66,12 @@ public struct AboutView<ContributorView: View>: View {
)
}
Divider()
ListTile(
icon: Assets.Icons.apartment.swiftUIImage,
title: "スポンサー"
)
NavigationLink(value: AboutRouting.sponsors) {
ListTile(
icon: Assets.Icons.apartment.swiftUIImage,
title: "スポンサー"
)
}
Divider()
SectionTitle(title: "Others")
ListTile(
Expand Down Expand Up @@ -113,6 +121,8 @@ public struct AboutView<ContributorView: View>: View {
switch routing {
case .contributors:
contributorViewProvider(())
case .sponsors:
sponsorViewProvider(())
}
}
}
Expand All @@ -121,6 +131,7 @@ public struct AboutView<ContributorView: View>: View {

#Preview {
AboutView(
contributorViewProvider: {_ in EmptyView()}
contributorViewProvider: {_ in EmptyView()},
sponsorViewProvider: {_ in EmptyView()}
)
}
3 changes: 3 additions & 0 deletions app-ios/Modules/Sources/Model/Extension/Sponsor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import shared

extension Sponsor: Identifiable {}
4 changes: 4 additions & 0 deletions app-ios/Modules/Sources/Navigation/RootView.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import About
import Sponsor
import Assets
import Contributor
import FloorMap
Expand Down Expand Up @@ -59,6 +60,9 @@ public struct RootView: View {
AboutView(
contributorViewProvider: { _ in
ContributorView()
},
sponsorViewProvider: { _ in
SponsorView()
}
)
.tag(Tab.about)
Expand Down
68 changes: 68 additions & 0 deletions app-ios/Modules/Sources/Sponsor/SponsorGridView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import Model
import shared
import SwiftUI
import Theme

struct SponsorGridView: View {

let title: String
let sponsors: [Sponsor]
let columns: Int
var action: (Sponsor) -> Void

var body: some View {
VStack(alignment: .leading, spacing: 16) {
Text(title)
.font(.system(size: 22, weight: .semibold, design: .default))
.foregroundStyle(AssetColors.Surface.onSurface.swiftUIColor)
LazyVGrid(columns: Array(repeating: GridItem(spacing: 16), count: columns), spacing: 16) {
ForEach(sponsors) { sponsor in
SponsorItemView(sponsor: sponsor) {
action(sponsor)
}
}
}
}
}
}

struct SponsorItemView: View {

let sponsor: Sponsor
let action: () -> Void

var body: some View {
ZStack {
AssetColors.Custom.white.swiftUIColor
Button {
action()
} label: {
AsyncImage(url: URL(string: sponsor.logo)) { image in
image
.resizable()
.frame(minWidth: 0, maxWidth: .infinity)
.frame(minHeight: 0, maxHeight: .infinity)
} placeholder: {
AssetColors.Custom.white.swiftUIColor
}
}
}
.frame(height: sponsor.plan.itemHeight)
.clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
}
}

private extension Plan {
var itemHeight: CGFloat {
switch self {
case .platinum:
return 112
case .gold:
return 112
case .supporter:
return 72
default:
return 72
}
}
}
59 changes: 59 additions & 0 deletions app-ios/Modules/Sources/Sponsor/SponsorView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import shared
import SwiftUI
import Theme

public struct SponsorView: View {
@ObservedObject var viewModel: SponsorViewModel = .init()

public init() {}

public var body: some View {
Group {
switch viewModel.state.planGroupedSponsors {
case .initial, .loading:
ProgressView()
.task {
await viewModel.load()
}
case .loaded(let planGroupedSponsors):
ScrollView {
LazyVStack(spacing: 24) {
ForEach(planGroupedSponsors.keys.sorted(by: {
$0.ordinal < $1.ordinal
}), id: \.self) { plan in
SponsorGridView(
title: plan.name,
sponsors: planGroupedSponsors[plan] ?? [],
columns: plan.column
) { _ in }
}
}
.padding(16)
}
case .failed:
EmptyView()
}
}
.navigationTitle("Sponsors")
.background(AssetColors.Surface.surface.swiftUIColor)
}
}

#Preview {
SponsorView()
}

private extension Plan {
var column: Int {
switch self {
case .platinum:
return 1
case .gold:
return 2
case .supporter:
return 3
default:
return 3
}
}
}
28 changes: 28 additions & 0 deletions app-ios/Modules/Sources/Sponsor/SponsorViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Foundation
import Model
import shared

struct SponsorState: ViewModelState {
var planGroupedSponsors: LoadingState<[Plan: [Sponsor]]> = .initial
}

@MainActor
final class SponsorViewModel: ObservableObject {
@Published private(set) var state: SponsorState = .init()

func load() async {
state.planGroupedSponsors = .loading

do {
let sponsors = try await FakeSponsorsApiClient().sponsors()

state.planGroupedSponsors = .loaded(
[Plan: [Sponsor]](grouping: sponsors) {
$0.plan
}
)
} catch let error {
state.planGroupedSponsors = .failed(error)
}
}
}