Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚀[Release v3.12.0] Merge into Main #221

Closed
wants to merge 52 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
d40fe0b
🦺[Techdebt] fix firebase (#115)
kcw-grunt Oct 28, 2022
847b1c8
🥳[Techdebt] relayout address view controller (#120)
kcw-grunt Aug 29, 2022
1db58ca
buiid bump (#125)
kcw-grunt Oct 28, 2022
94403b2
reemvoed conflict tags
kcw-grunt Nov 6, 2022
7ae41b9
🚀[Release v3.10.1] Merge into Develop (#162)
kcw-grunt Nov 28, 2022
045c5be
Add SwiftFormat to the codebase (#159)
Iferencak Dec 5, 2022
fd912d0
🤬[Techdebt] #167 add custom user agent++ (#168)
kcw-grunt Dec 14, 2022
e9276b1
bump to match current prod build number
kcw-grunt Jan 26, 2023
7989824
Removed app install date variable (#200)
Iferencak Mar 12, 2023
9bf1f78
nit…format (#203)
kcw-grunt Mar 16, 2023
7b14163
Update the loafwallet-core submodule
kcw-grunt Apr 9, 2023
3a03b0e
#207 resolve core update issue missing labels (#211)
kcw-grunt Nov 4, 2023
3377025
🚀[Release v3.11.1] Merge into Develop (#214)
kcw-grunt Nov 24, 2023
57e7f59
Removed all ArticleIds (#216)
kcw-grunt Dec 1, 2023
c341eb1
RENAMED the project to Litewallet
kcw-grunt Nov 24, 2023
c0c40fb
Updated the fee words for all languages
kcw-grunt Nov 27, 2023
2cb5db5
Added new EnterPhraseView HostingController
kcw-grunt Nov 28, 2023
09a1e50
WIP: Pusher waiting for https://github.com/pusher/push-notifications-…
kcw-grunt Dec 1, 2023
170068a
Integrating the ops fee
kcw-grunt Dec 1, 2023
ea32dc6
Successfully send to 2 outputs
kcw-grunt Dec 1, 2023
b9dbc52
Integrated Push Notifications
kcw-grunt Dec 3, 2023
4414ed7
Refactored legacy code
kcw-grunt Dec 4, 2023
e3039ff
Refactored the Launch
kcw-grunt Dec 4, 2023
df4e9db
WIP: Adding more create views
kcw-grunt Dec 5, 2023
b8dc28a
updated the gitignore
kcw-grunt Jan 4, 2024
6c56d78
Began added CreateViews
kcw-grunt Dec 6, 2023
2b62aa5
Updated the localization files
kcw-grunt Dec 7, 2023
5d52fab
Added pusher and paths for devices
kcw-grunt Dec 8, 2023
f6ca735
Finished layout of Acceptance for notifications
kcw-grunt Dec 31, 2023
16a58d8
Fixes a memory leak solved by @hectorchu
kcw-grunt Jan 7, 2024
d255c7a
updated loafwallet-core version
kcw-grunt Jan 7, 2024
6153a03
Need to work in the Showing and hiding the announce view
kcw-grunt Jan 12, 2024
f18f407
added LWAnalytics notifications
kcw-grunt Jan 14, 2024
5e169d9
Merge branch 'develop' into exploration/update-create-restore-wallet
kcw-grunt Jan 14, 2024
a07f920
added amount field
kcw-grunt Jan 14, 2024
f82ed3d
prelayout of the amount in the send SwiftUI send
kcw-grunt Jan 14, 2024
93b4334
added memo and Amount
kcw-grunt Jan 15, 2024
ff3336f
added hack to make it work
kcw-grunt Jan 15, 2024
0aa3433
cleanup of unused code
kcw-grunt Jan 15, 2024
6026658
cleanup of other efforts to debug
kcw-grunt Jan 15, 2024
1356735
readded the didStartEditing
kcw-grunt Jan 15, 2024
c70d7e3
Readded then Address Cell View
kcw-grunt Jan 16, 2024
479f5d1
Maintenance refactor
kcw-grunt Jan 17, 2024
8c7d4e7
fix TestFlight 3.12.0 (240115) · iPhone 13 · 17.2.1
kcw-grunt Jan 17, 2024
18069ed
Refactored the send animations and layout
kcw-grunt Jan 17, 2024
5946bcd
clean up location of vars
kcw-grunt Jan 18, 2024
3595601
Fixed a big bug
kcw-grunt Jan 18, 2024
0878f48
😍[Feature] Exploration/update create restore wallet (#219)
kcw-grunt Jan 18, 2024
c2f00cc
Merge branch 'exploration/update-create-restore-wallet' into develop
kcw-grunt Jan 18, 2024
7728444
resolve conflicts
kcw-grunt Jan 18, 2024
4a8d1a4
Added a address test
kcw-grunt Jan 18, 2024
76aa21b
updated filesystem
kcw-grunt Jan 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
added memo and Amount
Signed-off-by: kcw-grunt <mrkerrywashington@icloud.com>
kcw-grunt committed Jan 15, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 93b4334ab416ac2bb7eca32d2189485fa9bc6e48
248 changes: 248 additions & 0 deletions litewallet/RequestAmountViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
import Foundation
import UIKit

private let qrSize: CGSize = .init(width: 186.0, height: 186.0)
private let smallButtonHeight: CGFloat = 32.0
private let buttonPadding: CGFloat = 20.0
private let smallSharePadding: CGFloat = 12.0
private let largeSharePadding: CGFloat = 20.0

class RequestAmountViewController: UIViewController {
var presentEmail: PresentShare?
var presentText: PresentShare?

init(wallet: BRWallet, store: Store) {
self.wallet = wallet
amountView = AmountViewController(store: store, isPinPadExpandedAtLaunch: true, hasAcceptedFees: <#Bool#>, isRequesting: true)
super.init(nibName: nil, bundle: nil)
}

// MARK: - Private

private let amountView: AmountViewController
private let qrCode = UIImageView()
private let address = UILabel(font: .customBody(size: 14.0))
private let addressPopout = InViewAlert(type: .primary)
private let share = ShadowButton(title: S.Receive.share.localize(), type: .tertiary, image: #imageLiteral(resourceName: "Share"))
private let sharePopout = InViewAlert(type: .secondary)
private let border = UIView()
private var topSharePopoutConstraint: NSLayoutConstraint?
private let wallet: BRWallet

// MARK: - PinPad State

private var amount: Satoshis? {
didSet {
setQrCode()
}
}

override func viewDidLoad() {
addSubviews()
addConstraints()
setData()
addActions()
setupCopiedMessage()
setupShareButtons()
}

private func addSubviews() {
view.addSubview(qrCode)
view.addSubview(address)
view.addSubview(addressPopout)
view.addSubview(share)
view.addSubview(sharePopout)
view.addSubview(border)
}

private func addConstraints() {
addChildViewController(amountView, layout: {
amountView.view.constrain([
amountView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
amountView.view.topAnchor.constraint(equalTo: view.topAnchor),
amountView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
])
})
qrCode.constrain([
qrCode.constraint(.width, constant: qrSize.width),
qrCode.constraint(.height, constant: qrSize.height),
qrCode.topAnchor.constraint(equalTo: amountView.view.bottomAnchor, constant: C.padding[2]),
qrCode.constraint(.centerX, toView: view),
])
address.constrain([
address.constraint(toBottom: qrCode, constant: C.padding[1]),
address.constraint(.centerX, toView: view),
])
addressPopout.heightConstraint = addressPopout.constraint(.height, constant: 0.0)
addressPopout.constrain([
addressPopout.constraint(toBottom: address, constant: 0.0),
addressPopout.constraint(.centerX, toView: view),
addressPopout.constraint(.width, toView: view),
addressPopout.heightConstraint,
])
share.constrain([
share.constraint(toBottom: addressPopout, constant: C.padding[2]),
share.constraint(.centerX, toView: view),
share.constraint(.width, constant: qrSize.width),
share.constraint(.height, constant: smallButtonHeight),
])
sharePopout.heightConstraint = sharePopout.constraint(.height, constant: 0.0)
topSharePopoutConstraint = sharePopout.constraint(toBottom: share, constant: largeSharePadding)
sharePopout.constrain([
topSharePopoutConstraint,
sharePopout.constraint(.centerX, toView: view),
sharePopout.constraint(.width, toView: view),
sharePopout.heightConstraint,
])
border.constrain([
border.constraint(.width, toView: view),
border.constraint(toBottom: sharePopout, constant: 0.0),
border.constraint(.centerX, toView: view),
border.constraint(.height, constant: 1.0),
border.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -C.padding[2]),
])
}

private func setData() {
view.backgroundColor = .white
address.text = wallet.receiveAddress
address.textColor = .grayTextTint
border.backgroundColor = .secondaryBorder
qrCode.image = UIImage.qrCode(data: "\(wallet.receiveAddress)".data(using: .utf8)!, color: CIColor(color: .black))?
.resize(qrSize)!
share.isToggleable = true
sharePopout.clipsToBounds = true
}

private func addActions() {
let gr = UITapGestureRecognizer(target: self, action: #selector(RequestAmountViewController.addressTapped))
address.addGestureRecognizer(gr)
address.isUserInteractionEnabled = true
share.addTarget(self, action: #selector(RequestAmountViewController.shareTapped), for: .touchUpInside)
amountView.didUpdateAmount = { [weak self] amount in
self?.amount = amount
}
}

private func setQrCode() {
guard let amount = amount else { return }
let request = PaymentRequest.requestString(withAddress: wallet.receiveAddress, forAmount: amount.rawValue)
qrCode.image = UIImage.qrCode(data: request.data(using: .utf8)!, color: CIColor(color: .black))?
.resize(qrSize)!
}

private func setupCopiedMessage() {
let copiedMessage = UILabel(font: .customMedium(size: 14.0))
copiedMessage.textColor = .white
copiedMessage.text = S.Receive.copied.localize()
copiedMessage.textAlignment = .center
addressPopout.contentView = copiedMessage
}

private func setupShareButtons() {
let container = UIView()
container.translatesAutoresizingMaskIntoConstraints = false
let email = ShadowButton(title: S.Receive.emailButton.localize(), type: .tertiary)
let text = ShadowButton(title: S.Receive.textButton.localize(), type: .tertiary)
container.addSubview(email)
container.addSubview(text)
email.constrain([
email.constraint(.leading, toView: container, constant: C.padding[2]),
email.constraint(.top, toView: container, constant: buttonPadding),
email.constraint(.bottom, toView: container, constant: -buttonPadding),
email.trailingAnchor.constraint(equalTo: container.centerXAnchor, constant: -C.padding[1]),
])
text.constrain([
text.constraint(.trailing, toView: container, constant: -C.padding[2]),
text.constraint(.top, toView: container, constant: buttonPadding),
text.constraint(.bottom, toView: container, constant: -buttonPadding),
text.leadingAnchor.constraint(equalTo: container.centerXAnchor, constant: C.padding[1]),
])
sharePopout.contentView = container
email.addTarget(self, action: #selector(RequestAmountViewController.emailTapped), for: .touchUpInside)
text.addTarget(self, action: #selector(RequestAmountViewController.textTapped), for: .touchUpInside)
}

@objc private func shareTapped() {
toggle(alertView: sharePopout, shouldAdjustPadding: true)
if addressPopout.isExpanded {
toggle(alertView: addressPopout, shouldAdjustPadding: false)
}
}

@objc private func addressTapped() {
guard let text = address.text else { return }
UIPasteboard.general.string = text
toggle(alertView: addressPopout, shouldAdjustPadding: false, shouldShrinkAfter: true)
if sharePopout.isExpanded {
toggle(alertView: sharePopout, shouldAdjustPadding: true)
}
}

@objc private func emailTapped() {
guard let amount = amount else { return showErrorMessage(S.RequestAnAmount.noAmount.localize()) }
let text = PaymentRequest.requestString(withAddress: wallet.receiveAddress, forAmount: amount.rawValue)
presentEmail?(text, qrCode.image!)
}

@objc private func textTapped() {
guard let amount = amount else { return showErrorMessage(S.RequestAnAmount.noAmount.localize()) }
let text = PaymentRequest.requestString(withAddress: wallet.receiveAddress, forAmount: amount.rawValue)
presentText?(text, qrCode.image!)
}

private func toggle(alertView: InViewAlert, shouldAdjustPadding: Bool, shouldShrinkAfter: Bool = false)
{
share.isEnabled = false
address.isUserInteractionEnabled = false

var deltaY = alertView.isExpanded ? -alertView.height : alertView.height
if shouldAdjustPadding {
if deltaY > 0 {
deltaY -= (largeSharePadding - smallSharePadding)
} else {
deltaY += (largeSharePadding - smallSharePadding)
}
}

if alertView.isExpanded {
alertView.contentView?.isHidden = true
}

UIView.spring(C.animationDuration, animations: {
if shouldAdjustPadding {
let newPadding = self.sharePopout.isExpanded ? largeSharePadding : smallSharePadding
self.topSharePopoutConstraint?.constant = newPadding
}
alertView.toggle()
self.parent?.view.layoutIfNeeded()
}, completion: { _ in
alertView.isExpanded = !alertView.isExpanded
self.share.isEnabled = true
self.address.isUserInteractionEnabled = true
alertView.contentView?.isHidden = false
if shouldShrinkAfter {
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
if alertView.isExpanded {
self.toggle(alertView: alertView, shouldAdjustPadding: shouldAdjustPadding)
}
}
}
})
}

@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

extension RequestAmountViewController: ModalDisplayable {
var faqArticleId: String? {
return ArticleIds.nothing
}

var modalTitle: String {
return S.Receive.request.localize()
}
}
53 changes: 53 additions & 0 deletions litewallet/src/MemoFieldView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Foundation
import SwiftUI

struct MemoFieldView: UIViewRepresentable {
@Binding var text: String

private var placeholder: String

init(placeholder: String,
text: Binding<String>)
{
self.placeholder = placeholder
_text = text
}

func makeUIView(context: Context) -> UITextField {
let textfield = UITextField()
textfield.delegate = context.coordinator
textfield.placeholder = placeholder
textfield.textAlignment = .left
textfield.adjustsFontSizeToFitWidth = true
textfield.font = UIFont.barlowMedium(size: 14.0)
textfield.minimumFontSize = 12.0
textfield.keyboardType = .default
textfield.autocorrectionType = .no
textfield.autocapitalizationType = .none
return textfield
}

func updateUIView(_ uiView: UITextField, context _: Context) {
uiView.text = text
}

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

class Coordinator: NSObject, UITextFieldDelegate {
var parent: MemoFieldView

init(_ textField: MemoFieldView) {
parent = textField
}

func textFieldDidEndEditing(_ textField: UITextField, reason _: UITextField.DidEndEditingReason) {
textField.resignFirstResponder()
}

func textFieldDidBeginEditing(_ textField: UITextField) {
parent.text = textField.text!
}
}
}