-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathReportProjectFormViewModel.swift
115 lines (95 loc) · 3.21 KB
/
ReportProjectFormViewModel.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import Combine
import Foundation
import KsApi
import ReactiveSwift
public protocol ReportProjectFormViewModelInputs {
func viewDidLoad()
}
public protocol ReportProjectFormViewModelOutputs {}
public protocol ReportProjectFormViewModelType {
var inputs: ReportProjectFormViewModelInputs { get }
var outputs: ReportProjectFormViewModelOutputs { get }
}
public final class ReportProjectFormViewModel: ReportProjectFormViewModelType,
ReportProjectFormViewModelInputs, ReportProjectFormViewModelOutputs, ObservableObject {
@Published public var retrievedEmail: String? = nil
@Published public var saveButtonEnabled: Bool = false
@Published public var saveButtonLoading: Bool = false
@Published public var detailsText: String = ""
@Published public var bannerMessage: MessageBannerViewViewModel? = nil
@Published public var submitSuccess: Bool = false
private let viewDidLoadSubject = PassthroughSubject<Bool, Never>()
private let saveTriggeredSubject = PassthroughSubject<(), Never>()
private var cancellables = Set<AnyCancellable>()
public var projectID: String?
public var projectFlaggingKind: GraphAPI.NonDeprecatedFlaggingKind?
public init() {
/// Only enable the save button if the user has entered detail text
self.$detailsText
.map { !$0.isEmpty }
.assign(to: &self.$saveButtonEnabled)
/// Load the current user's e-mail on page load
self.viewDidLoadSubject
.flatMap { _ in
AppEnvironment.current
.apiService
.fetchGraphUserEmailCombine()
}
.compactMap { envelope in
envelope.me.email
}
.catch { _ in
CurrentValueSubject("")
}
.assign(to: &self.$retrievedEmail)
/// Submits report on saveTriggered
self.saveTriggeredSubject
.compactMap { [weak self] _ in
self?.createFlaggingInput()
.handleFailureAndAllowRetry { _ in
self?.bannerMessage = MessageBannerViewViewModel((
type: .error,
message: Strings.Something_went_wrong_please_try_again()
))
self?.saveButtonEnabled = true
self?.saveButtonLoading = false
}
}
.flatMap { $0 }
.sink(receiveValue: { [weak self] _ in
// Submitted successfully
self?.saveButtonEnabled = false
self?.saveButtonLoading = false
self?.bannerMessage = MessageBannerViewViewModel((
type: .success,
message: Strings.Your_message_has_been_sent()
))
self?.submitSuccess = true
})
.store(in: &self.cancellables)
}
private func createFlaggingInput() -> AnyPublisher<EmptyResponseEnvelope, ErrorEnvelope> {
let input = CreateFlaggingInput(
contentId: projectID!,
kind: projectFlaggingKind!,
details: detailsText,
clientMutationId: nil
)
return AppEnvironment
.current
.apiService
.createFlaggingInputCombine(input: input)
}
public func viewDidLoad() {
self.viewDidLoadSubject.send(true)
}
public func didTapSave() {
self.saveTriggeredSubject.send(())
}
public var inputs: ReportProjectFormViewModelInputs {
return self
}
public var outputs: ReportProjectFormViewModelOutputs {
return self
}
}