/
PokemonListView.swift
68 lines (62 loc) · 1.99 KB
/
PokemonListView.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import PokemonData
import SwiftUI
public struct PokemonListView: View {
// Environment object to share the same instance with all the sub views.
@EnvironmentObject private var repository: PokemonRepository
// State property to react to the changes.
@State private var model: Model = .init()
public init() {}
public var body: some View {
NavigationView {
List {
ForEach($model.pokemons) { pokemon in
pokemonRowView(pokemon)
}
loadButton
wipeButton
}
.navigationTitle("Pokemon List")
// We subscribe to the repository's publisher.
.onReceive(repository.pokemonsPublisher) { newState in
// And every time we receive a value we update the state.
model.updateStates(with: newState)
}
.alert(isPresented: $model.isDisplayingDeletionErrorToast) {
Alert(title: Text("Error removing Pokemon"))
}
}
}
}
private extension PokemonListView {
func pokemonRowView(_ pokemon: Binding<Pokemon>) -> some View {
NavigationLink(destination: PokemonDetailView(pokemon: pokemon)) {
VStack(alignment: .leading) {
Text(pokemon.wrappedValue.name)
.bold()
Text("Type: \(pokemon.wrappedValue.type.rawValue)")
Text("Id: \(pokemon.id)")
}
}
}
@ViewBuilder
var loadButton: some View {
if !model.hasPokemons {
HStack {
Button("Load Pokemons") {
Task {
await repository.loadAllPokemons()
}
}
Spacer()
if model.isLoading {
ProgressView()
}
}
}
}
var wipeButton: some View {
Button("Wipe Data") {
repository.wipe()
}
}
}