zkit-ui 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +1 -1
  2. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GalleryLayoutSupport.java → NativeImagePreviewLayoutSupport.java} +12 -12
  3. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GalleryMediaItem.java → NativeImagePreviewMediaItem.java} +2 -2
  4. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewModule.kt +43 -0
  5. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GalleryPagerAdapter.java → NativeImagePreviewPagerAdapter.java} +18 -18
  6. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GallerySharedElementGeometry.java → NativeImagePreviewSharedElementGeometry.java} +2 -2
  7. package/android/src/main/java/cn/fontree/zkit/ui/preview/NativeImagePreviewSharedElementNames.java +39 -0
  8. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GallerySharedElementState.java → NativeImagePreviewSharedElementState.java} +4 -4
  9. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GallerySourceViewRegistry.java → NativeImagePreviewSourceViewRegistry.java} +2 -2
  10. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GalleryTransitionSnapshotView.java → NativeImagePreviewTransitionSnapshotView.java} +3 -3
  11. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GalleryVideoPlayerView.java → NativeImagePreviewVideoPlayerView.java} +7 -7
  12. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GaleriaView.kt → NativeImagePreviewView.kt} +18 -18
  13. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GalleryViewerOverlayView.java → NativeImagePreviewViewerOverlayView.java} +49 -49
  14. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GalleryViewerPageView.java → NativeImagePreviewViewerPageView.java} +27 -27
  15. package/android/src/main/java/cn/fontree/zkit/ui/preview/{GalleryViewerTransitionController.java → NativeImagePreviewViewerTransitionController.java} +22 -22
  16. package/dist/ui/Button/index.d.ts +1 -1
  17. package/dist/ui/Button/index.d.ts.map +1 -1
  18. package/dist/ui/Button/index.js +18 -3
  19. package/dist/ui/NativeImagePreview/NativeImagePreview.js +6 -6
  20. package/dist/ui/NativeImagePreview/NativeImagePreview.web.d.ts +1 -0
  21. package/dist/ui/NativeImagePreview/NativeImagePreview.web.d.ts.map +1 -1
  22. package/dist/ui/NativeImagePreview/NativeImagePreview.web.js +105 -11
  23. package/dist/ui/NativeImagePreview/context.d.ts +1 -1
  24. package/dist/ui/NativeImagePreview/context.d.ts.map +1 -1
  25. package/dist/ui/NativeImagePreview/types.d.ts +3 -1
  26. package/dist/ui/NativeImagePreview/types.d.ts.map +1 -1
  27. package/dist/ui/NativeImagePreview/utils.d.ts.map +1 -1
  28. package/dist/ui/NativeImagePreview/utils.js +1 -0
  29. package/dist/ui/NativeImagePreview/web/geometry.d.ts +20 -0
  30. package/dist/ui/NativeImagePreview/web/geometry.d.ts.map +1 -0
  31. package/dist/ui/NativeImagePreview/web/geometry.js +121 -0
  32. package/dist/ui/NativeImagePreview/web/media.d.ts +6 -0
  33. package/dist/ui/NativeImagePreview/web/media.d.ts.map +1 -0
  34. package/dist/ui/NativeImagePreview/web/media.js +90 -0
  35. package/dist/ui/NativeImagePreview/web/styles.css +137 -0
  36. package/dist/ui/NativeImagePreview/web/transition.d.ts +15 -0
  37. package/dist/ui/NativeImagePreview/web/transition.d.ts.map +1 -0
  38. package/dist/ui/NativeImagePreview/web/transition.js +77 -0
  39. package/dist/ui/NativeImagePreview/web/types.d.ts +74 -0
  40. package/dist/ui/NativeImagePreview/web/types.d.ts.map +1 -0
  41. package/dist/ui/NativeImagePreview/web/types.js +3 -0
  42. package/dist/ui/NativeImagePreview/web/viewer.d.ts +104 -0
  43. package/dist/ui/NativeImagePreview/web/viewer.d.ts.map +1 -0
  44. package/dist/ui/NativeImagePreview/web/viewer.js +894 -0
  45. package/expo-module.config.json +2 -2
  46. package/ios/{GalleryViewer/GaleriaImageLoader.swift → NativeImagePreview/NativeImagePreviewImageLoader.swift} +7 -7
  47. package/ios/NativeImagePreview/NativeImagePreviewImageViewInteraction.swift +245 -0
  48. package/ios/{GalleryViewer/GaleriaLayoutSupport.swift → NativeImagePreview/NativeImagePreviewLayoutSupport.swift} +19 -19
  49. package/ios/NativeImagePreview/NativeImagePreviewMedia.swift +28 -0
  50. package/ios/NativeImagePreview/NativeImagePreviewSourceViewRegistry.swift +80 -0
  51. package/ios/{GalleryViewer/GaleriaVideoPlayerView.swift → NativeImagePreview/NativeImagePreviewVideoPlayerView.swift} +1 -1
  52. package/ios/{GalleryViewer/GaleriaViewerConfiguration.swift → NativeImagePreview/NativeImagePreviewViewerConfiguration.swift} +7 -7
  53. package/ios/{GalleryViewer/GaleriaViewerController.swift → NativeImagePreview/NativeImagePreviewViewerController.swift} +36 -36
  54. package/ios/{GalleryViewer/GaleriaViewerPageView.swift → NativeImagePreview/NativeImagePreviewViewerPageView.swift} +33 -33
  55. package/ios/{GalleryViewer/GaleriaViewerTransitionCoordinator.swift → NativeImagePreview/NativeImagePreviewViewerTransitionCoordinator.swift} +16 -16
  56. package/ios/{GaleriaModule.swift → NativeImagePreviewModule.swift} +4 -4
  57. package/ios/{GaleriaView.swift → NativeImagePreviewView.swift} +26 -27
  58. package/package.json +18 -12
  59. package/src/services/ImagePreviewService/README.md +1 -1
  60. package/src/types.d.ts +1 -0
  61. package/src/ui/Button/README.md +1 -1
  62. package/src/ui/Button/index.tsx +27 -7
  63. package/src/ui/NativeImagePreview/NativeImagePreview.tsx +7 -7
  64. package/src/ui/NativeImagePreview/NativeImagePreview.web.tsx +175 -11
  65. package/src/ui/NativeImagePreview/README.md +3 -3
  66. package/src/ui/NativeImagePreview/context.tsx +1 -1
  67. package/src/ui/NativeImagePreview/types.ts +3 -1
  68. package/src/ui/NativeImagePreview/utils.ts +1 -0
  69. package/src/ui/NativeImagePreview/web/geometry.ts +134 -0
  70. package/src/ui/NativeImagePreview/web/media.ts +91 -0
  71. package/src/ui/NativeImagePreview/web/styles.css +137 -0
  72. package/src/ui/NativeImagePreview/web/transition.ts +111 -0
  73. package/src/ui/NativeImagePreview/web/types.ts +88 -0
  74. package/src/ui/NativeImagePreview/web/viewer.ts +1024 -0
  75. package/android/src/main/java/cn/fontree/zkit/ui/preview/GaleriaModule.kt +0 -43
  76. package/android/src/main/java/cn/fontree/zkit/ui/preview/GallerySharedElementNames.java +0 -39
  77. package/ios/GalleryViewer/GaleriaImageViewInteraction.swift +0 -245
  78. package/ios/GalleryViewer/GaleriaMedia.swift +0 -28
  79. package/ios/GalleryViewer/GaleriaSourceViewRegistry.swift +0 -80
  80. /package/android/src/main/res/layout/{galeria_player_view.xml → native_image_preview_player_view.xml} +0 -0
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "platforms": ["apple", "android"],
3
3
  "apple": {
4
- "modules": ["GaleriaModule"],
4
+ "modules": ["NativeImagePreviewModule"],
5
5
  "podspecPath": "zkit-ui.podspec",
6
6
  "swiftModuleName": "zkit_ui"
7
7
  },
8
8
  "android": {
9
- "modules": ["cn.fontree.zkit.ui.preview.GaleriaModule"]
9
+ "modules": ["cn.fontree.zkit.ui.preview.NativeImagePreviewModule"]
10
10
  }
11
11
  }
@@ -4,7 +4,7 @@ import UIKit
4
4
  import SDWebImage
5
5
  #endif
6
6
 
7
- public protocol GaleriaImageLoading {
7
+ public protocol NativeImagePreviewImageLoading {
8
8
  func loadImage(
9
9
  _ url: URL,
10
10
  placeholder: UIImage?,
@@ -13,7 +13,7 @@ public protocol GaleriaImageLoading {
13
13
  )
14
14
  }
15
15
 
16
- public struct GaleriaURLSessionImageLoader: GaleriaImageLoading {
16
+ public struct NativeImagePreviewURLSessionImageLoader: NativeImagePreviewImageLoading {
17
17
  public init() {}
18
18
 
19
19
  public func loadImage(
@@ -41,7 +41,7 @@ public struct GaleriaURLSessionImageLoader: GaleriaImageLoading {
41
41
  }
42
42
 
43
43
  #if canImport(SDWebImage)
44
- struct GaleriaSDWebImageLoader: GaleriaImageLoading {
44
+ struct NativeImagePreviewSDWebImageLoader: NativeImagePreviewImageLoading {
45
45
  func loadImage(
46
46
  _ url: URL,
47
47
  placeholder: UIImage?,
@@ -62,12 +62,12 @@ struct GaleriaSDWebImageLoader: GaleriaImageLoading {
62
62
  }
63
63
  #endif
64
64
 
65
- public enum GaleriaImageLoaderFactory {
66
- public static func makeDefault() -> GaleriaImageLoading {
65
+ public enum NativeImagePreviewImageLoaderFactory {
66
+ public static func makeDefault() -> NativeImagePreviewImageLoading {
67
67
  #if canImport(SDWebImage)
68
- return GaleriaSDWebImageLoader()
68
+ return NativeImagePreviewSDWebImageLoader()
69
69
  #else
70
- return GaleriaURLSessionImageLoader()
70
+ return NativeImagePreviewURLSessionImageLoader()
71
71
  #endif
72
72
  }
73
73
  }
@@ -0,0 +1,245 @@
1
+ import ObjectiveC
2
+ import UIKit
3
+
4
+ extension UIImageView {
5
+ private struct NativeImagePreviewAnchorRegistration {
6
+ let previewGroupId: String
7
+ let index: Int
8
+ }
9
+
10
+ private final class NativeImagePreviewTapGestureRecognizer: UITapGestureRecognizer {
11
+ weak var fromViewController: UIViewController?
12
+ var dataSource: NativeImagePreviewDataSource?
13
+ var imageLoader: NativeImagePreviewImageLoading?
14
+ var initialIndex = 0
15
+ var previewGroupId: String?
16
+ var configuration = NativeImagePreviewViewerConfiguration()
17
+ }
18
+
19
+ private static var anchorRegistrationKey: UInt8 = 0
20
+ private static var gestureRecognizerKey: UInt8 = 0
21
+
22
+ private var topMostHostViewController: UIViewController? {
23
+ let keyWindow: UIWindow? = {
24
+ if #available(iOS 13.0, *) {
25
+ let scenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }
26
+ let activeScene = scenes.first(where: { $0.activationState == .foregroundActive }) ?? scenes.first
27
+ return activeScene?.windows.first(where: { $0.isKeyWindow }) ?? activeScene?.windows.first
28
+ } else {
29
+ return UIApplication.shared.windows.first(where: { $0.isKeyWindow }) ?? UIApplication.shared.windows.first
30
+ }
31
+ }()
32
+ guard let rootViewController = keyWindow?.rootViewController else { return nil }
33
+ return rootViewController.presentedViewController ?? rootViewController
34
+ }
35
+
36
+ public func setupNativeImagePreviewViewer(
37
+ configuration: NativeImagePreviewViewerConfiguration = NativeImagePreviewViewerConfiguration(),
38
+ from viewController: UIViewController? = nil,
39
+ imageLoader: NativeImagePreviewImageLoading? = nil,
40
+ previewGroupId: String? = nil
41
+ ) {
42
+ configureNativeImagePreviewViewer(
43
+ dataSource: NativeImagePreviewArrayDataSource(items: [.image(image)]),
44
+ initialIndex: 0,
45
+ configuration: configuration,
46
+ from: viewController,
47
+ imageLoader: imageLoader,
48
+ previewGroupId: previewGroupId
49
+ )
50
+ }
51
+
52
+ public func setupNativeImagePreviewViewer(
53
+ url: URL,
54
+ initialIndex: Int = 0,
55
+ placeholder: UIImage? = nil,
56
+ configuration: NativeImagePreviewViewerConfiguration = NativeImagePreviewViewerConfiguration(),
57
+ from viewController: UIViewController? = nil,
58
+ imageLoader: NativeImagePreviewImageLoading? = nil,
59
+ previewGroupId: String? = nil
60
+ ) {
61
+ configureNativeImagePreviewViewer(
62
+ dataSource: NativeImagePreviewArrayDataSource(items: [.imageURL(url, placeholder: placeholder)]),
63
+ initialIndex: initialIndex,
64
+ configuration: configuration,
65
+ from: viewController,
66
+ imageLoader: imageLoader,
67
+ previewGroupId: previewGroupId
68
+ )
69
+ }
70
+
71
+ public func setupNativeImagePreviewViewer(
72
+ images: [UIImage],
73
+ initialIndex: Int = 0,
74
+ configuration: NativeImagePreviewViewerConfiguration = NativeImagePreviewViewerConfiguration(),
75
+ from viewController: UIViewController? = nil,
76
+ imageLoader: NativeImagePreviewImageLoading? = nil,
77
+ previewGroupId: String? = nil
78
+ ) {
79
+ let items = images.map { NativeImagePreviewMediaItem.image($0) }
80
+ configureNativeImagePreviewViewer(
81
+ dataSource: NativeImagePreviewArrayDataSource(items: items),
82
+ initialIndex: initialIndex,
83
+ configuration: configuration,
84
+ from: viewController,
85
+ imageLoader: imageLoader,
86
+ previewGroupId: previewGroupId
87
+ )
88
+ }
89
+
90
+ public func setupNativeImagePreviewViewer(
91
+ urls: [URL],
92
+ initialIndex: Int = 0,
93
+ placeholder: UIImage? = nil,
94
+ configuration: NativeImagePreviewViewerConfiguration = NativeImagePreviewViewerConfiguration(),
95
+ from viewController: UIViewController? = nil,
96
+ imageLoader: NativeImagePreviewImageLoading? = nil,
97
+ previewGroupId: String? = nil
98
+ ) {
99
+ let items = urls.map { NativeImagePreviewMediaItem.imageURL($0, placeholder: placeholder) }
100
+ configureNativeImagePreviewViewer(
101
+ dataSource: NativeImagePreviewArrayDataSource(items: items),
102
+ initialIndex: initialIndex,
103
+ configuration: configuration,
104
+ from: viewController,
105
+ imageLoader: imageLoader,
106
+ previewGroupId: previewGroupId
107
+ )
108
+ }
109
+
110
+ public func setupNativeImagePreviewViewer(
111
+ dataSource: NativeImagePreviewDataSource,
112
+ initialIndex: Int = 0,
113
+ configuration: NativeImagePreviewViewerConfiguration = NativeImagePreviewViewerConfiguration(),
114
+ from viewController: UIViewController? = nil,
115
+ imageLoader: NativeImagePreviewImageLoading? = nil,
116
+ previewGroupId: String? = nil
117
+ ) {
118
+ configureNativeImagePreviewViewer(
119
+ dataSource: dataSource,
120
+ initialIndex: initialIndex,
121
+ configuration: configuration,
122
+ from: viewController,
123
+ imageLoader: imageLoader,
124
+ previewGroupId: previewGroupId
125
+ )
126
+ }
127
+
128
+ func removeNativeImagePreviewViewerInteraction() {
129
+ if let recognizer = nativeImagePreviewTapGestureRecognizer {
130
+ removeGestureRecognizer(recognizer)
131
+ }
132
+ nativeImagePreviewTapGestureRecognizer = nil
133
+
134
+ if let registration = nativeImagePreviewAnchorRegistration {
135
+ NativeImagePreviewSourceViewRegistry.shared.unregister(
136
+ self,
137
+ previewGroupId: registration.previewGroupId,
138
+ index: registration.index
139
+ )
140
+ }
141
+ nativeImagePreviewAnchorRegistration = nil
142
+ }
143
+
144
+ private func configureNativeImagePreviewViewer(
145
+ dataSource: NativeImagePreviewDataSource?,
146
+ initialIndex: Int,
147
+ configuration: NativeImagePreviewViewerConfiguration,
148
+ from viewController: UIViewController?,
149
+ imageLoader: NativeImagePreviewImageLoading?,
150
+ previewGroupId: String?
151
+ ) {
152
+ let recognizer = nativeImagePreviewTapGestureRecognizer ?? {
153
+ let recognizer = NativeImagePreviewTapGestureRecognizer(target: self, action: #selector(showNativeImagePreviewViewer(_:)))
154
+ recognizer.numberOfTouchesRequired = 1
155
+ recognizer.numberOfTapsRequired = 1
156
+ nativeImagePreviewTapGestureRecognizer = recognizer
157
+ return recognizer
158
+ }()
159
+
160
+ isUserInteractionEnabled = true
161
+ clipsToBounds = true
162
+
163
+ recognizer.dataSource = dataSource
164
+ recognizer.imageLoader = imageLoader
165
+ recognizer.initialIndex = initialIndex
166
+ recognizer.previewGroupId = previewGroupId
167
+ recognizer.configuration = configuration
168
+ recognizer.fromViewController = viewController
169
+
170
+ if recognizer.view !== self {
171
+ addGestureRecognizer(recognizer)
172
+ }
173
+
174
+ updateNativeImagePreviewAnchorRegistration(previewGroupId: previewGroupId, index: initialIndex)
175
+ }
176
+
177
+ private var nativeImagePreviewTapGestureRecognizer: NativeImagePreviewTapGestureRecognizer? {
178
+ get {
179
+ objc_getAssociatedObject(self, &Self.gestureRecognizerKey) as? NativeImagePreviewTapGestureRecognizer
180
+ }
181
+ set {
182
+ objc_setAssociatedObject(
183
+ self,
184
+ &Self.gestureRecognizerKey,
185
+ newValue,
186
+ .OBJC_ASSOCIATION_RETAIN_NONATOMIC
187
+ )
188
+ }
189
+ }
190
+
191
+ private var nativeImagePreviewAnchorRegistration: NativeImagePreviewAnchorRegistration? {
192
+ get {
193
+ objc_getAssociatedObject(self, &Self.anchorRegistrationKey) as? NativeImagePreviewAnchorRegistration
194
+ }
195
+ set {
196
+ objc_setAssociatedObject(
197
+ self,
198
+ &Self.anchorRegistrationKey,
199
+ newValue,
200
+ .OBJC_ASSOCIATION_RETAIN_NONATOMIC
201
+ )
202
+ }
203
+ }
204
+
205
+ @objc
206
+ private func showNativeImagePreviewViewer(_ recognizer: NativeImagePreviewTapGestureRecognizer) {
207
+ guard let sourceView = recognizer.view as? UIImageView else { return }
208
+ let resolvedImageLoader = recognizer.imageLoader ?? NativeImagePreviewImageLoaderFactory.makeDefault()
209
+ let viewerController = NativeImagePreviewViewerController(
210
+ sourceView: sourceView,
211
+ dataSource: recognizer.dataSource,
212
+ imageLoader: resolvedImageLoader,
213
+ configuration: recognizer.configuration,
214
+ initialIndex: recognizer.initialIndex,
215
+ previewGroupId: recognizer.previewGroupId
216
+ )
217
+
218
+ let rootViewController = recognizer.fromViewController ?? topMostHostViewController
219
+ let presenter = rootViewController.flatMap(topMostPresentedController(from:))
220
+ presenter?.present(viewerController, animated: false)
221
+ }
222
+
223
+ private func topMostPresentedController(from rootViewController: UIViewController) -> UIViewController {
224
+ var controller = rootViewController
225
+ while let presented = controller.presentedViewController {
226
+ controller = presented
227
+ }
228
+ return controller
229
+ }
230
+
231
+ private func updateNativeImagePreviewAnchorRegistration(previewGroupId: String?, index: Int) {
232
+ if let existing = nativeImagePreviewAnchorRegistration {
233
+ NativeImagePreviewSourceViewRegistry.shared.unregister(
234
+ self,
235
+ previewGroupId: existing.previewGroupId,
236
+ index: existing.index
237
+ )
238
+ nativeImagePreviewAnchorRegistration = nil
239
+ }
240
+
241
+ guard let previewGroupId = previewGroupId, previewGroupId.isEmpty == false else { return }
242
+ NativeImagePreviewSourceViewRegistry.shared.register(self, previewGroupId: previewGroupId, index: index)
243
+ nativeImagePreviewAnchorRegistration = NativeImagePreviewAnchorRegistration(previewGroupId: previewGroupId, index: index)
244
+ }
245
+ }
@@ -1,18 +1,18 @@
1
1
  import UIKit
2
2
 
3
- struct GaleriaSharedElementGeometry {
3
+ struct NativeImagePreviewSharedElementGeometry {
4
4
  let visibleFrameInWindow: CGRect
5
5
  let contentFrameInVisibleBounds: CGRect
6
6
  let cornerRadius: CGFloat
7
7
  }
8
8
 
9
- struct GaleriaSharedElementState {
9
+ struct NativeImagePreviewSharedElementState {
10
10
  let image: UIImage
11
- let geometry: GaleriaSharedElementGeometry
11
+ let geometry: NativeImagePreviewSharedElementGeometry
12
12
  }
13
13
 
14
14
  extension CGRect {
15
- func galeriaPixelAligned(scale: CGFloat) -> CGRect {
15
+ func nativeImagePreviewPixelAligned(scale: CGFloat) -> CGRect {
16
16
  guard scale > 0 else { return self }
17
17
  return CGRect(
18
18
  x: (origin.x * scale).rounded() / scale,
@@ -22,7 +22,7 @@ extension CGRect {
22
22
  )
23
23
  }
24
24
 
25
- func galeriaApproximatelyEquals(_ other: CGRect, tolerance: CGFloat = 0.5) -> Bool {
25
+ func nativeImagePreviewApproximatelyEquals(_ other: CGRect, tolerance: CGFloat = 0.5) -> Bool {
26
26
  abs(minX - other.minX) <= tolerance
27
27
  && abs(minY - other.minY) <= tolerance
28
28
  && abs(width - other.width) <= tolerance
@@ -30,18 +30,18 @@ extension CGRect {
30
30
  }
31
31
  }
32
32
 
33
- extension GaleriaSharedElementGeometry {
34
- func galeriaPixelAligned(scale: CGFloat) -> GaleriaSharedElementGeometry {
35
- GaleriaSharedElementGeometry(
36
- visibleFrameInWindow: visibleFrameInWindow.galeriaPixelAligned(scale: scale),
37
- contentFrameInVisibleBounds: contentFrameInVisibleBounds.galeriaPixelAligned(scale: scale),
33
+ extension NativeImagePreviewSharedElementGeometry {
34
+ func nativeImagePreviewPixelAligned(scale: CGFloat) -> NativeImagePreviewSharedElementGeometry {
35
+ NativeImagePreviewSharedElementGeometry(
36
+ visibleFrameInWindow: visibleFrameInWindow.nativeImagePreviewPixelAligned(scale: scale),
37
+ contentFrameInVisibleBounds: contentFrameInVisibleBounds.nativeImagePreviewPixelAligned(scale: scale),
38
38
  cornerRadius: (cornerRadius * scale).rounded() / scale
39
39
  )
40
40
  }
41
41
 
42
- func approximatelyEquals(_ other: GaleriaSharedElementGeometry, tolerance: CGFloat = 0.5) -> Bool {
43
- visibleFrameInWindow.galeriaApproximatelyEquals(other.visibleFrameInWindow, tolerance: tolerance)
44
- && contentFrameInVisibleBounds.galeriaApproximatelyEquals(
42
+ func approximatelyEquals(_ other: NativeImagePreviewSharedElementGeometry, tolerance: CGFloat = 0.5) -> Bool {
43
+ visibleFrameInWindow.nativeImagePreviewApproximatelyEquals(other.visibleFrameInWindow, tolerance: tolerance)
44
+ && contentFrameInVisibleBounds.nativeImagePreviewApproximatelyEquals(
45
45
  other.contentFrameInVisibleBounds,
46
46
  tolerance: tolerance
47
47
  )
@@ -49,8 +49,8 @@ extension GaleriaSharedElementGeometry {
49
49
  }
50
50
  }
51
51
 
52
- extension GaleriaSharedElementState {
53
- func approximatelyEquals(_ other: GaleriaSharedElementState, tolerance: CGFloat = 0.5) -> Bool {
52
+ extension NativeImagePreviewSharedElementState {
53
+ func approximatelyEquals(_ other: NativeImagePreviewSharedElementState, tolerance: CGFloat = 0.5) -> Bool {
54
54
  geometry.approximatelyEquals(other.geometry, tolerance: tolerance)
55
55
  && abs(image.size.width - other.image.size.width) <= tolerance
56
56
  && abs(image.size.height - other.image.size.height) <= tolerance
@@ -113,7 +113,7 @@ extension UIImageView {
113
113
  return convert(contentFrame, to: nil)
114
114
  }
115
115
 
116
- func galeriaSharedElementState(clippingFrameInWindow: CGRect? = nil) -> GaleriaSharedElementState? {
116
+ func nativeImagePreviewSharedElementState(clippingFrameInWindow: CGRect? = nil) -> NativeImagePreviewSharedElementState? {
117
117
  guard let image = image else { return nil }
118
118
  guard image.size.width > 0, image.size.height > 0 else { return nil }
119
119
 
@@ -126,7 +126,7 @@ extension UIImageView {
126
126
  visibleFrame = clippingFrame
127
127
  }
128
128
 
129
- let geometry = GaleriaSharedElementGeometry(
129
+ let geometry = NativeImagePreviewSharedElementGeometry(
130
130
  visibleFrameInWindow: visibleFrame,
131
131
  contentFrameInVisibleBounds: contentFrame.offsetBy(
132
132
  dx: -visibleFrame.minX,
@@ -135,9 +135,9 @@ extension UIImageView {
135
135
  cornerRadius: (clipsToBounds || layer.masksToBounds) ? layer.cornerRadius : 0
136
136
  )
137
137
  let scale = window?.screen.scale ?? UIScreen.main.scale
138
- return GaleriaSharedElementState(
138
+ return NativeImagePreviewSharedElementState(
139
139
  image: image,
140
- geometry: geometry.galeriaPixelAligned(scale: scale)
140
+ geometry: geometry.nativeImagePreviewPixelAligned(scale: scale)
141
141
  )
142
142
  }
143
143
  }
@@ -0,0 +1,28 @@
1
+ import UIKit
2
+
3
+ public enum NativeImagePreviewMediaItem {
4
+ case image(UIImage?)
5
+ case imageURL(URL, placeholder: UIImage?)
6
+ case video(url: URL, poster: URL?)
7
+ }
8
+
9
+ public protocol NativeImagePreviewDataSource: AnyObject {
10
+ func numberOfItems() -> Int
11
+ func item(at index: Int) -> NativeImagePreviewMediaItem
12
+ }
13
+
14
+ public final class NativeImagePreviewArrayDataSource: NativeImagePreviewDataSource {
15
+ private let items: [NativeImagePreviewMediaItem]
16
+
17
+ public init(items: [NativeImagePreviewMediaItem]) {
18
+ self.items = items
19
+ }
20
+
21
+ public func numberOfItems() -> Int {
22
+ items.count
23
+ }
24
+
25
+ public func item(at index: Int) -> NativeImagePreviewMediaItem {
26
+ items[index]
27
+ }
28
+ }
@@ -0,0 +1,80 @@
1
+ import UIKit
2
+
3
+ final class NativeImagePreviewSourceViewRegistry {
4
+ static let shared = NativeImagePreviewSourceViewRegistry()
5
+
6
+ private final class WeakImageView {
7
+ weak var value: UIImageView?
8
+
9
+ init(_ value: UIImageView) {
10
+ self.value = value
11
+ }
12
+ }
13
+
14
+ private var anchors: [String: [Int: WeakImageView]] = [:]
15
+
16
+ private init() {}
17
+
18
+ func register(_ imageView: UIImageView, previewGroupId: String, index: Int) {
19
+ cleanup()
20
+ var previewGroupAnchors = anchors[previewGroupId] ?? [:]
21
+ previewGroupAnchors[index] = WeakImageView(imageView)
22
+ anchors[previewGroupId] = previewGroupAnchors
23
+ }
24
+
25
+ func unregister(_ imageView: UIImageView, previewGroupId: String?, index: Int?) {
26
+ cleanup()
27
+ if let previewGroupId = previewGroupId {
28
+ remove(imageView, from: previewGroupId, index: index)
29
+ } else {
30
+ for previewGroupId in Array(anchors.keys) {
31
+ remove(imageView, from: previewGroupId, index: nil)
32
+ }
33
+ }
34
+ cleanup()
35
+ }
36
+
37
+ func sourceView(for previewGroupId: String, index: Int) -> UIImageView? {
38
+ cleanup()
39
+ guard
40
+ let imageView = anchors[previewGroupId]?[index]?.value,
41
+ let window = imageView.window,
42
+ !imageView.isHidden
43
+ else {
44
+ return nil
45
+ }
46
+
47
+ let frameInWindow = imageView.frameInWindow()
48
+ guard !frameInWindow.isEmpty, frameInWindow.intersects(window.bounds) else {
49
+ return nil
50
+ }
51
+
52
+ return imageView
53
+ }
54
+
55
+ private func remove(_ imageView: UIImageView, from previewGroupId: String, index: Int?) {
56
+ guard var previewGroupAnchors = anchors[previewGroupId] else { return }
57
+
58
+ if let index = index {
59
+ if let registeredView = previewGroupAnchors[index]?.value, registeredView === imageView {
60
+ previewGroupAnchors.removeValue(forKey: index)
61
+ }
62
+ } else {
63
+ previewGroupAnchors = previewGroupAnchors.filter { _, weakImageView in
64
+ guard let registeredView = weakImageView.value else { return false }
65
+ return registeredView !== imageView
66
+ }
67
+ }
68
+
69
+ anchors[previewGroupId] = previewGroupAnchors.isEmpty ? nil : previewGroupAnchors
70
+ }
71
+
72
+ private func cleanup() {
73
+ anchors = anchors.compactMapValues { previewGroupAnchors in
74
+ let activeAnchors = previewGroupAnchors.filter { _, weakImageView in
75
+ weakImageView.value != nil
76
+ }
77
+ return activeAnchors.isEmpty ? nil : activeAnchors
78
+ }
79
+ }
80
+ }
@@ -1,7 +1,7 @@
1
1
  import AVFoundation
2
2
  import UIKit
3
3
 
4
- final class GaleriaVideoPlayerView: UIView {
4
+ final class NativeImagePreviewVideoPlayerView: UIView {
5
5
  private var player: AVPlayer?
6
6
  private var playerLayer: AVPlayerLayer?
7
7
  private var timeObserver: Any?
@@ -1,6 +1,6 @@
1
1
  import UIKit
2
2
 
3
- public enum GaleriaViewerTheme {
3
+ public enum NativeImagePreviewViewerTheme {
4
4
  case light
5
5
  case dark
6
6
 
@@ -23,23 +23,23 @@ public enum GaleriaViewerTheme {
23
23
  }
24
24
  }
25
25
 
26
- public enum GaleriaViewerBarButton {
26
+ public enum NativeImagePreviewViewerBarButton {
27
27
  case title(String, onTap: ((Int) -> Void)?)
28
28
  case icon(UIImage, onTap: ((Int) -> Void)?)
29
29
  }
30
30
 
31
- public struct GaleriaViewerConfiguration {
32
- public var theme: GaleriaViewerTheme
31
+ public struct NativeImagePreviewViewerConfiguration {
32
+ public var theme: NativeImagePreviewViewerTheme
33
33
  public var contentMode: UIView.ContentMode
34
34
  public var closeIcon: UIImage?
35
- public var rightBarButton: GaleriaViewerBarButton?
35
+ public var rightBarButton: NativeImagePreviewViewerBarButton?
36
36
  public var onIndexChange: ((Int) -> Void)?
37
37
 
38
38
  public init(
39
- theme: GaleriaViewerTheme = .light,
39
+ theme: NativeImagePreviewViewerTheme = .light,
40
40
  contentMode: UIView.ContentMode = .scaleAspectFit,
41
41
  closeIcon: UIImage? = nil,
42
- rightBarButton: GaleriaViewerBarButton? = nil,
42
+ rightBarButton: NativeImagePreviewViewerBarButton? = nil,
43
43
  onIndexChange: ((Int) -> Void)? = nil
44
44
  ) {
45
45
  self.theme = theme