diff --git a/swiftchan/Views/Boards/Catalog/Thread/PostView.swift b/swiftchan/Views/Boards/Catalog/Thread/PostView.swift index df7d201..427686f 100644 --- a/swiftchan/Views/Boards/Catalog/Thread/PostView.swift +++ b/swiftchan/Views/Boards/Catalog/Thread/PostView.swift @@ -94,6 +94,7 @@ struct PostView: View { } if let id = post.pid { let color = Color.randomColor(seed: id) + let isFiltered = viewModel.searchFilters.posterID == id Text(id.description) .foregroundColor(Color.isRandomColorLight(seed: id) ? .black : .white) .background( @@ -102,7 +103,20 @@ struct PostView: View { .cornerRadius(5) .padding(.horizontal, -5) ) + .overlay( + RoundedRectangle(cornerRadius: 5) + .stroke(Color.accentColor, lineWidth: isFiltered ? 2 : 0) + .padding(.horizontal, -5) + ) .offset(x: 5) + .onTapGesture { + UIImpactFeedbackGenerator(style: .light).impactOccurred() + if viewModel.searchFilters.posterID == id { + viewModel.searchFilters.posterID = nil + } else { + viewModel.searchFilters.posterID = id + } + } } // Anonymous diff --git a/swiftchan/Views/Boards/Catalog/Thread/ThreadView.swift b/swiftchan/Views/Boards/Catalog/Thread/ThreadView.swift index e6c8227..6777f79 100644 --- a/swiftchan/Views/Boards/Catalog/Thread/ThreadView.swift +++ b/swiftchan/Views/Boards/Catalog/Thread/ThreadView.swift @@ -106,6 +106,8 @@ struct ThreadView: View { .overlay(alignment: .bottom) { if isSearching && !viewModel.searchResultIndices.isEmpty { searchToolbar + } else if viewModel.searchFilters.posterID != nil { + posterIDFilterBanner } } .overlay { @@ -305,6 +307,16 @@ struct ThreadView: View { viewModel.searchFilters.hasReplies.toggle() } ) + + if let posterID = viewModel.searchFilters.posterID { + FilterChip( + label: "ID: \(posterID)", + isSelected: true, + action: { + viewModel.searchFilters.posterID = nil + } + ) + } } .padding(.horizontal) } @@ -338,6 +350,39 @@ struct ThreadView: View { .background(.regularMaterial) } + @ViewBuilder + var posterIDFilterBanner: some View { + if let posterID = viewModel.searchFilters.posterID { + HStack { + let color = Color.randomColor(seed: posterID) + Text("Showing posts by") + .font(.subheadline) + .foregroundColor(.secondary) + Text(posterID) + .font(.subheadline) + .bold() + .foregroundColor(Color.isRandomColorLight(seed: posterID) ? .black : .white) + .padding(.horizontal, 8) + .padding(.vertical, 2) + .background(color) + .cornerRadius(5) + Text("(\(viewModel.searchResultIndices.count))") + .font(.subheadline) + .foregroundColor(.secondary) + Spacer() + Button { + viewModel.searchFilters.posterID = nil + } label: { + Image(systemName: "xmark.circle.fill") + .foregroundColor(.secondary) + } + } + .padding(.horizontal) + .padding(.vertical, 8) + .background(.regularMaterial) + } + } + private func fetchAndPrefetchMedia(auto: Bool = false) async { let hadPosts = !viewModel.posts.isEmpty await viewModel.getPosts()