Skip to content

Commit

Permalink
Add AddressComponent
Browse files Browse the repository at this point in the history
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
nikola-milicevic committed Apr 26, 2023
1 parent fdb45dc commit 5d50ea4
Show file tree
Hide file tree
Showing 49 changed files with 587 additions and 697 deletions.
290 changes: 135 additions & 155 deletions .swiftpm/xcode/xcshareddata/xcschemes/Unit Tests.xcscheme

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ package.addModules([
dependencies: [
"AccountPortfoliosClient",
],
tests: .yes()
tests: .no
),
.feature(
name: "AccountPreferencesFeature",
Expand Down Expand Up @@ -624,7 +624,7 @@ package.addModules([
.package(url: "https://github.com/davdroman/TextBuilder", from: "2.2.0")
},
],
tests: .yes()
tests: .no
),
.core(
name: "Resources",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,10 @@ extension AccountPortfoliosClient {

let nonFungibleResources = try await rawItems.parallelMap { resource in
// Load the nftIds from the resource vault
let nftIds = try await {
let nonFungibleLocalIds = try await {
// Resources of an account always have one single vault which stores the value.
guard let vault = resource.vaults.items.first else {
return [AccountPortfolio.NonFungibleResource.NonFungibleTokenId]()
return [AccountPortfolio.NonFungibleResource.NonFungibleLocalId]()
}

// Fetch all nft ids pages from the vault
Expand All @@ -261,7 +261,7 @@ extension AccountPortfoliosClient {
)
)
.map {
AccountPortfolio.NonFungibleResource.NonFungibleTokenId($0.nonFungibleId)
AccountPortfolio.NonFungibleResource.NonFungibleLocalId($0.nonFungibleId)
}

}()
Expand All @@ -273,7 +273,7 @@ extension AccountPortfoliosClient {
resourceAddress: .init(address: resource.resourceAddress),
name: metadata?.name,
description: metadata?.description,
nftIds: nftIds
localIds: nonFungibleLocalIds
)
}

Expand Down
73 changes: 0 additions & 73 deletions Sources/Core/DesignSystem/Components/AccountButton.swift

This file was deleted.

89 changes: 0 additions & 89 deletions Sources/Core/DesignSystem/Components/AddressView.swift

This file was deleted.

28 changes: 28 additions & 0 deletions Sources/Core/FeaturePrelude/AddressView/AddressFormat.swift
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 Sources/Core/FeaturePrelude/AddressView/AddressView.swift
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
Loading

0 comments on commit 5d50ea4

Please sign in to comment.