Skip to content

Commit

Permalink
collapsing
Browse files Browse the repository at this point in the history
  • Loading branch information
kugel3 committed Mar 9, 2024
1 parent 3cefae6 commit d88ae65
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@ extension TransactionHistoryClient {
items.append(transactionItem)
}

let items_ = try await response.items.parallelMap(transaction(for:))

// We filter out complex resources, i.e. Stake Claim NFTs, Pool Units and LSUs
let simpleResources = keyedResources.filter {
$0.metadata.validator == nil && $0.metadata.poolUnit == nil
Expand Down Expand Up @@ -187,6 +185,51 @@ extension TransactionHistoryClient {
}
}

// MARK: - TransactionInfo
struct TransactionInfo: Sendable {
static let timestampFormatter: ISO8601DateFormatter = {
let dateformatter = ISO8601DateFormatter()
dateformatter.formatOptions.insert(.withFractionalSeconds)
return dateformatter
}()

let time: Date
let message: String?
let manifestClass: GatewayAPI.ManifestClass?
// let fungibleBalanceChanges: String
// let nonFungibleBalanceChanges: String
let depositSettingsUpdated: Bool
let failed: Bool
}

extension TransactionInfo {
init(info: GatewayAPI.CommittedTransactionInfo) throws {
guard let time = TransactionInfo.timestampFormatter.date(from: info.roundTimestamp) else {
struct CorruptTimestamp: Error { let roundTimestamd: String }
throw CorruptTimestamp(roundTimestamd: info.roundTimestamp)
}

let message = info.message?.plaintext?.content.string
let manifestClass = info.manifestClasses?.first
guard info.receipt?.status == .committedSuccess else {
self.init(time: time, message: message, manifestClass: manifestClass, depositSettingsUpdated: false, failed: true)
return
}

let changes = info.balanceChanges

let depositSettingsUpdated = info.manifestClasses?.contains(.accountDepositSettingsUpdate) == true

self.init(
time: time,
message: message,
manifestClass: manifestClass,
depositSettingsUpdated: depositSettingsUpdated,
failed: false
)
}
}

