-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
ProjectActivityCommentCellViewModel.swift
156 lines (122 loc) · 5.74 KB
/
ProjectActivityCommentCellViewModel.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import Foundation
import KsApi
import Prelude
import ReactiveExtensions
import ReactiveSwift
public protocol ProjectActivityCommentCellViewModelInputs {
/// Call when the backing button is pressed.
func backingButtonPressed()
/// Call to set the activity and project.
func configureWith(activity: Activity, project: Project)
/// Call when the comment button is pressed.
func replyButtonPressed()
}
public protocol ProjectActivityCommentCellViewModelOutputs {
/// Emits the author's image URL.
var authorImageURL: Signal<URL?, Never> { get }
/// Emits the body of the comment.
var body: Signal<String, Never> { get }
/// Emits the cell's accessibility label.
var cellAccessibilityLabel: Signal<String, Never> { get }
/// Emits the cell's accessibility value.
var cellAccessibilityValue: Signal<String, Never> { get }
/// Go to the backing info screen.
var notifyDelegateGoToBacking: Signal<(Project, User), Never> { get }
/// Go to the comment reply dialog for the project/update comment.
var notifyDelegateGoToSendReply: Signal<(Project, Update?, ActivityComment), Never> { get }
/// Emits a Bool whether the footer pledge and reply stack view is hidden or not.
var pledgeFooterIsHidden: Signal<Bool, Never> { get }
/// Emits the activity's title.
var title: Signal<String, Never> { get }
}
public protocol ProjectActivityCommentCellViewModelType {
var inputs: ProjectActivityCommentCellViewModelInputs { get }
var outputs: ProjectActivityCommentCellViewModelOutputs { get }
}
public final class ProjectActivityCommentCellViewModel: ProjectActivityCommentCellViewModelType,
ProjectActivityCommentCellViewModelInputs, ProjectActivityCommentCellViewModelOutputs {
public init() {
let activityAndProject = self.activityAndProjectProperty.signal.skipNil()
let activity = activityAndProject.map(first)
self.authorImageURL = activity.map { ($0.user?.avatar.medium).flatMap(URL.init) }
self.body = activity.map { $0.comment?.body ?? "" }
self.notifyDelegateGoToBacking = activityAndProject
.takeWhen(self.backingButtonPressedProperty.signal)
.map { activity, project -> (Project, User)? in
guard let user = activity.user else { return nil }
return (project, user)
}
.skipNil()
let projectComment = activityAndProject
.filter { activity, _ in activity.category == .commentProject }
.flatMap { activity, project -> SignalProducer<(Project, Update?, ActivityComment), Never> in
guard let comment = activity.comment else { return .empty }
return .init(value: (project, nil, comment))
}
let updateComment = activityAndProject
.filter { activity, _ in activity.category == .commentPost }
.flatMap { activity, project -> SignalProducer<(Project, Update?, ActivityComment), Never> in
guard let update = activity.update, let comment = activity.comment else { return .empty }
return .init(value: (project, update, comment))
}
self.notifyDelegateGoToSendReply = Signal.merge(projectComment, updateComment)
.takeWhen(self.replyButtonPressedProperty.signal)
let projectTitle = activity
.filter { $0.category == .commentProject }
.map(commentOnProjectTitle(activity:))
let updateTitle = activity
.filter { $0.category == .commentPost }
.map(commentOnUpdateTitle(activity:))
self.title = Signal.merge(projectTitle, updateTitle)
self.cellAccessibilityLabel = self.title.map { title in title.htmlStripped() ?? "" }
self.cellAccessibilityValue = self.body
self.pledgeFooterIsHidden = activityAndProject
.map { activity, project in
activity.user == AppEnvironment.current.currentUser
&& project.creator == AppEnvironment.current.currentUser
}
}
fileprivate let backingButtonPressedProperty = MutableProperty(())
public func backingButtonPressed() {
self.backingButtonPressedProperty.value = ()
}
fileprivate let replyButtonPressedProperty = MutableProperty(())
public func replyButtonPressed() {
self.replyButtonPressedProperty.value = ()
}
fileprivate let activityAndProjectProperty = MutableProperty<(Activity, Project)?>(nil)
public func configureWith(activity: Activity, project: Project) {
self.activityAndProjectProperty.value = (activity, project)
}
public let authorImageURL: Signal<URL?, Never>
public let body: Signal<String, Never>
public let cellAccessibilityLabel: Signal<String, Never>
public let cellAccessibilityValue: Signal<String, Never>
public let notifyDelegateGoToBacking: Signal<(Project, User), Never>
public let notifyDelegateGoToSendReply: Signal<(Project, Update?, ActivityComment), Never>
public let pledgeFooterIsHidden: Signal<Bool, Never>
public let title: Signal<String, Never>
public var inputs: ProjectActivityCommentCellViewModelInputs { return self }
public var outputs: ProjectActivityCommentCellViewModelOutputs { return self }
}
private func commentOnProjectTitle(activity: Activity) -> String {
guard let user = activity.user else { return "" }
return AppEnvironment.current.currentUser == user ?
Strings.dashboard_activity_you_commented_on_your_project() :
Strings.dashboard_activity_user_name_commented_on_your_project(user_name: user.name)
}
private func commentOnUpdateTitle(activity: Activity) -> String {
guard let update = activity.update, let user = activity.user else { return "" }
if AppEnvironment.current.currentUser == user {
return Strings.dashboard_activity_you_commented_on_update_number(
space: "\u{00a0}",
update_number: String(update.sequence)
)
} else {
return Strings.dashboard_activity_user_name_commented_on_update_number(
user_name: user.name,
space: "\u{00a0}",
update_number: String(update.sequence)
)
}
}