Skip to content
This repository has been archived by the owner on Dec 14, 2021. It is now read-only.

Commit

Permalink
Confirm dialog for edit screen (#1059)
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyg authored and devinreams committed Jun 28, 2019
1 parent c01a095 commit a0c7fa6
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 7 deletions.
3 changes: 3 additions & 0 deletions lockbox-ios/Common/Resources/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ extension Constant.string {
static let save = NSLocalizedString("save", value: "Save", comment: "This is the button title for the entry editor view")
static let edit = NSLocalizedString("edit", value: "Edit", comment: "The button title allowing a user to access the item editor from the entry details view")
static let name = NSLocalizedString("name", value: "Name", comment: "Row title for the `name` row of the item editor, describing what name is used when displaying the entry")
static let discardChangesTitle = NSLocalizedString("edit.discardChangesDialog.title", value: "Discard Changes?", comment: "Title of dialog shown when cancel is tapped on the edit screen")
static let discardChangesMessage = NSLocalizedString("edit.discardChangesDialog.message", value: "Your edits will not be saved.", comment: "Message in dialog shown when cancel is tapped on the edit screen")
static let discard = NSLocalizedString("edit.discardChangesDialog.discard", value: "Discard", comment: "Button to remove changes in the dialog shown when cancel is tapped on the edit screen")
static let confirmDeleteLoginDialogTitle = NSLocalizedString("delete.confirmDialogTitle", value: "Delete this login?", comment: "Title for confirmation dialog when a login is deleted")
static let confirmDeleteLoginDialogMessage = NSLocalizedString("delete.confirmDeleteLoginDialogMessage", value: "This will delete the entry from both %@ and Firefox.", comment: "Message in confirmation dialog when a login is deleted")
static let deletedStatusAlert = NSLocalizedString("delete.statusAlert", value: "%@ deleted", comment: "Text in the status alert after a login has been deleted. %@ is the hostname of the login")
Expand Down
34 changes: 31 additions & 3 deletions lockbox-ios/Presenter/ItemDetailPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import RxCocoa
import RxDataSources
import MozillaAppServices

protocol ItemDetailViewProtocol: class, StatusAlertView {
protocol ItemDetailViewProtocol: class, StatusAlertView, AlertControllerView {
func enableSwipeNavigation(enabled: Bool)
func enableLargeTitle(enabled: Bool)
var cellTapped: Observable<String?> { get }
Expand Down Expand Up @@ -45,6 +45,13 @@ class ItemDetailPresenter {
}.asObserver()
}()


lazy private var discardChangesObserver: AnyObserver<Void> = {
return Binder(self) { target, _ in
target.dispatcher.dispatch(action: ItemDetailDisplayAction.viewMode)
}.asObserver()
}()

init(view: ItemDetailViewProtocol,
dispatcher: Dispatcher = .shared,
dataStore: DataStore = DataStore.shared,
Expand Down Expand Up @@ -151,9 +158,30 @@ class ItemDetailPresenter {

private func setupNavigation() {
self.view?.leftBarButtonTapped
.withLatestFrom(self.itemDetailStore.isEditing) { _, editing -> Action in
return editing ? ItemDetailDisplayAction.viewMode : MainRouteAction.list
.withLatestFrom(self.itemDetailStore.isEditing) { _, editing -> Action? in
if editing {
self.view?.displayAlertController(
buttons: [
AlertActionButtonConfiguration(
title: Constant.string.cancel,
tapObserver: nil,
style: .cancel
),
AlertActionButtonConfiguration(
title: Constant.string.discard,
tapObserver: self.discardChangesObserver,
style: .destructive)
],
title: Constant.string.discardChangesTitle,
message: Constant.string.discardChangesMessage,
style: .alert,
barButtonItem: nil)
} else {
return MainRouteAction.list
}
return nil
}
.filterNil()
.subscribe(onNext: { self.dispatcher.dispatch(action: $0) })
.disposed(by: self.disposeBag)

Expand Down
32 changes: 28 additions & 4 deletions lockbox-iosTests/ItemDetailPresenterSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class ItemDetailPresenterSpec: QuickSpec {
var tempAlertTimeout: TimeInterval?
var enableLargeTitleValue: Bool?
var enableSwipeValue: Bool?
var alertControllerTitle: String?
var alertControllerMessage: String?
var alertControllerButtons: [AlertActionButtonConfiguration]?

var itemDetailObserver: ItemDetailSectionModelObserver {
return { observable -> Disposable in
Expand Down Expand Up @@ -79,6 +82,16 @@ class ItemDetailPresenterSpec: QuickSpec {
self.tempAlertMessage = message
self.tempAlertTimeout = timeout
}

func displayAlertController(buttons: [AlertActionButtonConfiguration],
title: String?,
message: String?,
style: UIAlertController.Style,
barButtonItem: UIBarButtonItem?) {
self.alertControllerButtons = buttons
self.alertControllerTitle = title
self.alertControllerMessage = message
}
}

class FakeDispatcher: Dispatcher {
Expand Down Expand Up @@ -601,10 +614,21 @@ class ItemDetailPresenterSpec: QuickSpec {
self.view.leftButtonTappedStub.onNext(())
}

it("dispatches the view mode action") {
expect(self.dispatcher.dispatchActionArgument).notTo(beEmpty())
expect(self.dispatcher.dispatchActionArgument.popLast() as! ItemDetailDisplayAction)
.to(equal(ItemDetailDisplayAction.viewMode))
it("displays the alert controller") {
expect(self.view.alertControllerButtons).notTo(beNil())
expect(self.view.alertControllerTitle).to(equal(Constant.string.discardChangesTitle))
expect(self.view.alertControllerMessage).to(equal(Constant.string.discardChangesMessage))
}

describe("discardChangesObserver") {
beforeEach {
self.view.alertControllerButtons![1].tapObserver?.onNext(())
}

it("sends the viewMode action") {
let displayAction = self.dispatcher.dispatchActionArgument.popLast() as! ItemDetailDisplayAction
expect(displayAction).to(equal(.viewMode))
}
}
}

Expand Down

0 comments on commit a0c7fa6

Please sign in to comment.