Skip to content

Commit

Permalink
Improve tx list refresh control UX. Readability improvements continued.
Browse files Browse the repository at this point in the history
  • Loading branch information
kukabi committed Nov 24, 2020
1 parent 4d0e477 commit cab77e8
Show file tree
Hide file tree
Showing 24 changed files with 737 additions and 337 deletions.
2 changes: 2 additions & 0 deletions MobileWallet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@
619197D2BB78CBBC06B0F87E /* UTXO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619190C6EBD050DC647D1D7B /* UTXO.swift */; };
619198F3E20DFABEB23F63FE /* UTXO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619190C6EBD050DC647D1D7B /* UTXO.swift */; };
83EF1C05BE3D003F97626E60 /* Pods_MobileWalletTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9926F406D47AD1335698D7E1 /* Pods_MobileWalletTests.framework */; };
A01BBED62562B9DB007F551F /* Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01F54A7255EAB7E00F49AFA /* Localization.swift */; };
A01F54A8255EAB7E00F49AFA /* Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01F54A7255EAB7E00F49AFA /* Localization.swift */; };
A01F54A9255EAB7E00F49AFA /* Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01F54A7255EAB7E00F49AFA /* Localization.swift */; };
A01F54AA255EAB7E00F49AFA /* Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = A01F54A7255EAB7E00F49AFA /* Localization.swift */; };
Expand Down Expand Up @@ -2178,6 +2179,7 @@
00C520B92469720F0077BF7F /* TariEventBus.swift in Sources */,
00C520C02469720F0077BF7F /* ConnectionMonitor.swift in Sources */,
00C520A2246965260077BF7F /* NotificationService.swift in Sources */,
A01BBED62562B9DB007F551F /* Localization.swift in Sources */,
00C520C5246972140077BF7F /* Wallet.swift in Sources */,
00C520B2246971FC0077BF7F /* TariLib.swift in Sources */,
00C520B32469720A0077BF7F /* OnionConnector.swift in Sources */,
Expand Down
12 changes: 3 additions & 9 deletions MobileWallet/Common/BackgroundTasks/ReminderNotifications.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,22 @@ class ReminderNotifications {
static private let dateUserDefaultsKey = "should-schedule-reminders-updated-at"

static let titleString = String(
format: NSLocalizedString(
"scheduled_reminder.title.with_param",
comment: "Local reminder notifications"
),
format: localized("scheduled_reminder.title.with_param"),
TariSettings.shared.network.currencyDisplayTicker
)

static let recipientReminderNotifications: [ScheduledReminder] = [
ScheduledReminder(
identifier: "scheduled-reminders-recipient-1",
title: ReminderNotifications.titleString,
body: NSLocalizedString("scheduled_reminder.body.short", comment: "Local reminder notifications"),
body: localized("scheduled_reminder.body.short"),
deliverAfter: TariSettings.shared.environment == .production ? 60 * 60 * 24 : 60 * 60 * 2 //24h for prod and 2h for debug/testflight
),
ScheduledReminder(
identifier: "scheduled-reminders-recipient-2",
title: ReminderNotifications.titleString,
body: String(
format: NSLocalizedString(
"scheduled_reminder.body.long.with_param",
comment: "Local reminder notifications"
),
format: localized("scheduled_reminder.body.long.with_param"),
TariSettings.shared.network.currencyDisplayTicker
),
deliverAfter: TariSettings.shared.environment == .production ? 60 * 60 * 48 : 60 * 60 * 4 //48h for prod and 4h for debug/testflight
Expand Down
10 changes: 2 additions & 8 deletions MobileWallet/Common/DeepLinkManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,7 @@ class ShortcutParser {
func registerShortcuts() {
let showQRShortcutItem = UIApplicationShortcutItem(
type: ShortcutKey.showQR.rawValue,
localizedTitle: NSLocalizedString(
"shortcut.show_my_qr",
comment: "Home screen shortcut"
),
localizedTitle: localized("shortcut.show_my_qr"),
localizedSubtitle: nil,
icon: UIApplicationShortcutIcon(templateImageName: "qr"),
userInfo: nil
Expand All @@ -133,10 +130,7 @@ class ShortcutParser {
let sendShortcutItem = UIApplicationShortcutItem(
type: ShortcutKey.send.rawValue,
localizedTitle: String(
format: NSLocalizedString(
"common.send.with_param",
comment: "Common"
),
format: localized("common.send.with_param"),
TariSettings.shared.network.currencyDisplayTicker
),
localizedSubtitle: nil,
Expand Down
8 changes: 4 additions & 4 deletions MobileWallet/Common/Extensions/Date.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,21 @@ extension Date {
guard let minutes = components.minute else { return nil }

guard minutes != 0 else {
return NSLocalizedString("tx_list.now", comment: "Transaction list section heading")
return localized("tx_list.now")
}

return String(
format: NSLocalizedString("tx_list.relative_minutes", comment: "Transaction list section heading"),
format: localized("tx_list.relative_minutes"),
"\(minutes)"
)
}

return String(
format: NSLocalizedString("tx_list.relative_hours", comment: "Transaction list section heading"),
format: localized("tx_list.relative_hours"),
"\(hours)"
)
} else if Calendar.current.isDateInYesterday(self) {
return NSLocalizedString("tx_list.yesterday", comment: "Transaction list section heading")
return localized("tx_list.yesterday")
} else {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "MMM d, yyyy", options: 0, locale: .current)
Expand Down
20 changes: 10 additions & 10 deletions MobileWallet/Common/Extensions/LAContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ extension LAContext {

var rawValue: String {
switch self {
case .logIn: return NSLocalizedString("authentication.reason.login", comment: "Authentication")
case .userVerification: return NSLocalizedString("authentication.reason.user_verification", comment: "Authentication")
case .logIn: return localized("authentication.reason.login")
case .userVerification: return localized("authentication.reason.user_verification")
}
}
}
Expand Down Expand Up @@ -96,23 +96,23 @@ extension LAContext {
onSuccess()
} else {
if !showFailedDialog { return }
let localizedReason = error?.localizedDescription ?? NSLocalizedString("authentication.fail.description", comment: "Authentication")
let localizedReason = error?.localizedDescription ?? localized("authentication.fail.description")
TariLogger.error("Biometrics auth failed", error: error)
self.authenticationFailedAlertOptions(reason: localizedReason, onSuccess: onSuccess)
}
}
}
case .none:
let alert = UIAlertController(title: NSLocalizedString("authentication.error.title", comment: "Authentication") ,
message: NSLocalizedString("authentication.error.description", comment: "Authentication"),
let alert = UIAlertController(title: localized("authentication.error.title"),
message: localized("authentication.error.description"),
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("authentication.try_again", comment: "Authentication"),
alert.addAction(UIAlertAction(title: localized("authentication.try_again"),
style: .cancel,
handler: { [weak self] _ in
self?.authenticateUser(onSuccess: onSuccess)
}))

alert.addAction(UIAlertAction(title: NSLocalizedString("authentication.proceed", comment: "Authentication"), style: .default, handler: { _ in
alert.addAction(UIAlertAction(title: localized("authentication.proceed"), style: .default, handler: { _ in
onSuccess()
}))

Expand All @@ -123,13 +123,13 @@ extension LAContext {
}

private func authenticationFailedAlertOptions(reason: String, onSuccess: @escaping () -> Void) {
let alert = UIAlertController(title: NSLocalizedString("authentication.fail.title", comment: "Authentication"), message: reason, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("authentication.try_again", comment: "Authentication"), style: .default, handler: { [weak self] _ in
let alert = UIAlertController(title: localized("authentication.fail.title"), message: reason, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: localized("authentication.try_again"), style: .default, handler: { [weak self] _ in
guard let self = self else { return }
self.authenticateUser(onSuccess: onSuccess)
}))

alert.addAction(UIAlertAction(title: NSLocalizedString("authentication.action.open_settings", comment: "Authentication"), style: .default, handler: { [weak self] _ in
alert.addAction(UIAlertAction(title: localized("authentication.action.open_settings"), style: .default, handler: { [weak self] _ in
guard let self = self else { return }
if self.openAppSettings() {
self.authenticationFailedAlertOptions(reason: reason, onSuccess: onSuccess)
Expand Down
2 changes: 1 addition & 1 deletion MobileWallet/Common/UserFeedback/FeedbackView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class FeedbackView: UIView {
closeButton.setVariation(.secondary)
closeButton.translatesAutoresizingMaskIntoConstraints = false
addSubview(closeButton)
closeButton.setTitle(NSLocalizedString("feedback_view.close", comment: "Feedback view"), for: .normal)
closeButton.setTitle(localized("feedback_view.close"), for: .normal)
closeButton.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
closeButton.addTarget(self, action: #selector(onCloseButtonPressed), for: .touchUpInside)
}
Expand Down
112 changes: 81 additions & 31 deletions MobileWallet/Common/UserFeedback/UserFeedback.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,14 @@ class UserFeedback {

private var defaultAttributes: EKAttributes {
var attributes = EKAttributes.bottomFloat
attributes.screenBackground = .color(color: EKColor(Theme.shared.colors.feedbackPopupBackground!))
attributes.screenBackground = .color(
color: EKColor(Theme.shared.colors.feedbackPopupBackground!)
)
attributes.entryBackground = .clear
attributes.positionConstraints.size = .init(width: .offset(value: SIDE_OFFSET), height: .intrinsic)
attributes.positionConstraints.size = .init(
width: .offset(value: SIDE_OFFSET),
height: .intrinsic
)
attributes.positionConstraints.verticalOffset = VERTICAL_OFFSET
attributes.screenInteraction = .dismiss
attributes.entryInteraction = .forward
Expand All @@ -67,7 +72,10 @@ class UserFeedback {
)
}

func error(title: String, description: String, error: Error? = nil, onClose: (() -> Void)? = nil) {
func error(title: String,
description: String,
error: Error? = nil,
onClose: (() -> Void)? = nil) {
let errorFeedbackView = FeedbackView()

var descriptionText = description
Expand All @@ -76,12 +84,19 @@ class UserFeedback {
}

if onClose == nil {
errorFeedbackView.setupError(title: title, description: descriptionText)
errorFeedbackView.setupError(
title: title,
description: descriptionText
)
} else {
errorFeedbackView.setupError(title: title, description: descriptionText, onClose: {
SwiftEntryKit.dismiss()
onClose?()
})
errorFeedbackView.setupError(
title: title,
description: descriptionText,
onClose: {
SwiftEntryKit.dismiss()
onClose?()
}
)
}

var attributes = defaultAttributes
Expand All @@ -104,7 +119,13 @@ class UserFeedback {
attributes.displayDuration = .infinity
attributes.hapticFeedbackType = .none
attributes.screenInteraction = .dismiss
attributes.entranceAnimation = .init(translate: .init(duration: 0.25, anchorPosition: .bottom, spring: .init(damping: 1, initialVelocity: 0)))
attributes.entranceAnimation = .init(
translate: .init(
duration: 0.25,
anchorPosition: .bottom,
spring: .init(damping: 1, initialVelocity: 0)
)
)

SwiftEntryKit.display(entry: infoFeedbackView, using: attributes)
closeKeyboard()
Expand All @@ -116,9 +137,18 @@ class UserFeedback {
successFeedbackView.setupSuccess(title: title)
var attributes = EKAttributes.topToast

attributes.entryBackground = .color(color: EKColor(Theme.shared.colors.successFeedbackPopupBackground!))
attributes.entryBackground = .color(
color: EKColor(Theme.shared.colors.successFeedbackPopupBackground!)
)
attributes.screenBackground = .clear
attributes.shadow = .active(with: .init(color: EKColor(Theme.shared.colors.feedbackPopupBackground!), opacity: 0.35, radius: 10, offset: .zero))
attributes.shadow = .active(
with: .init(
color: EKColor(Theme.shared.colors.feedbackPopupBackground!),
opacity: 0.35,
radius: 10,
offset: .zero
)
)
attributes.displayDuration = 2
attributes.hapticFeedbackType = .success
attributes.screenInteraction = .forward
Expand Down Expand Up @@ -165,7 +195,11 @@ class UserFeedback {
TariLogger.verbose("User call to action: title=\(title) description=\(description)")
}

func acceptUserInput(title: String, cancelTitle: String, actionTitle: String, inputs: [UserFeedbackFormInput], onSubmit: @escaping ([String: String]) -> Void) {
func acceptUserInput(title: String,
cancelTitle: String,
actionTitle: String,
inputs: [UserFeedbackFormInput],
onSubmit: @escaping ([String: String]) -> Void) {
let successFeedbackView = FeedbackView()
successFeedbackView.setupForm(
title: title,
Expand All @@ -179,7 +213,14 @@ class UserFeedback {
var attributes = EKAttributes.float

attributes.screenBackground = .visualEffect(style: .dark)
attributes.shadow = .active(with: .init(color: EKColor(Theme.shared.colors.feedbackPopupBackground!), opacity: 0.35, radius: 10, offset: .zero))
attributes.shadow = .active(
with: .init(
color: EKColor(Theme.shared.colors.feedbackPopupBackground!),
opacity: 0.35,
radius: 10,
offset: .zero
)
)
attributes.displayDuration = .infinity
attributes.screenInteraction = .absorbTouches
attributes.entryInteraction = .absorbTouches
Expand All @@ -199,22 +240,16 @@ class UserFeedback {
image: Theme.shared.images.storeModal!,
imageTop: imageTop,
title: String(
format: NSLocalizedString(
"store_modal.title.with_param",
comment: "Store modal"
),
format: localized("store_modal.title.with_param"),
TariSettings.shared.network.currencyDisplayTicker
),
boldedTitle: NSLocalizedString("store_modal.bold_title", comment: "Store modal"),
boldedTitle: localized("store_modal.bold_title"),
description: String(
format: NSLocalizedString(
"store_modal.description",
comment: "Store modal"
),
format: localized("store_modal.description"),
TariSettings.shared.network.currencyDisplayTicker
),
cancelTitle: NSLocalizedString("store_modal.cancel", comment: "Store modal"),
actionTitle: NSLocalizedString("store_modal.action", comment: "Store modal"),
cancelTitle: localized("store_modal.cancel"),
actionTitle: localized("store_modal.action"),
actionIcon: Theme.shared.images.storeIcon!,
onClose: {
SwiftEntryKit.dismiss()
Expand All @@ -229,10 +264,19 @@ class UserFeedback {

ctaFeedbackView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(ctaFeedbackView)
ctaFeedbackView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: imageTop).isActive = true
ctaFeedbackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
ctaFeedbackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
ctaFeedbackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
ctaFeedbackView.topAnchor.constraint(
equalTo: containerView.topAnchor,
constant: imageTop
).isActive = true
ctaFeedbackView.bottomAnchor.constraint(
equalTo: containerView.bottomAnchor
).isActive = true
ctaFeedbackView.leadingAnchor.constraint(
equalTo: containerView.leadingAnchor
).isActive = true
ctaFeedbackView.trailingAnchor.constraint(
equalTo: containerView.trailingAnchor
).isActive = true

var attributes = defaultAttributes
attributes.displayDuration = .infinity
Expand Down Expand Up @@ -263,8 +307,13 @@ class UserFeedback {
attributes.displayDuration = .infinity
attributes.hapticFeedbackType = .none
attributes.screenInteraction = .dismiss
attributes.entranceAnimation = .init(translate: .init(duration: 0.25, anchorPosition: .bottom, spring: .init(damping: 1, initialVelocity: 0)))

attributes.entranceAnimation = .init(
translate: .init(
duration: 0.25,
anchorPosition: .bottom,
spring: .init(damping: 1, initialVelocity: 0)
)
)
SwiftEntryKit.display(entry: infoFeedbackView, using: attributes)
closeKeyboard()
}
Expand All @@ -273,7 +322,8 @@ class UserFeedback {
guard let topController = UIApplication.shared.topController() else { return }
let webBrowserViewController = WebBrowserViewController()
webBrowserViewController.url = url
webBrowserViewController.modalPresentationStyle = UIDevice.current.userInterfaceIdiom == .pad ? .automatic :.popover
webBrowserViewController.modalPresentationStyle =
UIDevice.current.userInterfaceIdiom == .pad ? .automatic :.popover
topController.present(webBrowserViewController, animated: true)
}
}
Loading

0 comments on commit cab77e8

Please sign in to comment.