Skip to content

Commit ea1bde8

Browse files
committed
Design frutttie + list + cart screens
Design list + cart screens
1 parent 2e349c8 commit ea1bde8

File tree

3 files changed

+138
-61
lines changed

3 files changed

+138
-61
lines changed

Fruitties/iosApp/iosApp/ui/CartView.swift

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import Foundation
1818
import SwiftUI
1919
import shared
2020

21-
struct CartView : View {
21+
struct CartView: View {
2222
/// Injects the `IOSViewModelStoreOwner` from the environment, which manages the lifecycle of `ViewModel` instances.
2323
@EnvironmentObject var viewModelStoreOwner: IOSViewModelStoreOwner
2424

@@ -63,32 +63,36 @@ struct CartDetailsView: View {
6363
/// This allows SwiftUI to react to changes in the cart's UI state.
6464
/// For more details, refer to: https://skie.touchlab.co/features/flows-in-swiftui
6565
Observing(self.cartViewModel.cartUiState) { cartUIState in
66-
ScrollView {
67-
LazyVStack {
68-
ForEach(cartUIState.cartDetails, id: \.fruittie.id) { item in
69-
HStack {
70-
Text("\(item.count)x \(item.fruittie.name)")
71-
.frame(maxWidth: .infinity, alignment: .leading)
72-
Spacer()
73-
Button(action: {
74-
self.cartViewModel.decreaseCountClick(cartItem: item)
75-
}) {
76-
Image(systemName: "minus.circle.fill")
77-
.foregroundColor(.red)
78-
}
79-
80-
Button(action: {
81-
self.cartViewModel.increaseCountClick(cartItem: item)
82-
}) {
83-
Image(systemName: "plus.circle.fill")
84-
.foregroundColor(.green)
85-
}
66+
List {
67+
ForEach(cartUIState.cartDetails, id: \.fruittie.id) { item in
68+
HStack {
69+
Text("\(item.count)x \(item.fruittie.name)")
70+
.frame(maxWidth: .infinity, alignment: .leading)
71+
Spacer()
72+
Button(action: {
73+
self.cartViewModel.decreaseCountClick(
74+
cartItem: item
75+
)
76+
}) {
77+
Image(systemName: "minus.circle.fill")
78+
.foregroundColor(.red)
8679
}
87-
.padding()
80+
.buttonStyle(.plain)
81+
82+
Button(action: {
83+
self.cartViewModel.increaseCountClick(
84+
cartItem: item
85+
)
86+
}) {
87+
Image(systemName: "plus.circle.fill")
88+
.foregroundColor(.green)
89+
}
90+
.buttonStyle(.plain)
8891
}
8992
}
90-
.animation(.default, value: cartUIState.cartDetails)
9193
}
94+
.listStyle(.inset)
95+
.animation(.default, value: cartUIState.cartDetails)
9296
}
9397
}
9498
}

Fruitties/iosApp/iosApp/ui/ContentView.swift

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,27 @@ struct ContentView: View {
3434
extras: creationExtras(appContainer: appContainer.value)
3535
)
3636
NavigationStack {
37-
VStack {
38-
Observing(mainViewModel.homeUiState) { homeUIState in
39-
ScrollView {
40-
LazyVStack {
41-
ForEach(homeUIState.fruitties, id: \.self) {
42-
value in
43-
FruittieView(
44-
fruittie: value,
45-
addToCart: { fruittie in
46-
Task {
47-
mainViewModel.addItemToCart(
48-
fruittie: fruittie
49-
)
50-
}
51-
}
52-
)
37+
Observing(mainViewModel.homeUiState) { homeUIState in
38+
List {
39+
ForEach(homeUIState.fruitties, id: \.self) {
40+
value in
41+
HStack {
42+
NavigationLink {
43+
ViewModelStoreOwnerProvider {
44+
FruittieScreen(fruittie: value)
45+
}
46+
} label: {
47+
FruittieView(fruittie: value)
5348
}
49+
Spacer()
50+
Button(
51+
"Add",
52+
action: {
53+
mainViewModel.addItemToCart(
54+
fruittie: value
55+
)
56+
}
57+
).buttonStyle(.bordered)
5458
}
5559
}
5660
}
@@ -76,28 +80,13 @@ struct ContentView: View {
7680

7781
struct FruittieView: View {
7882
var fruittie: Fruittie
79-
var addToCart: (Fruittie) -> Void
8083
var body: some View {
81-
HStack(alignment: .firstTextBaseline) {
82-
ZStack {
83-
RoundedRectangle(cornerRadius: 15).fill(
84-
Color(red: 0.8, green: 0.8, blue: 1.0)
85-
)
86-
VStack {
87-
Text("\(fruittie.name)")
88-
.fontWeight(.bold)
89-
.frame(maxWidth: .infinity, alignment: .leading)
90-
Text("\(fruittie.fullName)")
91-
.frame(maxWidth: .infinity, alignment: .leading)
92-
}.padding()
93-
Spacer()
94-
Button(
95-
action: { addToCart(fruittie) },
96-
label: {
97-
Text("Add")
98-
}
99-
).padding().frame(maxWidth: .infinity, alignment: .trailing)
100-
}.padding([.leading, .trailing])
101-
}
84+
VStack {
85+
Text("\(fruittie.name)")
86+
.fontWeight(.bold)
87+
.frame(maxWidth: .infinity, alignment: .leading)
88+
Text("\(fruittie.fullName)")
89+
.frame(maxWidth: .infinity, alignment: .leading)
90+
}.padding(.vertical, 5)
10291
}
10392
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright 2024 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import Foundation
18+
import SwiftUI
19+
import shared
20+
21+
struct FruittieScreen: View {
22+
@EnvironmentObject var viewModelStoreOwner: IOSViewModelStoreOwner
23+
@EnvironmentObject var appContainer: ObservableValueWrapper<AppContainer>
24+
let fruittie: Fruittie
25+
26+
var body: some View {
27+
let fruittieViewModel: FruittieViewModel =
28+
viewModelStoreOwner.viewModel(
29+
factory: FruittieViewModel.companion.Factory,
30+
extras: creationExtras(
31+
appContainer: appContainer.value,
32+
additional: { extras in
33+
extras.set(
34+
key: FruittieViewModel.companion.FRUITTIE_ID_KEY,
35+
t: fruittie.id
36+
)
37+
}
38+
)
39+
)
40+
41+
Observing(fruittieViewModel.state) { uiState in
42+
switch onEnum(of: uiState) {
43+
case .loading:
44+
VStack {
45+
ProgressView()
46+
Text("Loading fruittie details...")
47+
}
48+
.navigationTitle(fruittie.name)
49+
50+
case .content(let content):
51+
VStack {
52+
Text(content.fruittie.fullName)
53+
.font(.title2)
54+
.padding(.bottom, 5)
55+
Text("\(content.fruittie.calories) calories")
56+
.font(.title3)
57+
58+
Spacer()
59+
Button(action: {
60+
fruittieViewModel.addToCart(fruittie: content.fruittie)
61+
}) {
62+
HStack {
63+
Image(systemName: "cart.fill")
64+
Text("Add to cart")
65+
}
66+
.padding()
67+
.frame(maxWidth: .infinity)
68+
.background(Color.blue)
69+
.foregroundColor(.white)
70+
.cornerRadius(10)
71+
}
72+
.padding(.horizontal)
73+
}
74+
.navigationTitle(content.fruittie.name)
75+
.toolbar {
76+
ToolbarItem(placement: .navigationBarTrailing) {
77+
Text("In cart: \(content.inCart)")
78+
}
79+
}
80+
}
81+
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)