-
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 Move to enum Clean up Update context menu Use existing init
- Loading branch information
1 parent
625dc17
commit 3ca7321
Showing
53 changed files
with
686 additions
and
681 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 was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
File renamed without changes.
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,16 @@ | ||
import Resources | ||
import SwiftUI | ||
|
||
extension Button where Label == SwiftUI.Label<Text, Image> { | ||
public init(_ titleKey: LocalizedStringKey, asset: ImageAsset, action: @escaping () -> Void) { | ||
self.init(action: action) { | ||
SwiftUI.Label(titleKey, asset: asset) | ||
} | ||
} | ||
|
||
public init<S>(_ title: S, asset: ImageAsset, action: @escaping () -> Void) where S: StringProtocol { | ||
self.init(action: action) { | ||
SwiftUI.Label(title, asset: asset) | ||
} | ||
} | ||
} |
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,22 @@ | ||
import Resources | ||
import SwiftUI | ||
|
||
extension Label where Title == Text, Icon == Image { | ||
public init(_ titleKey: LocalizedStringKey, asset: ImageAsset) { | ||
self.init { | ||
Text(titleKey) | ||
} icon: { | ||
Image(asset: asset) | ||
.renderingMode(.template) | ||
} | ||
} | ||
|
||
public init<S>(_ title: S, asset: ImageAsset) where S: StringProtocol { | ||
self.init { | ||
Text(title) | ||
} icon: { | ||
Image(asset: asset) | ||
.renderingMode(.template) | ||
} | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
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() | ||
} | ||
} | ||
} |
134 changes: 134 additions & 0 deletions
134
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,134 @@ | ||
import Prelude | ||
import Resources | ||
import SharedModels | ||
import SwiftUI | ||
|
||
// MARK: - AddressView | ||
public struct AddressView: SwiftUI.View, Sendable { | ||
let identifiable: LedgerIdentifiable | ||
let isTappable: Bool | ||
private let format: AddressFormat | ||
private let action: Action | ||
|
||
@Dependency(\.pasteboardClient) var pasteboardClient | ||
@Dependency(\.openURL) var openURL | ||
|
||
public init( | ||
_ identifiable: LedgerIdentifiable, | ||
isTappable: Bool = true | ||
) { | ||
self.identifiable = identifiable | ||
self.isTappable = isTappable | ||
|
||
switch identifiable { | ||
case .address: | ||
format = .default | ||
action = .copy | ||
case let .identifier(identifier): | ||
switch identifier { | ||
case .transaction: | ||
format = .default | ||
action = .viewOnDashboard | ||
case .nonFungibleGlobalID: | ||
format = .nonFungibleLocalId | ||
action = .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(copyText, asset: AssetResource.copyBig) { | ||
copyToPasteboard() | ||
} | ||
|
||
Button(L10n.AddressAction.viewOnDashboard, asset: AssetResource.iconLinkOut) { | ||
viewOnRadixDashboard() | ||
} | ||
} | ||
} | ||
} | ||
|
||
private var addressView: some View { | ||
Text((identifiable.address).formatted(format)) | ||
.lineLimit(1) | ||
.minimumScaleFactor(0.5) | ||
} | ||
|
||
private var image: Image { | ||
Image(asset: action == .copy ? AssetResource.copy : AssetResource.iconLinkOut) | ||
} | ||
|
||
private var copyText: String { | ||
switch identifiable { | ||
case .address: | ||
return L10n.AddressAction.copyAddress | ||
case let .identifier(identifier): | ||
switch identifier { | ||
case .transaction: | ||
return L10n.AddressAction.copyTransactionId | ||
case .nonFungibleGlobalID: | ||
return L10n.AddressAction.copyNftId | ||
} | ||
} | ||
} | ||
} | ||
|
||
extension AddressView { | ||
private func tapAction() { | ||
action == .copy ? copyToPasteboard() : viewOnRadixDashboard() | ||
} | ||
|
||
private func copyToPasteboard() { | ||
pasteboardClient.copyString(identifiable.address) | ||
} | ||
|
||
private func viewOnRadixDashboard() { | ||
guard let addressURL else { return } | ||
Task { await openURL(addressURL) } | ||
} | ||
|
||
private var path: String? { | ||
identifiable.addressPrefix + "/" + identifiable.address | ||
} | ||
|
||
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(.address(.account(try! .init(address: "account_wqs8qxdx7qw8c")))) | ||
} | ||
} | ||
#endif |
Oops, something went wrong.