Add load more content button to the top bar

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
Daniel D’Aquino
2025-09-05 17:55:08 -07:00
parent 9bcee298d4
commit 2bea2faf3f
3 changed files with 65 additions and 61 deletions

View File

@@ -174,7 +174,7 @@ struct ContentView: View {
} }
case .home: case .home:
PostingTimelineView(damus_state: damus_state!, home: home, isSideBarOpened: $isSideBarOpened, active_sheet: $active_sheet, headerOffset: $headerOffset) PostingTimelineView(damus_state: damus_state!, home: home, homeEvents: home.events, isSideBarOpened: $isSideBarOpened, active_sheet: $active_sheet, headerOffset: $headerOffset)
case .notifications: case .notifications:
NotificationsView(state: damus, notifications: home.notifications, subtitle: $menu_subtitle) NotificationsView(state: damus, notifications: home.notifications, subtitle: $menu_subtitle)

View File

@@ -29,26 +29,6 @@ struct InnerTimelineView: View {
var body: some View { var body: some View {
LazyVStack(spacing: 0) { LazyVStack(spacing: 0) {
let incomingEvents = events.incoming.filter({ filter($0) })
if incomingEvents.count > 0 {
Button(
action: {
notify(.scroll_to_top)
},
label: {
HStack(spacing: 6) {
CondensedProfilePicturesView(state: state, pubkeys: incomingEvents.map({ $0.pubkey }), maxPictures: 3)
Text("Load new content", comment: "Button to load new notes in the timeline")
.bold()
}
.padding(.horizontal, 20)
.padding(.vertical, 10)
}
)
.buttonStyle(NeutralButtonStyle(cornerRadius: 50))
.padding(.vertical, 10)
}
let events = self.events.events let events = self.events.events
if events.isEmpty { if events.isEmpty {
EmptyTimelineView() EmptyTimelineView()

View File

@@ -11,6 +11,8 @@ struct PostingTimelineView: View {
let damus_state: DamusState let damus_state: DamusState
@ObservedObject var home: HomeModel @ObservedObject var home: HomeModel
/// Set this to `home.events`. This is separate from `home` because we need the events object to be directly observed so that we get instant view updates
@ObservedObject var homeEvents: EventHolder
@State var search: String = "" @State var search: String = ""
@State var results: [NostrEvent] = [] @State var results: [NostrEvent] = []
@State var initialOffset: CGFloat? @State var initialOffset: CGFloat?
@@ -44,53 +46,75 @@ struct PostingTimelineView: View {
TimelineView<AnyView>(events: home.events, loading: self.loading, headerHeight: $headerHeight, headerOffset: $headerOffset, damus: damus_state, show_friend_icon: false, filter: filter) TimelineView<AnyView>(events: home.events, loading: self.loading, headerHeight: $headerHeight, headerOffset: $headerOffset, damus: damus_state, show_friend_icon: false, filter: filter)
} }
func HeaderView()->some View { func HeaderView() -> some View {
VStack { VStack {
VStack(spacing: 0) { VStack {
// This is needed for the Dynamic Island VStack(spacing: 0) {
HStack {} // This is needed for the Dynamic Island
.frame(height: getSafeAreaTop()) HStack {}
.frame(height: getSafeAreaTop())
HStack(alignment: .top) { HStack(alignment: .top) {
TopbarSideMenuButton(damus_state: damus_state, isSideBarOpened: $isSideBarOpened) TopbarSideMenuButton(damus_state: damus_state, isSideBarOpened: $isSideBarOpened)
Spacer() Spacer()
Image("damus-home") Image("damus-home")
.resizable() .resizable()
.frame(width:30,height:30) .frame(width:30,height:30)
.shadow(color: DamusColors.purple, radius: 2) .shadow(color: DamusColors.purple, radius: 2)
.opacity(isSideBarOpened ? 0 : 1) .opacity(isSideBarOpened ? 0 : 1)
.animation(isSideBarOpened ? .none : .default, value: isSideBarOpened) .animation(isSideBarOpened ? .none : .default, value: isSideBarOpened)
.onTapGesture { .onTapGesture {
isSideBarOpened.toggle() isSideBarOpened.toggle()
}
.padding(.leading)
Spacer()
HStack(alignment: .center) {
SignalView(state: damus_state, signal: home.signal)
} }
.padding(.leading)
Spacer()
HStack(alignment: .center) {
SignalView(state: damus_state, signal: home.signal)
} }
.frame(maxWidth: .infinity, alignment: .trailing)
} }
.frame(maxWidth: .infinity, alignment: .trailing) .padding(.horizontal, 20)
}
.padding(.horizontal, 20)
VStack(spacing: 0) { VStack(spacing: 0) {
CustomPicker(tabs: [ CustomPicker(tabs: [
(NSLocalizedString("Notes", comment: "Label for filter for seeing only notes (instead of notes and replies)."), FilterState.posts), (NSLocalizedString("Notes", comment: "Label for filter for seeing only notes (instead of notes and replies)."), FilterState.posts),
(NSLocalizedString("Notes & Replies", comment: "Label for filter for seeing notes and replies (instead of only notes)."), FilterState.posts_and_replies) (NSLocalizedString("Notes & Replies", comment: "Label for filter for seeing notes and replies (instead of only notes)."), FilterState.posts_and_replies)
], ],
selection: $filter_state) selection: $filter_state)
Divider() Divider()
.frame(height: 1) .frame(height: 1)
}
}
.background {
DamusColors.adaptableWhite
.ignoresSafeArea()
}
if homeEvents.incoming.count > 0 {
Button(
action: {
notify(.scroll_to_top)
},
label: {
HStack(spacing: 6) {
CondensedProfilePicturesView(state: damus_state, pubkeys: homeEvents.incoming.map({ $0.pubkey }), maxPictures: 3)
.scaleEffect(0.75)
Text("Load new content", comment: "Button to load new notes in the timeline")
.bold()
}
.padding(.horizontal, 10)
.padding(.vertical, 5)
}
)
.buttonStyle(NeutralButtonStyle(cornerRadius: 50))
.padding(.vertical, 10)
} }
}
.background {
DamusColors.adaptableWhite
.ignoresSafeArea()
} }
} }