@codeleap/mobile 1.9.28 → 1.9.29

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 (116) hide show
  1. package/dist/components/Backdrop.d.ts +66 -0
  2. package/dist/components/Backdrop.js +70 -0
  3. package/dist/components/Backdrop.js.map +1 -0
  4. package/dist/components/Button.d.ts +3 -3
  5. package/dist/components/Button.js.map +1 -1
  6. package/dist/components/FileInput.js +0 -2
  7. package/dist/components/FileInput.js.map +1 -1
  8. package/dist/components/Image.js +2 -2
  9. package/dist/components/Image.js.map +1 -1
  10. package/dist/components/List.d.ts +23 -4
  11. package/dist/components/List.js +17 -1
  12. package/dist/components/List.js.map +1 -1
  13. package/dist/components/Modal/index.d.ts +1 -1
  14. package/dist/components/Modal/index.js +26 -27
  15. package/dist/components/Modal/index.js.map +1 -1
  16. package/dist/components/Modal/styles.d.ts +3 -9
  17. package/dist/components/Modal/styles.js +26 -17
  18. package/dist/components/Modal/styles.js.map +1 -1
  19. package/dist/components/NewModal/index.d.ts +27 -0
  20. package/dist/components/NewModal/index.js +99 -0
  21. package/dist/components/NewModal/index.js.map +1 -0
  22. package/dist/components/NewModal/styles.d.ts +57 -0
  23. package/dist/components/NewModal/styles.js +58 -0
  24. package/dist/components/NewModal/styles.js.map +1 -0
  25. package/dist/components/Overlay.js +13 -9
  26. package/dist/components/Overlay.js.map +1 -1
  27. package/dist/components/Scroll.d.ts +4 -2
  28. package/dist/components/Scroll.js.map +1 -1
  29. package/dist/components/SegmentedControl/index.d.ts +42 -0
  30. package/dist/components/SegmentedControl/index.js +137 -0
  31. package/dist/components/SegmentedControl/index.js.map +1 -0
  32. package/dist/components/SegmentedControl/styles.d.ts +54 -0
  33. package/dist/components/SegmentedControl/styles.js +36 -0
  34. package/dist/components/SegmentedControl/styles.js.map +1 -0
  35. package/dist/components/SegmentedControl.d.ts +5 -0
  36. package/dist/components/SegmentedControl.js +32 -0
  37. package/dist/components/SegmentedControl.js.map +1 -0
  38. package/dist/components/Select/index.js +1 -1
  39. package/dist/components/Select/index.js.map +1 -1
  40. package/dist/components/Text.d.ts +8 -3
  41. package/dist/components/Text.js +12 -5
  42. package/dist/components/Text.js.map +1 -1
  43. package/dist/components/TextInput.d.ts +4 -2
  44. package/dist/components/TextInput.js +2 -2
  45. package/dist/components/TextInput.js.map +1 -1
  46. package/dist/components/Touchable.d.ts +5 -3
  47. package/dist/components/Touchable.js +26 -19
  48. package/dist/components/Touchable.js.map +1 -1
  49. package/dist/components/View.js +1 -1
  50. package/dist/components/View.js.map +1 -1
  51. package/dist/components/_Modal/index.d.ts +27 -0
  52. package/dist/components/_Modal/index.js +114 -0
  53. package/dist/components/_Modal/index.js.map +1 -0
  54. package/dist/components/_Modal/styles.d.ts +64 -0
  55. package/dist/components/_Modal/styles.js +60 -0
  56. package/dist/components/_Modal/styles.js.map +1 -0
  57. package/dist/components/components.d.ts +2 -0
  58. package/dist/components/components.js +2 -0
  59. package/dist/components/components.js.map +1 -1
  60. package/dist/index.d.ts +3 -0
  61. package/dist/index.js +16 -1
  62. package/dist/index.js.map +1 -1
  63. package/dist/utils/ModalManager/components.d.ts +5 -5
  64. package/dist/utils/ModalManager/components.js +16 -9
  65. package/dist/utils/ModalManager/components.js.map +1 -1
  66. package/dist/utils/ModalManager/context.d.ts +8 -3
  67. package/dist/utils/ModalManager/context.js +47 -23
  68. package/dist/utils/ModalManager/context.js.map +1 -1
  69. package/dist/utils/ModalManager/index.d.ts +3 -7
  70. package/dist/utils/ModalManager/index.js +1 -1
  71. package/dist/utils/ModalManager/index.js.map +1 -1
  72. package/dist/utils/PermissionManager/components.d.ts +18 -0
  73. package/dist/utils/PermissionManager/components.js +52 -0
  74. package/dist/utils/PermissionManager/components.js.map +1 -0
  75. package/dist/utils/PermissionManager/context.d.ts +52 -0
  76. package/dist/utils/PermissionManager/context.js +325 -0
  77. package/dist/utils/PermissionManager/context.js.map +1 -0
  78. package/dist/utils/PermissionManager/index.d.ts +4 -0
  79. package/dist/utils/PermissionManager/index.js +9 -0
  80. package/dist/utils/PermissionManager/index.js.map +1 -0
  81. package/dist/utils/PermissionManager/types.d.ts +13 -0
  82. package/dist/utils/PermissionManager/types.js +3 -0
  83. package/dist/utils/PermissionManager/types.js.map +1 -0
  84. package/dist/utils/hooks.d.ts +6 -0
  85. package/dist/utils/hooks.js +62 -0
  86. package/dist/utils/hooks.js.map +1 -0
  87. package/package.json +1 -1
  88. package/src/components/Backdrop.tsx +77 -0
  89. package/src/components/Button.tsx +3 -2
  90. package/src/components/FileInput.tsx +2 -2
  91. package/src/components/Image.tsx +3 -2
  92. package/src/components/List.tsx +44 -5
  93. package/src/components/Modal/index.tsx +38 -49
  94. package/src/components/Modal/styles.ts +35 -31
  95. package/src/components/Overlay.tsx +22 -13
  96. package/src/components/Scroll.tsx +3 -1
  97. package/src/components/SegmentedControl/index.tsx +182 -0
  98. package/src/components/SegmentedControl/styles.ts +65 -0
  99. package/src/components/Select/index.tsx +1 -2
  100. package/src/components/Text.tsx +23 -10
  101. package/src/components/TextInput.tsx +4 -2
  102. package/src/components/Touchable.tsx +31 -20
  103. package/src/components/View.tsx +1 -1
  104. package/src/components/_Modal/index.tsx +162 -0
  105. package/src/components/_Modal/styles.ts +125 -0
  106. package/src/components/components.ts +3 -0
  107. package/src/index.ts +6 -0
  108. package/src/modules/imageCropPicker.d.ts +497 -0
  109. package/src/modules/index.d.ts +186 -0
  110. package/src/utils/ModalManager/components.tsx +20 -9
  111. package/src/utils/ModalManager/context.tsx +69 -30
  112. package/src/utils/ModalManager/index.ts +6 -2
  113. package/src/utils/PermissionManager/context.tsx +299 -0
  114. package/src/utils/PermissionManager/index.ts +20 -0
  115. package/src/utils/PermissionManager/types.ts +24 -0
  116. package/src/utils/hooks.ts +65 -0