extension TransactionHistoryRequest {
var gatewayRequest: GatewayAPI.StreamTransactionsRequest {
.init(
Expand Down
3 changes: 2 additions & 1 deletion RadixWallet/Core/DesignSystem/Layouts/FlowLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ public struct FlowLayout: Layout {
public let alignment: VerticalAlignment
public let spacing: CGSize

public init(alignment: VerticalAlignment = .center, spacing: CGFloat = 10, rowLimit: Int? = nil) {
public init(alignment: VerticalAlignment = .center, spacing: CGFloat = 10) {
self.alignment = alignment
self.spacing = .init(width: spacing, height: spacing)
}
Expand Down Expand Up @@ -38,6 +38,7 @@ public struct FlowLayout: Layout {
containerWidth: bounds.width,
alignment: alignment
).offsets

for (offset, subview) in zip(offsets, subviews) {
subview.place(at: CGPoint(x: offset.x + bounds.minX, y: offset.y + bounds.minY), proposal: .unspecified)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ public struct BlueTextButtonStyle: ButtonStyle {
configuration.label
.textStyle(.body1StandaloneLink)
.foregroundColor(.app.blue2)
.opacity(configuration.isPressed ? 0.2 : 1)
.opacity(configuration.isPressed ? 0.5 : 1)
}
}
110 changes: 81 additions & 29 deletions RadixWallet/Features/AccountHistory/TransactionFilters+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,21 @@ extension TransactionHistoryFilters {
ScrollView {
WithViewStore(store, observe: \.filters, send: { .view($0) }) { viewStore in
VStack(spacing: .medium3) {
SubSection(filters: viewStore.transferTypes, store: store)
HStack(spacing: .small1) {
FiltersView(filters: viewStore.transferTypes, store: store)

Spacer(minLength: 0)
}

Divider()

if viewStore.showAssetsSection {
Section("Type of asset") { // FIXME: Strings
SubSection("Tokens", filters: viewStore.fungibles, flexible: tokenLabels, store: store)
SubSection("Tokens", filters: viewStore.fungibles, labels: tokenLabels, store: store)

Divider()

SubSection("NFTs", filters: viewStore.nonFungibles, flexible: nftLabels, store: store)
SubSection("NFTs", filters: viewStore.nonFungibles, labels: nftLabels, store: store)
}

Divider()
Expand Down Expand Up @@ -67,11 +71,11 @@ extension TransactionHistoryFilters {
}

private var tokenLabels: SubSection.FlexibleLabels {
.init(showAll: "Show all tokens", showLess: "Show fewer tokens")
.init(showAll: "Show all tokens", showLess: "Show fewer tokens") // FIXME: Strings
}

private var nftLabels: SubSection.FlexibleLabels {
.init(showAll: "Show all NFTs", showLess: "Show fewer NFTs")
.init(showAll: "Show all NFTs", showLess: "Show fewer NFTs") // FIXME: Strings
}

struct Section<Content: SwiftUI.View>: SwiftUI.View {
Expand All @@ -86,19 +90,19 @@ extension TransactionHistoryFilters {

var body: some SwiftUI.View {
VStack(spacing: 0) {
HStack(spacing: .zero) {
Text(name)
.textStyle(.body1Header)
.foregroundStyle(.app.gray1)
.padding(.vertical, .small2)
Button {
withAnimation(.default) {
expanded.toggle()
}
} label: {
HStack(spacing: .zero) {
Text(name)
.textStyle(.body1Header)
.foregroundStyle(.app.gray1)
.padding(.vertical, .small2)

Spacer()
Spacer()

Button {
withAnimation(.default) {
expanded.toggle()
}
} label: {
Image(expanded ? .chevronUp : .chevronDown)
}
}
Expand All @@ -119,16 +123,30 @@ extension TransactionHistoryFilters {
let showLess: String
}

@SwiftUI.State private var showsAll: Bool = false
@SwiftUI.State private var rowHeight: CGFloat = .infinity
@SwiftUI.State private var totalHeight: CGFloat = .infinity
@SwiftUI.State private var isCollapsed: Bool = true

let heading: String?
let filters: IdentifiedArrayOf<State.Filter>
let flexible: FlexibleLabels?
let labels: FlexibleLabels?
let store: StoreOf<TransactionHistoryFilters>

init(_ heading: String? = nil, filters: IdentifiedArrayOf<State.Filter>, flexible: FlexibleLabels? = nil, store: StoreOf<TransactionHistoryFilters>) {
private var showCollapseButton: Bool {
labels != nil && totalHeight > collapsedHeight
}

private var collapsedHeight: CGFloat {
CGFloat(collapsedRowLimit) * rowHeight + CGFloat(collapsedRowLimit - 1) * spacing
}

private let collapsedRowLimit: Int = 2
private let spacing: CGFloat = .small1

init(_ heading: String? = nil, filters: IdentifiedArrayOf<State.Filter>, labels: FlexibleLabels? = nil, store: StoreOf<TransactionHistoryFilters>) {
self.heading = heading
self.filters = filters
self.flexible = flexible
self.labels = labels
self.store = store
}

Expand All @@ -144,25 +162,58 @@ extension TransactionHistoryFilters {
}

HStack(spacing: .zero) {
FlowLayout(spacing: .small1) {
ForEach(filters) { filter in
TransactionFilterView(filter: filter) { id in
store.send(.view(.filterTapped(id)))
}
}
FlowLayout(spacing: spacing) {
FiltersView(filters: filters, store: store)
}
.measureSize(flowLayoutID)
.overlay {
TransactionFilterView.Dummy()
.measureSize(flowDummyID)
}

Spacer(minLength: 0)
}
.frame(maxHeight: isCollapsed ? collapsedHeight : .infinity, alignment: .top)
.clipped()
.onReadSizes(flowDummyID, flowLayoutID) { dummySize, flowSize in
rowHeight = dummySize.height
totalHeight = flowSize.height
}

if let flexible {
Button(showsAll ? "- \(flexible.showLess)" : "+ \(flexible.showAll)") {
showsAll.toggle()
if showCollapseButton, let labels {
Button {
withAnimation {
isCollapsed.toggle()
}
} label: {
ZStack {
Text("+ \(labels.showAll)")
.opacity(isCollapsed ? 1 : 0)
Text("- \(labels.showLess)")
.opacity(isCollapsed ? 0 : 1)
}
}
.buttonStyle(.blueText)
.padding(.top, .medium3)
}
}
.animation(.default, value: isCollapsed)
}
}

private let flowLayoutID = "FlowLayout"
private let flowDummyID = "FlowDummy"
}

private struct FiltersView: SwiftUI.View {
let filters: IdentifiedArrayOf<State.Filter>
let store: StoreOf<TransactionHistoryFilters>

var body: some SwiftUI.View {
ForEach(filters) { filter in
TransactionFilterView(filter: filter) { id in
store.send(.view(.filterTapped(id)))
}
}
}
}
Expand Down Expand Up @@ -227,6 +278,7 @@ struct TransactionFilterView: SwiftUI.View {
var body: some SwiftUI.View {
Text("ABC")
.textStyle(.body1HighImportance)
.foregroundStyle(.clear)
.padding(.vertical, .small2)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public struct TransactionHistory: Sendable, FeatureReducer {
period: range,
filters: filters,
allResources: allResources,
ascending: true,
ascending: false,
cursor: nil
)
let response = try await transactionHistoryClient.getTransactionHistory(request)
Expand Down
37 changes: 37 additions & 0 deletions RadixWallet/Features/AccountHistory/TransactionHistory+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -540,3 +540,40 @@ extension TransactionHistory.State.TransactionSection {
day.formatted(date: .abbreviated, time: .omitted)
}
}

extension View {
public func measureSize(_ id: AnyHashable) -> some View {
background {
GeometryReader { proxy in
Color.clear
.preference(key: PositionsPreferenceKey.self, value: [id: proxy.frame(in: .local)])
}
}
}

public func readSize(_ id: AnyHashable, content: @escaping (CGSize) -> some View) -> some View {
overlayPreferenceValue(PositionsPreferenceKey.self, alignment: .top) { positions in
if let size = positions[id]?.size {
content(size)
} else {
EmptyView()
}
}
}

public func onReadSize(_ id: AnyHashable, content: @escaping (CGSize) -> Void) -> some View {
onPreferenceChange(PositionsPreferenceKey.self) { positions in
if let size = positions[id]?.size {
content(size)
}
}
}

public func onReadSizes(_ id1: AnyHashable, _ id2: AnyHashable, content: @escaping (CGSize, CGSize) -> Void) -> some View {
onPreferenceChange(PositionsPreferenceKey.self) { positions in
if let size1 = positions[id1]?.size, let size2 = positions[id2]?.size {
content(size1, size2)
}
}
}
}

0 comments on commit d88ae65

Please sign in to comment.