mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-04-08 01:39:52 +00:00
Implement basic tap-to-collapse
This commit is contained in:
parent
2d251a5b6d
commit
ec5bc5c1bb
6 changed files with 56 additions and 3 deletions
|
@ -113,12 +113,15 @@ public struct StatusDetailView: View {
|
|||
.navigationBarTitleDisplayMode(.inline)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func makeStatusesListView(statuses: [Status]) -> some View {
|
||||
ForEach(statuses) { status in
|
||||
let collapsedIds = viewModel.hierarchyCollapseState.implicitlyCollapsedStatusIds(for: statuses)
|
||||
ForEach(statuses.filter { !collapsedIds.contains($0.id) }) { status in
|
||||
let (indentationLevel, extraInsets) = viewModel.getIndentationLevel(id: status.id, maxIndent: userPreferences.getRealMaxIndent())
|
||||
let viewModel: StatusRowViewModel = .init(status: status,
|
||||
client: client,
|
||||
routerPath: routerPath,
|
||||
hierarchyCollapseState: viewModel.hierarchyCollapseState,
|
||||
scrollToId: $viewModel.scrollToId)
|
||||
let isFocused = self.viewModel.statusId == status.id
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ import SwiftUI
|
|||
|
||||
var client: Client?
|
||||
var routerPath: RouterPath?
|
||||
|
||||
let hierarchyCollapseState = StatusHierarchyCollapseState()
|
||||
|
||||
enum State {
|
||||
case loading, display(statuses: [Status]), error(error: Error)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import Observation
|
||||
import Models
|
||||
|
||||
@MainActor
|
||||
@Observable public class StatusHierarchyCollapseState {
|
||||
public var explicitlyCollapsedStatusIds: Set<String>
|
||||
|
||||
public init(explicitlyCollapsedStatusIds: Set<String> = []) {
|
||||
self.explicitlyCollapsedStatusIds = explicitlyCollapsedStatusIds
|
||||
}
|
||||
|
||||
public func implicitlyCollapsedStatusIds(for statuses: [Status]) -> Set<String> {
|
||||
let childs: [String: [String]] = Dictionary(
|
||||
grouping: statuses.filter { $0.inReplyToId != nil },
|
||||
by: { $0.inReplyToId! }
|
||||
).mapValues { $0.map(\.id) }
|
||||
|
||||
func descendants(for id: String) -> [String] {
|
||||
(childs[id] ?? []).flatMap { [$0] + descendants(for: $0) }
|
||||
}
|
||||
|
||||
return Set(explicitlyCollapsedStatusIds.flatMap(descendants(for:)))
|
||||
}
|
||||
}
|
|
@ -29,7 +29,9 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
|
|||
switch fetcher.statusesState {
|
||||
case .loading:
|
||||
ForEach(Status.placeholders()) { status in
|
||||
StatusRowView(viewModel: .init(status: status, client: client, routerPath: routerPath),
|
||||
StatusRowView(viewModel: .init(status: status,
|
||||
client: client,
|
||||
routerPath: routerPath),
|
||||
context: .timeline)
|
||||
.redacted(reason: .placeholder)
|
||||
.allowsHitTesting(false)
|
||||
|
|
|
@ -348,7 +348,11 @@ public struct StatusRowView: View {
|
|||
|
||||
private func handleTap() {
|
||||
guard !isFocused else { return }
|
||||
viewModel.navigateToDetail()
|
||||
if indentationLevel > 0, viewModel.hierarchyCollapseState != nil {
|
||||
viewModel.isHierarchyExplicitlyCollapsed.toggle()
|
||||
} else {
|
||||
viewModel.navigateToDetail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ import SwiftUI
|
|||
|
||||
let client: Client
|
||||
let routerPath: RouterPath
|
||||
|
||||
let hierarchyCollapseState: StatusHierarchyCollapseState?
|
||||
|
||||
let userFollowedTag: HTMLString.Link?
|
||||
|
||||
|
@ -67,6 +69,20 @@ import SwiftUI
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// toggled on tap, collapses the post with its hierarchy of replies
|
||||
var isHierarchyExplicitlyCollapsed: Bool {
|
||||
get {
|
||||
hierarchyCollapseState?.explicitlyCollapsedStatusIds.contains(status.id) ?? false
|
||||
}
|
||||
set {
|
||||
if newValue {
|
||||
hierarchyCollapseState?.explicitlyCollapsedStatusIds.insert(status.id)
|
||||
} else {
|
||||
hierarchyCollapseState?.explicitlyCollapsedStatusIds.remove(status.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// used by the button to expand a collapsed post
|
||||
var isCollapsed: Bool = true {
|
||||
|
@ -162,6 +178,7 @@ import SwiftUI
|
|||
public init(status: Status,
|
||||
client: Client,
|
||||
routerPath: RouterPath,
|
||||
hierarchyCollapseState: StatusHierarchyCollapseState? = nil,
|
||||
isRemote: Bool = false,
|
||||
showActions: Bool = true,
|
||||
textDisabled: Bool = false,
|
||||
|
@ -171,6 +188,7 @@ import SwiftUI
|
|||
finalStatus = status.reblog ?? status
|
||||
self.client = client
|
||||
self.routerPath = routerPath
|
||||
self.hierarchyCollapseState = hierarchyCollapseState
|
||||
self.isRemote = isRemote
|
||||
self.showActions = showActions
|
||||
self.textDisabled = textDisabled
|
||||
|
|
Loading…
Reference in a new issue