Add pull to refresh for Subscriptions, Popular and Trending (fixes #31)

This commit is contained in:
Arkadiusz Fal
2022-01-05 17:25:57 +01:00
parent 1db4a3197d
commit 363424fa74
13 changed files with 527 additions and 67 deletions

View File

@@ -27,11 +27,17 @@ struct FavoritesView: View {
FavoriteItemView(item: item, dragging: $dragging)
}
#else
#if os(iOS)
let first = favorites.first
#endif
ForEach(favorites) { item in
FavoriteItemView(item: item, dragging: $dragging)
#if os(macOS)
.workaroundForVerticalScrollingBug()
#endif
#if os(iOS)
.padding(.top, item == first && RefreshControl.navigationBarTitleDisplayMode == .inline ? 10 : 0)
#endif
}
#endif
}
@@ -54,6 +60,9 @@ struct FavoritesView: View {
.background(Color.secondaryBackground)
.frame(minWidth: 360)
#endif
#if os(iOS)
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
#endif
}
}
}

View File

@@ -127,6 +127,9 @@ struct PlaylistsView: View {
.onChange(of: accounts.current) { _ in
model.load(force: true)
}
#if os(iOS)
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
#endif
}
#if os(tvOS)

View File

@@ -48,6 +48,69 @@ struct TrendingView: View {
}
}
}
.toolbar {
#if os(macOS)
ToolbarItemGroup {
if let favoriteItem = favoriteItem {
FavoriteButton(item: favoriteItem)
.id(favoriteItem.id)
}
if accounts.app.supportsTrendingCategories {
categoryButton
}
countryButton
}
#elseif os(iOS)
ToolbarItemGroup(placement: .bottomBar) {
Group {
if accounts.app.supportsTrendingCategories {
HStack {
Text("Category")
.foregroundColor(.secondary)
categoryButton
// only way to disable Menu animation is to
// force redraw of the view when it changes
.id(UUID())
}
Spacer()
}
if let favoriteItem = favoriteItem {
FavoriteButton(item: favoriteItem)
.id(favoriteItem.id)
Spacer()
}
HStack {
Text("Country")
.foregroundColor(.secondary)
countryButton
}
}
}
#endif
}
.onChange(of: resource) { _ in
resource.load()
updateFavoriteItem()
}
.onAppear {
if videos.isEmpty {
resource.addObserver(store)
resource.loadIfNeeded()
} else {
store.replace(videos)
}
updateFavoriteItem()
}
#if os(tvOS)
.fullScreenCover(isPresented: $presentingCountrySelection) {
TrendingCountry(selectedCountry: $country)
@@ -61,67 +124,14 @@ struct TrendingView: View {
}
.navigationTitle("Trending")
#endif
.toolbar {
#if os(macOS)
ToolbarItemGroup {
if let favoriteItem = favoriteItem {
FavoriteButton(item: favoriteItem)
.id(favoriteItem.id)
}
if accounts.app.supportsTrendingCategories {
categoryButton
}
countryButton
}
#elseif os(iOS)
ToolbarItemGroup(placement: .bottomBar) {
Group {
HStack {
if accounts.app.supportsTrendingCategories {
Text("Category")
.foregroundColor(.secondary)
categoryButton
// only way to disable Menu animation is to
// force redraw of the view when it changes
.id(UUID())
}
}
Spacer()
if let favoriteItem = favoriteItem {
FavoriteButton(item: favoriteItem)
.id(favoriteItem.id)
Spacer()
}
HStack {
Text("Country")
.foregroundColor(.secondary)
countryButton
}
}
}
#endif
}
.onChange(of: resource) { _ in
resource.load()
updateFavoriteItem()
}
.onAppear {
if videos.isEmpty {
resource.addObserver(store)
resource.loadIfNeeded()
} else {
store.replace(videos)
}
updateFavoriteItem()
}
#if os(iOS)
.refreshControl { refreshControl in
resource.load().onCompletion { _ in
refreshControl.endRefreshing()
}
}
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
#endif
}
#if os(tvOS)

View File

@@ -30,5 +30,13 @@ struct PopularView: View {
FavoriteButton(item: FavoriteItem(section: .popular))
}
}
#if os(iOS)
.refreshControl { refreshControl in
resource?.load().onCompletion { _ in
refreshControl.endRefreshing()
}
}
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
#endif
}
}

View File

@@ -24,6 +24,13 @@ struct SubscriptionsView: View {
.onChange(of: accounts.current) { _ in
loadResources(force: true)
}
#if os(iOS)
.refreshControl { refreshControl in
loadResources(force: true) {
refreshControl.endRefreshing()
}
}
#endif
}
}
.toolbar {
@@ -31,26 +38,35 @@ struct SubscriptionsView: View {
FavoriteButton(item: FavoriteItem(section: .subscriptions))
}
}
#if os(iOS)
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
#endif
}
fileprivate func loadResources(force: Bool = false) {
private func loadResources(force: Bool = false, onCompletion: @escaping () -> Void = {}) {
feed?.addObserver(store)
if accounts.app == .invidious {
// Invidious for some reason won't refresh feed until homepage is loaded
if let request = force ? accounts.api.home?.load() : accounts.api.home?.loadIfNeeded() {
request.onSuccess { _ in
loadFeed(force: force)
loadFeed(force: force, onCompletion: onCompletion)
}
} else {
loadFeed(force: force)
loadFeed(force: force, onCompletion: onCompletion)
}
} else {
loadFeed(force: force)
loadFeed(force: force, onCompletion: onCompletion)
}
}
fileprivate func loadFeed(force: Bool = false) {
_ = force ? feed?.load() : feed?.loadIfNeeded()
private func loadFeed(force: Bool = false, onCompletion: @escaping () -> Void = {}) {
if let request = force ? feed?.load() : feed?.loadIfNeeded() {
request.onCompletion { _ in
onCompletion()
}
} else {
onCompletion()
}
}
}