damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit 846a786fd02f17bbbe428a55eefabf474b4a4a9e
parent 517f3714e891c286ea7c8f15e0522b33f431d65a
Author: ericholguin <ericholguin@apache.org>
Date:   Tue, 26 Mar 2024 20:43:58 -0600

ux: fix image indicators

Changelog-Fixed: Fix image indicators to limit number of dots to not spill screen beyond visible margins
Closes: https://github.com/damus-io/damus/issues/1227
Closes: https://github.com/damus-io/damus/issues/1295
Signed-off-by: ericholguin <ericholguin@apache.org>
Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mdamus/Components/ImageCarousel.swift | 72+++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Mdamus/Views/Images/FullScreenCarouselView.swift | 21++++-----------------
2 files changed, 51 insertions(+), 42 deletions(-)

diff --git a/damus/Components/ImageCarousel.swift b/damus/Components/ImageCarousel.swift @@ -31,6 +31,49 @@ struct ShareSheet: UIViewControllerRepresentable { } } +// Custom UIPageControl +struct PageControlView: UIViewRepresentable { + @Binding var currentPage: Int + var numberOfPages: Int + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + func makeUIView(context: Context) -> UIPageControl { + let uiView = UIPageControl() + uiView.backgroundStyle = .minimal + uiView.currentPageIndicatorTintColor = UIColor(Color("DamusPurple")) + uiView.pageIndicatorTintColor = UIColor(Color("DamusLightGrey")) + uiView.currentPage = currentPage + uiView.numberOfPages = numberOfPages + uiView.addTarget(context.coordinator, action: #selector(Coordinator.valueChanged), for: .valueChanged) + return uiView + } + + func updateUIView(_ uiView: UIPageControl, context: Context) { + uiView.currentPage = currentPage + uiView.numberOfPages = numberOfPages + } +} + +extension PageControlView { + final class Coordinator: NSObject { + var parent: PageControlView + + init(_ parent: PageControlView) { + self.parent = parent + } + + @objc func valueChanged(sender: UIPageControl) { + let currentPage = sender.currentPage + withAnimation { + parent.currentPage = currentPage + } + } + } +} + enum ImageShape { case square @@ -227,7 +270,6 @@ struct ImageCarousel<Content: View>: View { .onChange(of: model.selectedIndex) { value in model.selectedIndex = value } - .tabViewStyle(PageTabViewStyle()) } var body: some View { @@ -235,31 +277,11 @@ struct ImageCarousel<Content: View>: View { Medias .onTapGesture { } - // This is our custom carousel image indicator - CarouselDotsView(urls: urls, selectedIndex: $model.selectedIndex) - } - } -} - -// MARK: - Custom Carousel -struct CarouselDotsView<T>: View { - let urls: [T] - @Binding var selectedIndex: Int - - var body: some View { - if urls.count > 1 { - HStack { - ForEach(urls.indices, id: \.self) { index in - Circle() - .fill(index == selectedIndex ? Color("DamusPurple") : Color("DamusLightGrey")) - .frame(width: 10, height: 10) - .onTapGesture { - selectedIndex = index - } - } + if urls.count > 1 { + PageControlView(currentPage: $model.selectedIndex, numberOfPages: urls.count) + .frame(maxWidth: 0, maxHeight: 0) + .padding(.top, 5) } - .padding(.top, CGFloat(8)) - .id(UUID()) } } } diff --git a/damus/Views/Images/FullScreenCarouselView.swift b/damus/Views/Images/FullScreenCarouselView.swift @@ -37,21 +37,6 @@ struct FullScreenCarouselView<Content: View>: View { self.content = nil } - var tabViewIndicator: some View { - HStack(spacing: 10) { - ForEach(urls.indices, id: \.self) { index in - Capsule() - .fill(index == selectedIndex ? Color.white : Color.damusMediumGrey) - .frame(width: 7, height: 7) - .onTapGesture { - selectedIndex = index - } - } - } - .padding() - .clipShape(Capsule()) - } - var background: some ShapeStyle { if case .video = urls[safe: selectedIndex] { return AnyShapeStyle(Color.black) @@ -115,8 +100,10 @@ struct FullScreenCarouselView<Content: View>: View { .foregroundColor(.white) Spacer() - if (urls.count > 1) { - tabViewIndicator + if urls.count > 1 { + PageControlView(currentPage: $selectedIndex, numberOfPages: urls.count) + .frame(maxWidth: 0, maxHeight: 0) + .padding(.top, 5) } self.content?()