Revert "Switch to using LazyVStack for the Timeline"
This reverts commit 9878ca4b17
.
This commit is contained in:
parent
9878ca4b17
commit
6b08b1e48b
|
@ -17,6 +17,13 @@ struct TimelineItemView: View {
|
||||||
var width: CGFloat
|
var width: CGFloat
|
||||||
var timelineItem: TimelineItem
|
var timelineItem: TimelineItem
|
||||||
|
|
||||||
|
#if os(macOS)
|
||||||
|
var verticalPadding: CGFloat = 10
|
||||||
|
#endif
|
||||||
|
#if os(iOS)
|
||||||
|
var verticalPadding: CGFloat = 0
|
||||||
|
#endif
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(alignment: .top) {
|
HStack(alignment: .top) {
|
||||||
TimelineItemStatusView(selected: selected, status: timelineItem.status)
|
TimelineItemStatusView(selected: selected, status: timelineItem.status)
|
||||||
|
@ -58,8 +65,7 @@ struct TimelineItemView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.vertical, 10)
|
.padding(.vertical, verticalPadding)
|
||||||
.padding(.horizontal)
|
|
||||||
.onAppear {
|
.onAppear {
|
||||||
articleIconImageLoader.loadImage(for: timelineItem.article)
|
articleIconImageLoader.loadImage(for: timelineItem.article)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ struct TimelineView: View {
|
||||||
|
|
||||||
@EnvironmentObject private var timelineModel: TimelineModel
|
@EnvironmentObject private var timelineModel: TimelineModel
|
||||||
|
|
||||||
@State private var navigate = false
|
|
||||||
@State private var timelineItemFrames = [String: CGRect]()
|
@State private var timelineItemFrames = [String: CGRect]()
|
||||||
|
|
||||||
@ViewBuilder var body: some View {
|
@ViewBuilder var body: some View {
|
||||||
|
@ -41,31 +40,24 @@ struct TimelineView: View {
|
||||||
.buttonStyle(PlainButtonStyle())
|
.buttonStyle(PlainButtonStyle())
|
||||||
.help(isReadFiltered ?? false ? "Show Read Articles" : "Filter Read Articles")
|
.help(isReadFiltered ?? false ? "Show Read Articles" : "Filter Read Articles")
|
||||||
}
|
}
|
||||||
ScrollView {
|
ScrollViewReader { scrollViewProxy in
|
||||||
ScrollViewReader { scrollViewProxy in
|
List(timelineItems.items, selection: $timelineModel.selectedTimelineItemIDs) { timelineItem in
|
||||||
LazyVStack {
|
let selected = timelineModel.selectedTimelineItemIDs.contains(timelineItem.article.articleID)
|
||||||
ForEach(timelineItems.items) { timelineItem in
|
TimelineItemView(selected: selected, width: geometryReaderProxy.size.width, timelineItem: timelineItem)
|
||||||
let selected = timelineModel.selectedTimelineItemIDs.contains(timelineItem.article.articleID)
|
.background(TimelineItemFramePreferenceView(timelineItem: timelineItem))
|
||||||
TimelineItemView(selected: selected, width: geometryReaderProxy.size.width, timelineItem: timelineItem)
|
}
|
||||||
.background(TimelineItemBackgroundView(selected: selected, timelineItem: timelineItem))
|
.onPreferenceChange(TimelineItemFramePreferenceKey.self) { preferences in
|
||||||
.onTapGesture {
|
for pref in preferences {
|
||||||
timelineModel.selectedTimelineItemIDs = Set([timelineItem.id])
|
timelineItemFrames[pref.articleID] = pref.frame
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onPreferenceChange(TimelineItemFramePreferenceKey.self) { preferences in
|
.onChange(of: timelineModel.selectedTimelineItemIDs) { selectedArticleIDs in
|
||||||
for pref in preferences {
|
let proxyFrame = geometryReaderProxy.frame(in: .global)
|
||||||
timelineItemFrames[pref.articleID] = pref.frame
|
for articleID in selectedArticleIDs {
|
||||||
}
|
if let itemFrame = timelineItemFrames[articleID] {
|
||||||
}
|
if itemFrame.minY < proxyFrame.minY + 3 || itemFrame.maxY > proxyFrame.maxY - 35 {
|
||||||
.onChange(of: timelineModel.selectedTimelineItemIDs) { selectedArticleIDs in
|
withAnimation {
|
||||||
let proxyFrame = geometryReaderProxy.frame(in: .global)
|
scrollViewProxy.scrollTo(articleID, anchor: .center)
|
||||||
for articleID in selectedArticleIDs {
|
|
||||||
if let itemFrame = timelineItemFrames[articleID] {
|
|
||||||
if itemFrame.minY < proxyFrame.minY + 3 || itemFrame.maxY > proxyFrame.maxY - 35 {
|
|
||||||
withAnimation {
|
|
||||||
scrollViewProxy.scrollTo(articleID, anchor: .center)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,36 +67,30 @@ struct TimelineView: View {
|
||||||
}
|
}
|
||||||
.navigationTitle(Text(verbatim: timelineModel.nameForDisplay))
|
.navigationTitle(Text(verbatim: timelineModel.nameForDisplay))
|
||||||
#else
|
#else
|
||||||
ZStack {
|
ScrollViewReader { scrollViewProxy in
|
||||||
NavigationLink(destination: ArticleView(), isActive: $navigate) {
|
List(timelineItems.items) { timelineItem in
|
||||||
EmptyView()
|
ZStack {
|
||||||
|
let selected = timelineModel.selectedTimelineItemID == timelineItem.article.articleID
|
||||||
|
TimelineItemView(selected: selected, width: geometryReaderProxy.size.width, timelineItem: timelineItem)
|
||||||
|
.background(TimelineItemFramePreferenceView(timelineItem: timelineItem))
|
||||||
|
NavigationLink(destination: ArticleContainerView(),
|
||||||
|
tag: timelineItem.article.articleID,
|
||||||
|
selection: $timelineModel.selectedTimelineItemID) {
|
||||||
|
EmptyView()
|
||||||
|
}.buttonStyle(PlainButtonStyle())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ScrollView {
|
.onPreferenceChange(TimelineItemFramePreferenceKey.self) { preferences in
|
||||||
ScrollViewReader { scrollViewProxy in
|
for pref in preferences {
|
||||||
LazyVStack {
|
timelineItemFrames[pref.articleID] = pref.frame
|
||||||
ForEach(timelineItems.items) { timelineItem in
|
}
|
||||||
let selected = timelineModel.selectedTimelineItemID == timelineItem.article.articleID
|
}
|
||||||
TimelineItemView(selected: selected, width: geometryReaderProxy.size.width, timelineItem: timelineItem)
|
.onChange(of: timelineModel.selectedTimelineItemID) { selectedArticleID in
|
||||||
.background(TimelineItemBackgroundView(selected: selected, timelineItem: timelineItem))
|
let proxyFrame = geometryReaderProxy.frame(in: .global)
|
||||||
.onTapGesture {
|
if let articleID = selectedArticleID, let itemFrame = timelineItemFrames[articleID] {
|
||||||
timelineModel.selectedTimelineItemIDs = Set([timelineItem.id])
|
if itemFrame.minY < proxyFrame.minY + 3 || itemFrame.maxY > proxyFrame.maxY - 3 {
|
||||||
navigate = true
|
withAnimation {
|
||||||
}
|
scrollViewProxy.scrollTo(articleID, anchor: .center)
|
||||||
}
|
|
||||||
}
|
|
||||||
.onPreferenceChange(TimelineItemFramePreferenceKey.self) { preferences in
|
|
||||||
for pref in preferences {
|
|
||||||
timelineItemFrames[pref.articleID] = pref.frame
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: timelineModel.selectedTimelineItemID) { selectedArticleID in
|
|
||||||
let proxyFrame = geometryReaderProxy.frame(in: .global)
|
|
||||||
if let articleID = selectedArticleID, let itemFrame = timelineItemFrames[articleID] {
|
|
||||||
if itemFrame.minY < proxyFrame.minY + 3 || itemFrame.maxY > proxyFrame.maxY - 3 {
|
|
||||||
withAnimation {
|
|
||||||
scrollViewProxy.scrollTo(articleID, anchor: .center)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,16 +118,13 @@ struct TimelineItemFramePreference: Equatable {
|
||||||
let frame: CGRect
|
let frame: CGRect
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TimelineItemBackgroundView: View {
|
struct TimelineItemFramePreferenceView: View {
|
||||||
|
|
||||||
let selected: Bool
|
|
||||||
let timelineItem: TimelineItem
|
let timelineItem: TimelineItem
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
GeometryReader { proxy in
|
GeometryReader { proxy in
|
||||||
Rectangle()
|
Rectangle()
|
||||||
.fill(selected ? Color.accentColor : Color.clear)
|
.fill(Color.clear)
|
||||||
.cornerRadius(6)
|
|
||||||
.preference(key: TimelineItemFramePreferenceKey.self,
|
.preference(key: TimelineItemFramePreferenceKey.self,
|
||||||
value: [TimelineItemFramePreference(articleID: timelineItem.article.articleID, frame: proxy.frame(in: .global))])
|
value: [TimelineItemFramePreference(articleID: timelineItem.article.articleID, frame: proxy.frame(in: .global))])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue