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:
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?()