mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1/**
2 * Copyright (c) JOB TODAY S.A. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 */
8
9import {
10 Animated,
11 GestureResponderEvent,
12 PanResponder,
13 PanResponderGestureState,
14 PanResponderInstance,
15 NativeTouchEvent,
16} from 'react-native'
17import {Dimensions, Position} from './@types'
18
19type CacheStorageItem = {key: string; value: any}
20
21export const createCache = (cacheSize: number) => ({
22 _storage: [] as CacheStorageItem[],
23 get(key: string): any {
24 const {value} =
25 this._storage.find(({key: storageKey}) => storageKey === key) || {}
26
27 return value
28 },
29 set(key: string, value: any) {
30 if (this._storage.length >= cacheSize) {
31 this._storage.shift()
32 }
33
34 this._storage.push({key, value})
35 },
36})
37
38export const splitArrayIntoBatches = (arr: any[], batchSize: number): any[] =>
39 arr.reduce((result, item) => {
40 const batch = result.pop() || []
41
42 if (batch.length < batchSize) {
43 batch.push(item)
44 result.push(batch)
45 } else {
46 result.push(batch, [item])
47 }
48
49 return result
50 }, [])
51
52export const getImageTransform = (
53 image: Dimensions | null,
54 screen: Dimensions,
55) => {
56 if (!image?.width || !image?.height) {
57 return [] as const
58 }
59
60 const wScale = screen.width / image.width
61 const hScale = screen.height / image.height
62 const scale = Math.min(wScale, hScale)
63 const {x, y} = getImageTranslate(image, screen)
64
65 return [{x, y}, scale] as const
66}
67
68export const getImageStyles = (
69 image: Dimensions | null,
70 translate: Animated.ValueXY,
71 scale?: Animated.Value,
72) => {
73 if (!image?.width || !image?.height) {
74 return {width: 0, height: 0}
75 }
76
77 const transform = translate.getTranslateTransform()
78
79 if (scale) {
80 // @ts-ignore TODO - is scale incorrect? might need to remove -prf
81 transform.push({scale}, {perspective: new Animated.Value(1000)})
82 }
83
84 return {
85 width: image.width,
86 height: image.height,
87 transform,
88 }
89}
90
91export const getImageTranslate = (
92 image: Dimensions,
93 screen: Dimensions,
94): Position => {
95 const getTranslateForAxis = (axis: 'x' | 'y'): number => {
96 const imageSize = axis === 'x' ? image.width : image.height
97 const screenSize = axis === 'x' ? screen.width : screen.height
98
99 return (screenSize - imageSize) / 2
100 }
101
102 return {
103 x: getTranslateForAxis('x'),
104 y: getTranslateForAxis('y'),
105 }
106}
107
108export const getImageDimensionsByTranslate = (
109 translate: Position,
110 screen: Dimensions,
111): Dimensions => ({
112 width: screen.width - translate.x * 2,
113 height: screen.height - translate.y * 2,
114})
115
116export const getImageTranslateForScale = (
117 currentTranslate: Position,
118 targetScale: number,
119 screen: Dimensions,
120): Position => {
121 const {width, height} = getImageDimensionsByTranslate(
122 currentTranslate,
123 screen,
124 )
125
126 const targetImageDimensions = {
127 width: width * targetScale,
128 height: height * targetScale,
129 }
130
131 return getImageTranslate(targetImageDimensions, screen)
132}
133
134type HandlerType = (
135 event: GestureResponderEvent,
136 state: PanResponderGestureState,
137) => void
138
139type PanResponderProps = {
140 onGrant: HandlerType
141 onStart?: HandlerType
142 onMove: HandlerType
143 onRelease?: HandlerType
144 onTerminate?: HandlerType
145}
146
147export const createPanResponder = ({
148 onGrant,
149 onStart,
150 onMove,
151 onRelease,
152 onTerminate,
153}: PanResponderProps): PanResponderInstance =>
154 PanResponder.create({
155 onStartShouldSetPanResponder: () => true,
156 onStartShouldSetPanResponderCapture: () => true,
157 onMoveShouldSetPanResponder: () => true,
158 onMoveShouldSetPanResponderCapture: () => true,
159 onPanResponderGrant: onGrant,
160 onPanResponderStart: onStart,
161 onPanResponderMove: onMove,
162 onPanResponderRelease: onRelease,
163 onPanResponderTerminate: onTerminate,
164 onPanResponderTerminationRequest: () => false,
165 onShouldBlockNativeResponder: () => false,
166 })
167
168export const getDistanceBetweenTouches = (
169 touches: NativeTouchEvent[],
170): number => {
171 const [a, b] = touches
172
173 if (a == null || b == null) {
174 return 0
175 }
176
177 return Math.sqrt(
178 Math.pow(a.pageX - b.pageX, 2) + Math.pow(a.pageY - b.pageY, 2),
179 )
180}