- We now lerp the badge sprite to the closest design spec available - Also enables badges on internal builds
307 lines
12 KiB
Swift
307 lines
12 KiB
Swift
//
|
|
// Copyright (c) 2021 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
@objc
|
|
public extension HomeViewController {
|
|
|
|
func reloadTableDataAndResetCellContentCache() {
|
|
AssertIsOnMainThread()
|
|
|
|
cellContentCache.clear()
|
|
conversationCellHeightCache = nil
|
|
reloadTableData()
|
|
}
|
|
|
|
func reloadTableData() {
|
|
AssertIsOnMainThread()
|
|
|
|
tableView.reloadData()
|
|
}
|
|
|
|
func updateCellVisibility() {
|
|
AssertIsOnMainThread()
|
|
|
|
for cell in tableView.visibleCells {
|
|
guard let cell = cell as? HomeViewCell else {
|
|
continue
|
|
}
|
|
updateCellVisibility(cell: cell, isCellVisible: true)
|
|
}
|
|
}
|
|
|
|
func updateCellVisibility(cell: HomeViewCell, isCellVisible: Bool) {
|
|
AssertIsOnMainThread()
|
|
|
|
cell.isCellVisible = self.isViewVisible && isCellVisible
|
|
}
|
|
|
|
func ensureCellAnimations() {
|
|
AssertIsOnMainThread()
|
|
|
|
for cell in tableView.visibleCells {
|
|
guard let cell = cell as? HomeViewCell else {
|
|
continue
|
|
}
|
|
cell.ensureCellAnimations()
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
func configureUnreadPaymentsBannerSingle(_ paymentsReminderView: UIView,
|
|
paymentModel: TSPaymentModel,
|
|
transaction: SDSAnyReadTransaction) {
|
|
|
|
guard paymentModel.isIncoming,
|
|
!paymentModel.isUnidentified,
|
|
let address = paymentModel.address,
|
|
let paymentAmount = paymentModel.paymentAmount,
|
|
paymentAmount.isValid else {
|
|
configureUnreadPaymentsBannerMultiple(paymentsReminderView, unreadCount: 1)
|
|
return
|
|
}
|
|
guard nil != TSContactThread.getWithContactAddress(address, transaction: transaction) else {
|
|
configureUnreadPaymentsBannerMultiple(paymentsReminderView, unreadCount: 1)
|
|
return
|
|
}
|
|
|
|
let userName = contactsManager.shortDisplayName(for: address, transaction: transaction)
|
|
let formattedAmount = PaymentsFormat.format(paymentAmount: paymentAmount,
|
|
isShortForm: true,
|
|
withCurrencyCode: true,
|
|
withSpace: true)
|
|
let format = NSLocalizedString("PAYMENTS_NOTIFICATION_BANNER_1_WITH_DETAILS_FORMAT",
|
|
comment: "Format for the payments notification banner for a single payment notification with details. Embeds: {{ %1$@ the name of the user who sent you the payment, %2$@ the amount of the payment }}.")
|
|
let title = String(format: format, userName, formattedAmount)
|
|
|
|
let avatarView = ConversationAvatarView(sizeClass: .customDiameter(Self.paymentsBannerAvatarSize), localUserDisplayMode: .asUser)
|
|
avatarView.update(transaction) { config in
|
|
config.dataSource = .address(address)
|
|
}
|
|
|
|
let paymentsHistoryItem = PaymentsHistoryItem(paymentModel: paymentModel,
|
|
displayName: userName)
|
|
|
|
configureUnreadPaymentsBanner(paymentsReminderView,
|
|
title: title,
|
|
avatarView: avatarView) { [weak self] in
|
|
self?.showAppSettings(mode: .payment(paymentsHistoryItem: paymentsHistoryItem))
|
|
}
|
|
}
|
|
|
|
func configureUnreadPaymentsBannerMultiple(_ paymentsReminderView: UIView,
|
|
unreadCount: UInt) {
|
|
let title: String
|
|
if unreadCount == 1 {
|
|
title = NSLocalizedString("PAYMENTS_NOTIFICATION_BANNER_1",
|
|
comment: "Label for the payments notification banner for a single payment notification.")
|
|
} else {
|
|
let format = NSLocalizedString("PAYMENTS_NOTIFICATION_BANNER_N_FORMAT",
|
|
comment: "Format for the payments notification banner for multiple payment notifications. Embeds: {{ the number of unread payment notifications }}.")
|
|
title = String(format: format, OWSFormat.formatUInt(unreadCount))
|
|
}
|
|
|
|
let iconView = UIImageView.withTemplateImageName(Theme.iconName(.paymentNotification),
|
|
tintColor: (Theme.isDarkThemeEnabled
|
|
? .ows_gray15
|
|
: .ows_white))
|
|
iconView.autoSetDimensions(to: .square(24))
|
|
let iconCircleView = OWSLayerView.circleView(size: CGFloat(Self.paymentsBannerAvatarSize))
|
|
iconCircleView.backgroundColor = (Theme.isDarkThemeEnabled
|
|
? .ows_gray80
|
|
: .ows_gray95)
|
|
iconCircleView.addSubview(iconView)
|
|
iconView.autoCenterInSuperview()
|
|
|
|
configureUnreadPaymentsBanner(paymentsReminderView,
|
|
title: title,
|
|
avatarView: iconCircleView) { [weak self] in
|
|
self?.showAppSettings(mode: .payments)
|
|
}
|
|
}
|
|
|
|
private static let paymentsBannerAvatarSize: UInt = 40
|
|
|
|
private class PaymentsBannerView: UIView {
|
|
let block: () -> Void
|
|
|
|
required init(block: @escaping () -> Void) {
|
|
self.block = block
|
|
|
|
super.init(frame: .zero)
|
|
|
|
isUserInteractionEnabled = true
|
|
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTap)))
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
@objc
|
|
func didTap() {
|
|
block()
|
|
}
|
|
}
|
|
|
|
private func configureUnreadPaymentsBanner(_ paymentsReminderView: UIView,
|
|
title: String,
|
|
avatarView: UIView,
|
|
block: @escaping () -> Void) {
|
|
paymentsReminderView.removeAllSubviews()
|
|
|
|
let paymentsBannerView = PaymentsBannerView(block: block)
|
|
paymentsReminderView.addSubview(paymentsBannerView)
|
|
paymentsBannerView.autoPinEdgesToSuperviewEdges()
|
|
|
|
if UIDevice.current.isIPad {
|
|
paymentsReminderView.backgroundColor = (Theme.isDarkThemeEnabled
|
|
? .ows_gray75
|
|
: .ows_gray05)
|
|
} else {
|
|
paymentsReminderView.backgroundColor = (Theme.isDarkThemeEnabled
|
|
? .ows_gray90
|
|
: .ows_gray02)
|
|
}
|
|
|
|
avatarView.setCompressionResistanceHigh()
|
|
avatarView.setContentHuggingHigh()
|
|
|
|
let titleLabel = UILabel()
|
|
titleLabel.text = title
|
|
titleLabel.textColor = Theme.primaryTextColor
|
|
titleLabel.font = UIFont.ows_dynamicTypeSubheadlineClamped.ows_semibold
|
|
|
|
let viewLabel = UILabel()
|
|
viewLabel.text = CommonStrings.viewButton
|
|
viewLabel.textColor = Theme.accentBlueColor
|
|
viewLabel.font = UIFont.ows_dynamicTypeSubheadlineClamped
|
|
|
|
let textStack = UIStackView(arrangedSubviews: [ titleLabel, viewLabel ])
|
|
textStack.axis = .vertical
|
|
textStack.alignment = .leading
|
|
|
|
let dismissButton = OWSLayerView.circleView(size: 20)
|
|
dismissButton.backgroundColor = (Theme.isDarkThemeEnabled
|
|
? .ows_gray65
|
|
: .ows_gray05)
|
|
dismissButton.setCompressionResistanceHigh()
|
|
dismissButton.setContentHuggingHigh()
|
|
|
|
let dismissIcon = UIImageView.withTemplateImageName("x-16",
|
|
tintColor: (Theme.isDarkThemeEnabled
|
|
? .ows_white
|
|
: .ows_gray60))
|
|
dismissIcon.autoSetDimensions(to: .square(16))
|
|
dismissButton.addSubview(dismissIcon)
|
|
dismissIcon.autoCenterInSuperview()
|
|
|
|
let stack = UIStackView(arrangedSubviews: [ avatarView,
|
|
textStack,
|
|
dismissButton ])
|
|
stack.axis = .horizontal
|
|
stack.alignment = .center
|
|
stack.spacing = 10
|
|
stack.layoutMargins = UIEdgeInsets(
|
|
top: OWSTableViewController2.cellVInnerMargin,
|
|
left: OWSTableViewController2.cellHOuterLeftMargin(in: view),
|
|
bottom: OWSTableViewController2.cellVInnerMargin,
|
|
right: OWSTableViewController2.cellHOuterRightMargin(in: view)
|
|
)
|
|
stack.isLayoutMarginsRelativeArrangement = true
|
|
paymentsBannerView.addSubview(stack)
|
|
stack.autoPinEdgesToSuperviewEdges()
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public enum ShowAppSettingsMode {
|
|
case none
|
|
case payments
|
|
case payment(paymentsHistoryItem: PaymentsHistoryItem)
|
|
case paymentsTransferIn
|
|
case appearance
|
|
case avatarBuilder
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
public extension HomeViewController {
|
|
|
|
@objc
|
|
func createAvatarBarButtonViewWithSneakyTransaction() -> UIView {
|
|
let avatarView = ConversationAvatarView(sizeClass: .twentyEight, localUserDisplayMode: .asUser)
|
|
databaseStorage.read { readTx in
|
|
avatarView.update(readTx) { config in
|
|
if let address = tsAccountManager.localAddress(with: readTx) {
|
|
config.dataSource = .address(address)
|
|
config.applyConfigurationSynchronously()
|
|
}
|
|
}
|
|
}
|
|
return avatarView
|
|
}
|
|
|
|
@objc
|
|
func showAppSettings() {
|
|
showAppSettings(mode: .none)
|
|
}
|
|
|
|
@objc
|
|
func showAppSettingsInAppearanceMode() {
|
|
showAppSettings(mode: .appearance)
|
|
}
|
|
|
|
@objc
|
|
func showAppSettingsInAvatarBuilderMode() {
|
|
showAppSettings(mode: .avatarBuilder)
|
|
}
|
|
|
|
func showAppSettings(mode: ShowAppSettingsMode) {
|
|
AssertIsOnMainThread()
|
|
|
|
Logger.info("")
|
|
|
|
// Dismiss any message actions if they're presented
|
|
if FeatureFlags.contextMenus {
|
|
conversationSplitViewController?.selectedConversationViewController?.dismissMessageContextMenu(animated: true)
|
|
} else {
|
|
conversationSplitViewController?.selectedConversationViewController?.dismissMessageActions(animated: true)
|
|
}
|
|
|
|
let navigationController = AppSettingsViewController.inModalNavigationController()
|
|
|
|
var completion: (() -> Void)?
|
|
|
|
var viewControllers = navigationController.viewControllers
|
|
switch mode {
|
|
case .none:
|
|
break
|
|
case .payments:
|
|
let paymentsSettings = PaymentsSettingsViewController(mode: .inAppSettings)
|
|
viewControllers += [ paymentsSettings ]
|
|
case .payment(let paymentsHistoryItem):
|
|
let paymentsSettings = PaymentsSettingsViewController(mode: .inAppSettings)
|
|
let paymentsDetail = PaymentsDetailViewController(paymentItem: paymentsHistoryItem)
|
|
viewControllers += [ paymentsSettings, paymentsDetail ]
|
|
case .paymentsTransferIn:
|
|
let paymentsSettings = PaymentsSettingsViewController(mode: .inAppSettings)
|
|
let paymentsTransferIn = PaymentsTransferInViewController()
|
|
viewControllers += [ paymentsSettings, paymentsTransferIn ]
|
|
case .appearance:
|
|
let appearance = AppearanceSettingsTableViewController()
|
|
viewControllers += [ appearance ]
|
|
case .avatarBuilder:
|
|
let profile = ProfileSettingsViewController()
|
|
viewControllers += [ profile ]
|
|
completion = { profile.presentAvatarSettingsView() }
|
|
}
|
|
navigationController.setViewControllers(viewControllers, animated: false)
|
|
presentFormSheet(navigationController, animated: true, completion: completion)
|
|
}
|
|
}
|