-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use address component in home screen Use address component in new entity Use address component in fungible token details Use address component in nft details wip wip Replace AddressComponent with AddressView Fix tests Refactor Minor updates wip wip
- Loading branch information
1 parent
fdb45dc
commit 5d50ea4
Showing
49 changed files
with
587 additions
and
697 deletions.
There are no files selected for viewing
290 changes: 135 additions & 155 deletions
290
.swiftpm/xcode/xcshareddata/xcschemes/Unit Tests.xcscheme
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
28 changes: 28 additions & 0 deletions
28
Sources/Core/FeaturePrelude/AddressView/AddressFormat.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import Foundation | ||
|
||
// MARK: - AddressFormat | ||
public enum AddressFormat: String, Sendable { | ||
case `default` | ||
case nonFungibleLocalId | ||
} | ||
|
||
extension String { | ||
public func truncatedMiddle(keepFirst first: Int, last: Int) -> Self { | ||
guard count > first + last else { return self } | ||
return prefix(first) + "..." + suffix(last) | ||
} | ||
|
||
public func colonSeparated() -> Self { | ||
guard let index = range(of: ":")?.upperBound else { return self } | ||
return String(self[index...]) | ||
} | ||
|
||
public func formatted(_ format: AddressFormat) -> Self { | ||
switch format { | ||
case .default: | ||
return truncatedMiddle(keepFirst: 4, last: 6) | ||
case .nonFungibleLocalId: | ||
return colonSeparated() | ||
} | ||
} | ||
} |
151 changes: 151 additions & 0 deletions
151
Sources/Core/FeaturePrelude/AddressView/AddressView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import Prelude | ||
import Profile | ||
import Resources | ||
import SharedModels | ||
import SwiftUI | ||
|
||
// MARK: - AddressView | ||
public struct AddressView: SwiftUI.View, Sendable { | ||
let address: AddressType | ||
let isTappable: Bool | ||
private let format: AddressFormat | ||
private let action: Action | ||
|
||
@Dependency(\.pasteboardClient) var pasteboardClient | ||
@Dependency(\.openURL) var openURL | ||
|
||
public init( | ||
_ address: AddressType, | ||
isTappable: Bool = true | ||
) { | ||
self.address = address | ||
self.isTappable = isTappable | ||
self.format = address is AccountPortfolio.NonFungibleResource.NonFungibleGlobalId ? .nonFungibleLocalId : .default | ||
self.action = address is TXID ? .viewOnDashboard : .copy | ||
} | ||
} | ||
|
||
extension AddressView { | ||
@ViewBuilder | ||
public var body: some View { | ||
if isTappable { | ||
tappableAddressView | ||
} else { | ||
addressView | ||
} | ||
} | ||
|
||
private var tappableAddressView: some View { | ||
Button { | ||
tapAction() | ||
} label: { | ||
HStack(spacing: .small3) { | ||
addressView | ||
image | ||
} | ||
.contentShape(.contextMenuPreview, RoundedRectangle(cornerRadius: .medium1)) | ||
.contextMenu { | ||
Button { | ||
copyToPasteboard() | ||
} label: { | ||
Text(L10n.AddressAction.copy) | ||
} | ||
|
||
Button { | ||
viewOnRadixDashboard() | ||
} label: { | ||
Text(L10n.AddressAction.viewOnDashboard) | ||
} | ||
} | ||
} | ||
} | ||
|
||
private var addressView: some View { | ||
Text((addressString ?? "").formatted(format)) | ||
.lineLimit(1) | ||
.minimumScaleFactor(0.5) | ||
} | ||
|
||
private var image: Image { | ||
Image(asset: action == .copy ? AssetResource.copy : AssetResource.iconLinkOut) | ||
} | ||
|
||
private var addressString: String? { | ||
if let accountAddress = address as? AccountAddress { | ||
return accountAddress.address | ||
} else if let resourceAddress = address as? ResourceAddress { | ||
return resourceAddress.address | ||
} else if let nftGlobalID = address as? AccountPortfolio.NonFungibleResource.NonFungibleGlobalId { | ||
return nftGlobalID | ||
} else if let transactionID = address as? TXID { | ||
return transactionID.rawValue | ||
} else { | ||
return nil | ||
} | ||
} | ||
|
||
private var addressPrefix: String? { | ||
switch address { | ||
case is AccountAddress: | ||
return "account" | ||
case is PackageAddress: | ||
return "package" | ||
case is ResourceAddress: | ||
return "resource" | ||
case is ComponentAddress: | ||
return "component" | ||
case is AccountPortfolio.NonFungibleResource.NonFungibleGlobalId: | ||
return "nft" | ||
case is TXID: | ||
return "transaction" | ||
default: | ||
return nil | ||
} | ||
} | ||
} | ||
|
||
extension AddressView { | ||
private func tapAction() { | ||
action == .copy ? copyToPasteboard() : viewOnRadixDashboard() | ||
} | ||
|
||
private func copyToPasteboard() { | ||
guard let addressString else { return } | ||
pasteboardClient.copyString(addressString) | ||
} | ||
|
||
private func viewOnRadixDashboard() { | ||
guard let addressURL else { return } | ||
Task { await openURL(addressURL) } | ||
} | ||
|
||
private var isNFTAddress: Bool { | ||
address is AccountPortfolio.NonFungibleResource.NonFungibleGlobalId | ||
} | ||
|
||
private var path: String? { | ||
guard let addressString, let addressPrefix else { return nil } | ||
return addressPrefix + "/" + addressString | ||
} | ||
|
||
private var addressURL: URL? { | ||
guard let path else { return nil } | ||
return Radix.Dashboard.rcnet.url.appending(path: path) | ||
} | ||
} | ||
|
||
// MARK: AddressView.Action | ||
extension AddressView { | ||
private enum Action { | ||
case copy | ||
case viewOnDashboard | ||
} | ||
} | ||
|
||
#if DEBUG | ||
struct AddressView_Previews: PreviewProvider { | ||
static var previews: some View { | ||
AddressView("account_wqs8qxdx7qw8c") | ||
} | ||
} | ||
#endif |
Oops, something went wrong.