@@ -27,6 +27,14 @@ class CustomListViewController: UIViewController {
27
27
private let alertPresenter : AlertPresenter
28
28
private var validationErrors : Set < CustomListFieldValidationError > = [ ]
29
29
30
+ private var persistedCustomList : CustomList ? {
31
+ return interactor. fetchAll ( ) . first ( where: { $0. id == subject. value. id } )
32
+ }
33
+
34
+ private var customListHasUnsavedChanges : Bool {
35
+ return persistedCustomList != subject. value. customList
36
+ }
37
+
30
38
private lazy var cellConfiguration : CustomListCellConfiguration = {
31
39
CustomListCellConfiguration ( tableView: tableView, subject: subject)
32
40
} ( )
@@ -91,9 +99,37 @@ class CustomListViewController: UIViewController {
91
99
}
92
100
93
101
private func configureNavigationItem( ) {
102
+ if let navigationController = navigationController as? InterceptibleNavigationController {
103
+ interceptNavigation ( navigationController)
104
+ }
105
+
94
106
navigationItem. rightBarButtonItem = saveBarButton
95
107
}
96
108
109
+ private func interceptNavigation( _ navigationController: InterceptibleNavigationController ) {
110
+ navigationController. shouldPopViewController = { [ weak self] viewController in
111
+ guard
112
+ let self,
113
+ viewController is Self ,
114
+ customListHasUnsavedChanges
115
+ else { return true }
116
+
117
+ self . onUnsavedChanges ( )
118
+ return false
119
+ }
120
+
121
+ navigationController. shouldPopToViewController = { [ weak self] viewController in
122
+ guard
123
+ let self,
124
+ viewController is ListCustomListViewController ,
125
+ customListHasUnsavedChanges
126
+ else { return true }
127
+
128
+ self . onUnsavedChanges ( )
129
+ return false
130
+ }
131
+ }
132
+
97
133
private func configureTableView( ) {
98
134
tableView. delegate = dataSourceConfiguration
99
135
tableView. backgroundColor = . secondaryColor
@@ -195,4 +231,51 @@ class CustomListViewController: UIViewController {
195
231
196
232
alertPresenter. showAlert ( presentation: presentation, animated: true )
197
233
}
234
+
235
+ @objc private func onUnsavedChanges( ) {
236
+ let message = NSMutableAttributedString (
237
+ markdownString: NSLocalizedString (
238
+ " CUSTOM_LISTS_UNSAVED_CHANGES_PROMPT " ,
239
+ tableName: " CustomLists " ,
240
+ value: " You have unsaved changes. " ,
241
+ comment: " "
242
+ ) ,
243
+ options: MarkdownStylingOptions ( font: . preferredFont( forTextStyle: . body) )
244
+ )
245
+
246
+ let presentation = AlertPresentation (
247
+ id: " api-custom-lists-unsaved-changes-alert " ,
248
+ icon: . alert,
249
+ attributedMessage: message,
250
+ buttons: [
251
+ AlertAction (
252
+ title: NSLocalizedString (
253
+ " CUSTOM_LISTS_DISCARD_CHANGES_BUTTON " ,
254
+ tableName: " CustomLists " ,
255
+ value: " Discard changes " ,
256
+ comment: " "
257
+ ) ,
258
+ style: . destructive,
259
+ handler: {
260
+ // Reset subject/view model to no longer having unsaved changes.
261
+ if let persistedCustomList = self . persistedCustomList {
262
+ self . subject. value. update ( with: persistedCustomList)
263
+ }
264
+ self . delegate? . customListDidSave ( self . subject. value. customList)
265
+ }
266
+ ) ,
267
+ AlertAction (
268
+ title: NSLocalizedString (
269
+ " CUSTOM_LISTS_BACK_TO_EDITING_BUTTON " ,
270
+ tableName: " CustomLists " ,
271
+ value: " Back to editing " ,
272
+ comment: " "
273
+ ) ,
274
+ style: . default
275
+ ) ,
276
+ ]
277
+ )
278
+
279
+ alertPresenter. showAlert ( presentation: presentation, animated: true )
280
+ }
198
281
}
0 commit comments