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

1.6.14 #979

Merged
merged 19 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Example/IntegrationTests/Push/Publisher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Publisher {
let payload = try encoder.encode(notifyRequestPayload)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Authorization", forHTTPHeaderField: InputConfig.gmDappProjectSecret)
request.setValue("Bearer \(InputConfig.gmDappProjectSecret)", forHTTPHeaderField: "Authorization")
request.httpBody = payload
let (_, response) = try await URLSession.shared.data(for: request)
guard (response as? HTTPURLResponse)?.statusCode == 200 else { fatalError("Notify error") }
Expand Down
8 changes: 3 additions & 5 deletions Sources/Auth/Services/Wallet/WalletRequestSubscriber.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,11 @@ class WalletRequestSubscriber {
let assertionId = payload.decryptedPayload.sha256().toHexString()
do {
let origin = try await verifyClient.verifyOrigin(assertionId: assertionId)
let verifyContext = await verifyClient.createVerifyContext(
origin: origin,
domain: payload.request.payloadParams.domain
)
let verifyContext = verifyClient.createVerifyContext(origin: origin, domain: payload.request.payloadParams.domain)
onRequest?((request, verifyContext))
} catch {
onRequest?((request, nil))
let verifyContext = verifyClient.createVerifyContext(origin: nil, domain: payload.request.payloadParams.domain)
onRequest?((request, verifyContext))
return
}
}
Expand Down
30 changes: 16 additions & 14 deletions Sources/WalletConnectModal/Modal/ModalContainerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,7 @@ struct ModalContainerView: View {

var body: some View {
VStack(spacing: 0) {

Color.thickOverlay
.colorScheme(.light)
.transform {
#if os(iOS)
$0.onTapGesture {
withAnimation {
showModal = false
}
}
#endif
}
.opacity(showModal ? 1 : 0)
Color.clear

if showModal {
ModalSheet(
Expand All @@ -33,8 +21,22 @@ struct ModalContainerView: View {
.animation(.spring(), value: showModal)
}
}

.background(
Color.thickOverlay
.colorScheme(.light)
.opacity(showModal ? 1 : 0)
.transform {
#if os(iOS)
$0.onTapGesture {
withAnimation {
showModal = false
}
}
#endif
}
)
.edgesIgnoringSafeArea(.all)
.ignoresSafeArea(.keyboard, edges: .bottom)
.onChangeBackported(of: showModal, perform: { newValue in
if newValue == false {
withAnimation {
Expand Down
70 changes: 50 additions & 20 deletions Sources/WalletConnectModal/Modal/ModalSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,46 @@ import SwiftUI
public struct ModalSheet: View {
@ObservedObject var viewModel: ModalViewModel

@Environment(\.verticalSizeClass) var verticalSizeClass

@State var searchEditing = false

var isLandscape: Bool {
verticalSizeClass == .compact
}

public var body: some View {
VStack(spacing: 0) {
modalHeader()

VStack(spacing: 0) {
contentHeader()
content()

}
.frame(maxWidth: .infinity)
.background(Color.background1)
.cornerRadius(30, corners: [.topLeft, .topRight])
}
.padding(.bottom, 40)
.edgesIgnoringSafeArea(.bottom)
.background(
VStack(spacing: 0) {
Color.accent
.frame(height: 90)
.cornerRadius(8, corners: [[.topLeft, .topRight]])
Color.background1
}
)
.toastView(toast: $viewModel.toast)
.if(isLandscape) {
$0.padding(.horizontal, 80)
}
.onAppear {
Task {
await viewModel.fetchWallets()
await viewModel.createURI()
}
}
.background(
ZStack {
Color.thickOverlay.colorScheme(.light)

VStack(spacing: 0) {
Color.accent
.frame(height: 90)
.cornerRadius(8, corners: [[.topLeft, .topRight]])
Color.background1
}
}
)
.toastView(toast: $viewModel.toast)
}

private func modalHeader() -> some View {
Expand Down Expand Up @@ -81,14 +88,33 @@ public struct ModalSheet: View {
.overlay(
VStack {
if viewModel.destination.hasSearch {
TextField("Search", text: $viewModel.searchTerm)
.transform {
#if os(iOS)
$0.textFieldStyle(.roundedBorder)
.autocapitalization(.none)

HStack {
Image(systemName: "magnifyingglass")
TextField("Search", text: $viewModel.searchTerm, onEditingChanged: { editing in
self.searchEditing = editing
})
.transform { view in
#if os(macOS)
view
#else
view.autocapitalization(.none)
#endif
}
.padding(.horizontal, 50)
}
.padding(.vertical, 4)
.padding(.horizontal, 10)
.background(Color.background3)
.foregroundColor(searchEditing ? .foreground1 : .foreground3)
.cornerRadius(28)
.overlay(
RoundedRectangle(cornerRadius: 28)
.stroke(searchEditing ? Color.accent : Color.thinOverlay, lineWidth: 1)
)
.onDisappear {
searchEditing = false
}
.padding(.horizontal, 50)
} else {
Text(viewModel.destination.contentTitle)
.font(.system(size: 20).weight(.semibold))
Expand Down Expand Up @@ -135,14 +161,18 @@ public struct ModalSheet: View {
navigateTo: viewModel.navigateTo(_:),
navigateToExternalLink: viewModel.navigateToExternalLink(_:)
)
.padding(.bottom, 20)
case .qr:
qrCode()
.padding(.bottom, 20)
case .getWallet:
GetAWalletView(
wallets: Array(viewModel.wallets.prefix(6)),
onWalletTap: viewModel.onGetWalletTap(_:),
navigateToExternalLink: viewModel.navigateToExternalLink(_:)
)
.frame(minHeight: isLandscape ? 200 : 550)
.padding(.bottom, 20)
}
}
}
Expand Down
70 changes: 66 additions & 4 deletions Sources/WalletConnectModal/Modal/ModalViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,11 @@ final class ModalViewModel: ObservableObject {
}

var filteredWallets: [Listing] {
if searchTerm.isEmpty { return wallets }
if searchTerm.isEmpty { return sortByRecent(wallets) }

return wallets.filter { $0.name.lowercased().contains(searchTerm.lowercased()) }
return sortByRecent(
wallets.filter { $0.name.lowercased().contains(searchTerm.lowercased()) }
)
}

private var disposeBag = Set<AnyCancellable>()
Expand All @@ -77,7 +79,7 @@ final class ModalViewModel: ObservableObject {
.sink { sessions in
print(sessions)
isShown.wrappedValue = false
self.toast = Toast(style: .success, message: "Session estabilished", duration: 15)
self.toast = Toast(style: .success, message: "Session estabilished", duration: 5)
}
.store(in: &disposeBag)

Expand Down Expand Up @@ -120,6 +122,8 @@ final class ModalViewModel: ObservableObject {
}

func onListingTap(_ listing: Listing) {
setLastTimeUsed(listing.id)

navigateToDeepLink(
universalLink: listing.mobile.universal ?? "",
nativeLink: listing.mobile.native ?? ""
Expand All @@ -146,7 +150,6 @@ final class ModalViewModel: ObservableObject {

func onCopyButton() {


guard let uri else {
toast = Toast(style: .error, message: "No uri found")
return
Expand Down Expand Up @@ -190,13 +193,72 @@ final class ModalViewModel: ObservableObject {

return lhs < rhs
}

loadRecentWallets()
}
} catch {
toast = Toast(style: .error, message: error.localizedDescription)
}
}
}

// MARK: - Recent Wallets

private extension ModalViewModel {

func sortByRecent(_ input: [Listing]) -> [Listing] {
input.sorted { lhs, rhs in
guard let lhsLastTimeUsed = lhs.lastTimeUsed else {
return false
}

guard let rhsLastTimeUsed = rhs.lastTimeUsed else {
return true
}

return lhsLastTimeUsed > rhsLastTimeUsed
}
}

func loadRecentWallets() {
RecentWalletsStorage().recentWallets.forEach { wallet in

guard let lastTimeUsed = wallet.lastTimeUsed else {
return
}

// Consider Recent only for 3 days
if abs(lastTimeUsed.timeIntervalSinceNow) > (24 * 60 * 60 * 3) {
return
}

setLastTimeUsed(wallet.id, date: lastTimeUsed)
}
}

func saveRecentWallets() {
RecentWalletsStorage().recentWallets = Array(wallets.filter {
$0.lastTimeUsed != nil
}.prefix(5))
}

func setLastTimeUsed(_ walletId: String, date: Date = Date()) {
guard let index = wallets.firstIndex(where: {
$0.id == walletId
}) else {
return
}

var copy = wallets[index]
copy.lastTimeUsed = date
wallets[index] = copy

saveRecentWallets()
}
}

// MARK: - Deeplinking

private extension ModalViewModel {
enum DeeplinkErrors: LocalizedError {
case noWalletLinkFound
Expand Down
31 changes: 31 additions & 0 deletions Sources/WalletConnectModal/Modal/RecentWalletStorage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Foundation

final class RecentWalletsStorage {
private let defaults: UserDefaults

init(defaults: UserDefaults = .standard) {
self.defaults = defaults
}

var recentWallets: [Listing] {
get {
guard
let data = defaults.data(forKey: "recentWallets"),
let wallets = try? JSONDecoder().decode([Listing].self, from: data)
else {
return []
}

return wallets
}
set {
guard
let walletsData = try? JSONEncoder().encode(newValue)
else {
return
}

defaults.set(walletsData, forKey: "recentWallets")
}
}
}
17 changes: 8 additions & 9 deletions Sources/WalletConnectModal/Modal/Screens/GetAWalletView.swift
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import SwiftUI

struct GetAWalletView: View {

let wallets: [Listing]
let onWalletTap: (Listing) -> Void
let navigateToExternalLink: (URL) -> Void

var body: some View {
VStack {

ScrollView {
List {
ForEach(wallets) { wallet in
ForEach(wallets, id: \.id) { wallet in
Button {
onWalletTap(wallet)
} label: {

HStack {
WalletImage(wallet: wallet)
.frame(width: 40, height: 40)
Expand All @@ -34,8 +31,8 @@ struct GetAWalletView: View {
.frame(minHeight: 400)
.listStyle(.plain)


VStack(alignment: .center, spacing: 8) {

Text("Not what you’re looking for?")
.font(
.system(size: 16)
Expand All @@ -44,7 +41,7 @@ struct GetAWalletView: View {
.multilineTextAlignment(.center)
.foregroundColor(.foreground1)

Text("With hundreds of wallets out there, there’s something for everyone ")
Text("With hundreds of wallets out there, there’s something for everyone ")
.font(
.system(size: 14)
.weight(.medium)
Expand All @@ -70,10 +67,10 @@ struct GetAWalletView: View {
}
}

#if DEBUG

struct GetAWalletView_Previews: PreviewProvider {

static var previews: some View {

GetAWalletView(
wallets: Listing.stubList,
onWalletTap: { _ in },
Expand All @@ -82,3 +79,5 @@ struct GetAWalletView_Previews: PreviewProvider {
.environment(\.projectId, Secrets.load().projectID)
}
}

#endif
Loading
Loading