forked from shadowfacts/Tusker
parent
2b66f98832
commit
cd9d64410f
|
@ -974,9 +974,9 @@
|
||||||
D641C787213DD862004B4513 /* Compose */,
|
D641C787213DD862004B4513 /* Compose */,
|
||||||
D641C785213DD83B004B4513 /* Conversation */,
|
D641C785213DD83B004B4513 /* Conversation */,
|
||||||
D6F2E960249E772F005846BB /* Crash Reporter */,
|
D6F2E960249E772F005846BB /* Crash Reporter */,
|
||||||
|
D61F759729384D4200C0B37F /* Customize Timelines */,
|
||||||
D627943C23A5635D00D38C68 /* Explore */,
|
D627943C23A5635D00D38C68 /* Explore */,
|
||||||
D6A4DCC92553666600D9DE31 /* Fast Account Switcher */,
|
D6A4DCC92553666600D9DE31 /* Fast Account Switcher */,
|
||||||
D61F759729384D4200C0B37F /* Customize Timelines */,
|
|
||||||
D641C788213DD86D004B4513 /* Large Image */,
|
D641C788213DD86D004B4513 /* Large Image */,
|
||||||
D627944B23A9A02400D38C68 /* Lists */,
|
D627944B23A9A02400D38C68 /* Lists */,
|
||||||
D627944823A6AD5100D38C68 /* Local Predicate Statuses List */,
|
D627944823A6AD5100D38C68 /* Local Predicate Statuses List */,
|
||||||
|
|
|
@ -32,6 +32,7 @@ struct AddHashtagPinnedTimelineView: View {
|
||||||
@State private var searchTask: Task<Void, Never>?
|
@State private var searchTask: Task<Void, Never>?
|
||||||
@State private var isSearching = false
|
@State private var isSearching = false
|
||||||
@State private var searchResults: [String] = []
|
@State private var searchResults: [String] = []
|
||||||
|
@State private var trendingTags: [String] = []
|
||||||
|
|
||||||
private var savedAndFollowedHashtags: [String] {
|
private var savedAndFollowedHashtags: [String] {
|
||||||
var tags = Set<String>()
|
var tags = Set<String>()
|
||||||
|
@ -42,17 +43,19 @@ struct AddHashtagPinnedTimelineView: View {
|
||||||
for followed in mastodonController.followedHashtags {
|
for followed in mastodonController.followedHashtags {
|
||||||
tags.insert(followed.name)
|
tags.insert(followed.name)
|
||||||
}
|
}
|
||||||
return Array(tags).sorted(using: SemiCaseSensitiveComparator())
|
return tags.sorted(using: SemiCaseSensitiveComparator())
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
list
|
list
|
||||||
.listStyle(.grouped)
|
|
||||||
.appGroupedListBackground(container: AddHashtagPinnedTimelineRepresentable.UIViewControllerType.self)
|
.appGroupedListBackground(container: AddHashtagPinnedTimelineRepresentable.UIViewControllerType.self)
|
||||||
|
.listStyle(.grouped)
|
||||||
.navigationTitle("Add Hashtag")
|
.navigationTitle("Add Hashtag")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.searchable(text: $viewModel.searchQuery, placement: .navigationBarDrawer(displayMode: .always), prompt: Text("Search for hashtags"))
|
.searchable(text: $viewModel.searchQuery, placement: .navigationBarDrawer(displayMode: .always), prompt: Text("Search for hashtags"))
|
||||||
|
.autocorrectionDisabled()
|
||||||
|
.textInputAutocapitalization(.never)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .cancellationAction) {
|
ToolbarItem(placement: .cancellationAction) {
|
||||||
Button("Cancel") {
|
Button("Cancel") {
|
||||||
|
@ -71,35 +74,45 @@ struct AddHashtagPinnedTimelineView: View {
|
||||||
try? await updateSearchResults()
|
try? await updateSearchResults()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.task {
|
||||||
|
await fetchTrendingTags()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
|
||||||
private var list: some View {
|
private var list: some View {
|
||||||
let list = List {
|
List {
|
||||||
Section {
|
if !viewModel.searchQuery.isEmpty {
|
||||||
if viewModel.searchQuery.isEmpty {
|
Section {
|
||||||
forEachTag(savedAndFollowedHashtags)
|
|
||||||
} else {
|
|
||||||
forEachTag(searchResults)
|
|
||||||
}
|
|
||||||
} header: {
|
|
||||||
ProgressView()
|
ProgressView()
|
||||||
.progressViewStyle(.circular)
|
.progressViewStyle(.circular)
|
||||||
.opacity(isSearching ? 1 : 0)
|
.opacity(isSearching ? 1 : 0)
|
||||||
|
.animation(.linear(duration: 0.1), value: isSearching)
|
||||||
.frame(maxWidth: .infinity, alignment: .center)
|
.frame(maxWidth: .infinity, alignment: .center)
|
||||||
.listRowBackground(EmptyView())
|
.listRowBackground(EmptyView())
|
||||||
.listRowSeparator(.hidden)
|
.listRowSeparator(.hidden)
|
||||||
|
|
||||||
|
forEachTag(searchResults)
|
||||||
|
}
|
||||||
|
.appGroupedListRowBackground()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !savedAndFollowedHashtags.isEmpty {
|
||||||
|
Section {
|
||||||
|
forEachTag(savedAndFollowedHashtags)
|
||||||
|
} header: {
|
||||||
|
Text("Saved and Followed Hashtags")
|
||||||
|
}
|
||||||
|
.appGroupedListRowBackground()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !trendingTags.isEmpty {
|
||||||
|
Section {
|
||||||
|
forEachTag(trendingTags)
|
||||||
|
} header: {
|
||||||
|
Text("Trending Hashtags")
|
||||||
|
}
|
||||||
|
.appGroupedListRowBackground()
|
||||||
}
|
}
|
||||||
.appGroupedListRowBackground()
|
|
||||||
}
|
|
||||||
.listStyle(.grouped)
|
|
||||||
|
|
||||||
if #available(iOS 16.0, *) {
|
|
||||||
list
|
|
||||||
.scrollContentBackground(.hidden)
|
|
||||||
.background(Color.appGroupedBackground)
|
|
||||||
} else {
|
|
||||||
list
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +139,14 @@ struct AddHashtagPinnedTimelineView: View {
|
||||||
searchResults = results.hashtags.map(\.name)
|
searchResults = results.hashtags.map(\.name)
|
||||||
isSearching = false
|
isSearching = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func fetchTrendingTags() async {
|
||||||
|
guard mastodonController.instanceFeatures.trends else { return }
|
||||||
|
let req = Client.getTrendingHashtags()
|
||||||
|
if let (results, _) = try? await mastodonController.run(req) {
|
||||||
|
trendingTags = results.map(\.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SearchViewModel: ObservableObject {
|
private class SearchViewModel: ObservableObject {
|
||||||
|
|
|
@ -89,7 +89,7 @@ struct CustomizeTimelinesList: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listStyle(.insetGrouped)
|
.listStyle(.insetGrouped)
|
||||||
.appGroupedListBackground(container: UIHostingController<CustomizeTimelinesList>.self)
|
.appGroupedListBackground(container: UIHostingController<CustomizeTimelinesView>.self)
|
||||||
.navigationTitle(Text("Customize Timelines"))
|
.navigationTitle(Text("Customize Timelines"))
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
|
|
Loading…
Reference in New Issue