@@ -0,0 +1,299 @@
1
+ import React, { useContext, useState } from 'react'
2
+ import { ModalManager } from '@codeleap/mobile'
3
+ import { deepEqual, onMount, onUpdate, PermissionManager, PermissionTypes, useDebounce, usePrevious } from '@codeleap/common'
4
+ import { AppState, Linking } from 'react-native'
5
+ import { PermissionConfig, PermissionModalsConfig } from './types'
6
+
7
+ type TPermissionContext = {
8
+ state: Record<string, PermissionTypes.PermissionStatus>
9
+ modalConfig: PermissionModalsConfig<any>
10
+ manager: PermissionManager<any, any>
11
+ }
12
+
13
+ const PermissionContext = React.createContext({} as TPermissionContext)
14
+
15
+ type PermissionProviderProps = {
16
+ children: React.ReactElement
17
+ AppPermissions: PermissionManager<any, any>
18
+ modalConfig: PermissionModalsConfig<any>
19
+ }
20
+ type PermissionsRecord = PermissionManager<any, any>['values']
21
+ function getStatuses(state: PermissionsRecord) {
22
+ const statuses = Object.entries(state).map(([k, v]) => [k, v.status])
23
+ return Object.fromEntries(statuses)
24
+ }
25
+
26
+ export function Provider({ children, AppPermissions, modalConfig }:PermissionProviderProps) {
27
+
28
+ const [state, setState] = useState(() => getStatuses(AppPermissions.values))
29
+
30
+ onMount(() => {
31
+
32
+ AppState.addEventListener('focus', () => {
33
+
34
+ AppPermissions.update().then((vals) => {
35
+ const statuses = getStatuses(vals)
36
+ if (!deepEqual(statuses, state)) {
37
+ setState({ ...statuses })
38
+ }
39
+
40
+ })
41
+ })
42
+
43
+ })
44
+
45
+ return <PermissionContext.Provider value={{
46
+ state,
47
+ modalConfig: modalConfig,
48
+ manager: AppPermissions,
49
+ }}>
50
+ {children}
51
+ </PermissionContext.Provider>
52
+ }
53
+
54
+ type TAskManyResults<T extends string> =Record<T, PermissionTypes.PermissionStatus> & {
55
+ overall
56
+ : PermissionTypes.PermissionStatus
57
+ }
58
+
59
+ type AskManyOpts<T extends string|number|symbol > = {
60
+ breakOnDenied?: T[]
61
+ }
62
+
63
+ export type UsePermissions<
64
+ _PermissionNames extends string,
65
+ PermissionNames extends string = `${_PermissionNames}?` | _PermissionNames> = () => TPermissionContext & {
66
+ askPermission: (name: PermissionNames, onResolve?: (status: PermissionTypes.PermissionStatus) => any) => any
67
+ askMany<T extends PermissionNames, R = TAskManyResults<T>>(
68
+ perms: T[],
69
+ onResolve?: (res:R) => any,
70
+ options?: AskManyOpts<T>
71
+ ):Promise<void>
72
+ }
73
+
74
+ export const usePermissions:UsePermissions<any> = () => {
75
+ const modalCtx = ModalManager.useModalContext()
76
+ const permissionCtx = useContext(PermissionContext)
77
+
78
+ async function askPermission(name: string, onResolve?: (status: PermissionTypes.PermissionStatus, modalName?: string) => any) {
79
+ const status = await permissionCtx.manager.get(name, {
80
+ ask: false,
81
+ askOnDenied: false,
82
+ askOnPending: false,
83
+ })
84
+
85
+ const permissionModalName = `permissions.${name}`
86
+
87
+ if (!status.isGranted) {
88
+
89
+ modalCtx.toggleModal(permissionModalName, true, {
90
+ onPermissionResolve: (status) => {
91
+ modalCtx.toggleModal(permissionModalName, false, {})
92
+ setTimeout(() => {
93
+ onResolve?.(status, permissionModalName)
94
+
95
+ }, modalCtx.transitionDuration)
96
+ },
97
+ })
98
+
99
+ } else {
100
+ onResolve?.(status.status as unknown as PermissionTypes.PermissionStatus)
101
+ }
102
+ }
103
+
104
+ const askMany = async (
105
+ perms: any[],
106
+ onResolve?: (res:any) => any,
107
+ options?: AskManyOpts<any>,
108
+ ) => {
109
+
110
+ let prevModal = null
111
+ const results = {}
112
+
113
+ for (const _permission of perms) {
114
+ const permission = _permission.replace('?', '')
115
+ const status = await permissionCtx.manager.get(permission, {
116
+ ask: false,
117
+ askOnDenied: false,
118
+ askOnPending: false,
119
+ })
120
+ results[permission] = status.status
121
+ const permissionModalName = `permissions.${permission}`
122
+
123
+ if (!status.isGranted) {
124
+ let onOpen = null
125
+
126
+ if (prevModal) {
127
+
128
+ onOpen = () => new Promise((resolve) => {
129
+ setTimeout(() => {
130
+ console.log('transition', {
131
+ prevModal,
132
+ permissionModalName,
133
+
134
+ })
135
+ modalCtx.transition(prevModal, permissionModalName, {
136
+ props: {
137
+ onPermissionResolve: (status) => {
138
+ resolve(status)
139
+ },
140
+ },
141
+ })
142
+ })
143
+ })
144
+ } else {
145
+ onOpen = () => new Promise((resolve) => {
146
+ setTimeout(() => {
147
+ modalCtx.toggleModal(permissionModalName, true, {
148
+ onPermissionResolve: (status) => {
149
+ resolve(status)
150
+ },
151
+ })
152
+ })
153
+ })
154
+
155
+ }
156
+
157
+ results[permission] = await onOpen()
158
+ prevModal = permissionModalName
159
+
160
+ if (!_permission.endsWith('?') && results[permission] !== 'granted') {
161
+ break
162
+ }
163
+ }
164
+ }
165
+ if (prevModal) {
166
+ console.log(`Close prev modal`, {
167
+ prevModal,
168
+ })
169
+ setTimeout(() => {
170
+ modalCtx.toggleModal(prevModal, false, {})
171
+ })
172
+ }
173
+ onResolve({
174
+ ...results,
175
+ overall: Object.values(results).every(x => x === 'granted') ? 'granted' : 'denied',
176
+ })
177
+ }
178
+
179
+ return {
180
+ askPermission,
181
+ askMany,
182
+ ...permissionCtx,
183
+ }
184
+ }
185
+
186
+ export function usePermissionModal(permissionName: string) {
187
+
188
+ const modalId = `permissions.${permissionName}`
189
+ const modals = ModalManager.useModalContext()
190
+ const permissionCtx = usePermissions()
191
+ const modalState = modals.state[modalId]
192
+
193
+ const currentState = permissionCtx.state[permissionName]
194
+ const status = currentState
195
+ const [debouncedStatus, reset] = useDebounce(status, modals.transitionDuration * 0.5)
196
+
197
+ function getConfig(withStatus) {
198
+ return {
199
+ ...permissionCtx.modalConfig[permissionName],
200
+ ...permissionCtx.modalConfig[permissionName]?.[withStatus],
201
+ } as PermissionConfig
202
+ }
203
+ const config = getConfig(debouncedStatus)
204
+
205
+ function onPermissionResolve(_status?: PermissionTypes.PermissionStatus) {
206
+ modalState?.props?.onPermissionResolve?.(_status || status)
207
+
208
+ }
209
+
210
+ onUpdate(() => {
211
+
212
+ if (modalState?.visible && !!status) {
213
+
214
+ if (status === 'granted') {
215
+ reset()
216
+ onPermissionResolve()
217
+ } else {
218
+
219
+ if (!deepEqual(config, getConfig(status))) {
220
+
221
+ modals.transition(modalId, modalId, {
222
+ props: modalState?.props,
223
+ })
224
+ }
225
+ }
226
+
227
+ }
228
+ }, [status, modalState?.visible])
229
+
230
+ async function onAllow() {
231
+
232
+ switch (config.onAllow) {
233
+ case 'ask':
234
+ const newStatus = await permissionCtx.manager.get(permissionName, {
235
+ ask: true,
236
+ askOnDenied: true,
237
+ askOnPending: true,
238
+ })
239
+ if (!newStatus.isGranted) {
240
+ onPermissionResolve(newStatus.status)
241
+ }
242
+ break
243
+
244
+ case 'openSettings':
245
+ default:
246
+ Linking.openSettings()
247
+ break
248
+ }
249
+
250
+ }
251
+
252
+ function onDeny() {
253
+ onPermissionResolve()
254
+ }
255
+
256
+ return {
257
+ onAllow,
258
+ onDeny,
259
+ modalId,
260
+ permissionName,
261
+ modalState: {
262
+ ...modalState,
263
+
264
+ },
265
+ currentState,
266
+ config,
267
+
268
+ }
269
+ }
270
+
271
+ type PermissionManagerArgTypes<M extends PermissionManager<any, any>> = {
272
+ perms: M extends PermissionManager<infer P, any> ? P extends Record<string, any> ? P : never : never
273
+ opts: M extends PermissionManager<any, infer O> ? O : never
274
+ }
275
+
276
+ type CreateTypedPermissionHooksArgs<
277
+ M extends PermissionManager<any, any>,
278
+ Args extends PermissionManagerArgTypes<M> = PermissionManagerArgTypes<M>,
279
+ ModalConfig extends PermissionModalsConfig<keyof Args['perms']> = PermissionModalsConfig<keyof Args['perms']>
280
+ > = {
281
+ modalConfig: ModalConfig
282
+ permissionsManager: M
283
+ }
284
+
285
+ export function createTypedPermissionHooks<
286
+ M extends PermissionManager<any, any>,
287
+ Args extends PermissionManagerArgTypes<M> = PermissionManagerArgTypes<M>
288
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
289
+ >(configuration: CreateTypedPermissionHooksArgs<M>) {
290
+
291
+ const _usePermissions = usePermissions as UsePermissions<Exclude<keyof Args['perms'], number | symbol>>
292
+ const _usePermissionModal = usePermissionModal as ((name: keyof Args['perms']) => ReturnType<typeof usePermissionModal>)
293
+
294
+ return {
295
+ usePermissions: _usePermissions,
296
+ usePermissionModal: _usePermissionModal,
297
+
298
+ }
299
+ }
@@ -0,0 +1,20 @@
1
+ import { usePermissions, Provider, createTypedPermissionHooks, usePermissionModal } from './context'
2
+ import {
3
+
4
+ PermissionConfig,
5
+ PermissionModalsConfig,
6
+
7
+ } from './types'
8
+ export {
9
+ usePermissions,
10
+ Provider,
11
+ usePermissionModal,
12
+ createTypedPermissionHooks,
13
+
14
+ }
15
+
16
+ export type {
17
+
18
+ PermissionConfig,
19
+ PermissionModalsConfig,
20
+ }
@@ -0,0 +1,24 @@
1
+ import { PermissionTypes } from '@codeleap/common'
2
+ type NonGrantedPermissionTypes = Exclude<PermissionTypes.PermissionStatus, 'granted'>
3
+
4
+ export type BasePermissionConfig = {
5
+ fullscreenModal?: boolean
6
+ dismissable?: boolean
7
+ title: string
8
+ onAllow: 'openSettings' | 'ask'
9
+
10
+ description: string[]
11
+ icon: string
12
+ }
13
+
14
+ export type PermissionConfig = BasePermissionConfig &
15
+ Partial<
16
+ Record<
17
+ NonGrantedPermissionTypes,
18
+ Partial<BasePermissionConfig>
19
+ >
20
+ >
21
+
22
+ export type PermissionModalsConfig<PermissionNames extends string|number|symbol> = Partial<
23
+ Record<PermissionNames, PermissionConfig>
24
+ >
@@ -0,0 +1,65 @@
1
+ import { onMount, onUpdate, usePrevious, useRef, useState } from '@codeleap/common'
2
+ import { Animated, AppState, AppStateStatus } from 'react-native'
3
+
4
+ export function useAnimateColor(value: string, opts?: Partial<Animated.TimingAnimationConfig>) {
5
+ const iters = useRef(0)
6
+ const [anim] = useState(new Animated.Value(iters.current))
7
+ const _prev = usePrevious(value)
8
+ const prev = _prev || value
9
+
10
+ onUpdate(() => {
11
+ // if (value === prev) return
12
+ const animation = Animated.timing(anim, {
13
+ ...opts,
14
+ toValue: iters.current + 1,
15
+ useNativeDriver: false,
16
+
17
+ })
18
+ animation.start(() => {
19
+ iters.current += 1
20
+ })
21
+
22
+ return () => {
23
+ animation.stop()
24
+
25
+ }
26
+ }, [value])
27
+
28
+ const color = anim.interpolate({
29
+ outputRange: [prev, value],
30
+ inputRange: [iters.current, iters.current + 1],
31
+ })
32
+
33
+ return color
34
+
35
+ }
36
+
37
+ export function useAppState(filter?: AppStateStatus[]) {
38
+ const [appState, setAppState] = useState(() => AppState.currentState)
39
+
40
+ onMount(() => {
41
+ AppState.addEventListener('change', s => {
42
+ if (!filter || filter.includes(s)) {
43
+ setAppState(s)
44
+ }
45
+ })
46
+ })
47
+
48
+ return {
49
+ appState,
50
+ }
51
+ }
52
+
53
+ export function useStaticAnimationStyles<T extends Record<string|number|symbol, any>, K extends keyof T >(obj: T, keys: K[]) {
54
+ const styles = useRef({})
55
+
56
+ if (Object.keys(styles.current).length === 0) {
57
+ const mappedStyles = keys.map((k) => [k, { ...obj[k] }])
58
+
59
+ styles.current = Object.fromEntries(mappedStyles)
60
+ }
61
+
62
+ return styles.current as {
63
+ [P in K] : T[K]
64
+ }
65
+ }