@codeleap/mobile 2.2.10 → 2.3.0
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.
- package/dist/utils/ModalManager/components.js +0 -7
- package/dist/utils/ModalManager/components.js.map +1 -1
- package/package.json +2 -1
- package/src/components/ActionIcon/index.tsx +0 -32
- package/src/components/ActionIcon/styles.ts +0 -97
- package/src/components/ActivityIndicator/index.tsx +0 -50
- package/src/components/ActivityIndicator/styles.ts +0 -68
- package/src/components/Animated.tsx +0 -34
- package/src/components/AutoComplete/index.tsx +0 -163
- package/src/components/AutoComplete/styles.ts +0 -44
- package/src/components/Backdrop/index.tsx +0 -48
- package/src/components/Backdrop/styles.ts +0 -33
- package/src/components/Button/index.tsx +0 -167
- package/src/components/Button/styles.ts +0 -129
- package/src/components/Calendar/index.tsx +0 -65
- package/src/components/Calendar/style.ts +0 -35
- package/src/components/Calendar/types.ts +0 -102
- package/src/components/Checkbox/index.tsx +0 -91
- package/src/components/Checkbox/styles.ts +0 -81
- package/src/components/ContentView/index.tsx +0 -63
- package/src/components/ContentView/styles.ts +0 -24
- package/src/components/Drawer/index.tsx +0 -33
- package/src/components/Drawer/styles.ts +0 -43
- package/src/components/EmptyPlaceholder/index.tsx +0 -88
- package/src/components/EmptyPlaceholder/styles.ts +0 -58
- package/src/components/FileInput/index.tsx +0 -181
- package/src/components/FileInput/styles.ts +0 -15
- package/src/components/Grid/index.tsx +0 -117
- package/src/components/Grid/styles.ts +0 -11
- package/src/components/Icon/index.tsx +0 -69
- package/src/components/Icon/styles.ts +0 -57
- package/src/components/Image/index.tsx +0 -91
- package/src/components/Image/styles.ts +0 -20
- package/src/components/ImageView/Spotlight.tsx +0 -157
- package/src/components/ImageView/component.tsx +0 -38
- package/src/components/ImageView/index.ts +0 -2
- package/src/components/InputLabel/index.tsx +0 -38
- package/src/components/InputLabel/styles.ts +0 -19
- package/src/components/List/PaginationIndicator.tsx +0 -71
- package/src/components/List/index.tsx +0 -114
- package/src/components/List/styles.ts +0 -19
- package/src/components/Modal/index.tsx +0 -218
- package/src/components/Modal/styles.ts +0 -153
- package/src/components/MultiSelect/index.tsx +0 -138
- package/src/components/MultiSelect/styles.ts +0 -18
- package/src/components/MultiSelect/types.ts +0 -42
- package/src/components/Navigation/Navigation.tsx +0 -54
- package/src/components/Navigation/constants.ts +0 -8
- package/src/components/Navigation/index.tsx +0 -3
- package/src/components/Navigation/types.ts +0 -35
- package/src/components/Navigation/utils.tsx +0 -57
- package/src/components/Pager/index.tsx +0 -121
- package/src/components/Pager/styles.ts +0 -81
- package/src/components/RadioInput/index.tsx +0 -106
- package/src/components/RadioInput/styles.ts +0 -67
- package/src/components/Scroll/index.tsx +0 -124
- package/src/components/Scroll/styles.ts +0 -18
- package/src/components/Sections/index.tsx +0 -91
- package/src/components/SegmentedControl/index.tsx +0 -204
- package/src/components/SegmentedControl/styles.ts +0 -89
- package/src/components/Select/index.tsx +0 -167
- package/src/components/Select/styles.ts +0 -62
- package/src/components/Select/types.ts +0 -43
- package/src/components/Slider/Mark.tsx +0 -46
- package/src/components/Slider/Thumb.tsx +0 -29
- package/src/components/Slider/index.tsx +0 -130
- package/src/components/Slider/styles.ts +0 -76
- package/src/components/Slider/types.ts +0 -30
- package/src/components/Switch/index.tsx +0 -91
- package/src/components/Switch/styles.ts +0 -38
- package/src/components/Text/index.tsx +0 -97
- package/src/components/Text/styles.ts +0 -50
- package/src/components/TextInput/index.tsx +0 -319
- package/src/components/TextInput/styles.ts +0 -127
- package/src/components/Touchable/index.tsx +0 -172
- package/src/components/Touchable/styles.ts +0 -28
- package/src/components/View/index.tsx +0 -103
- package/src/components/View/styles.ts +0 -24
- package/src/components/components.ts +0 -42
- package/src/components/defaultStyles.ts +0 -62
- package/src/components/legacy/Modal/index.tsx +0 -163
- package/src/components/legacy/Modal/styles.ts +0 -125
- package/src/components/legacy/Pager/index.tsx +0 -242
- package/src/components/legacy/Pager/styles.ts +0 -51
- package/src/components/legacy/index.ts +0 -2
- package/src/modules/documentPicker.ts +0 -7
- package/src/modules/fastImage.ts +0 -2
- package/src/modules/imageCropPicker.d.ts +0 -497
- package/src/modules/index.d.ts +0 -682
- package/src/modules/reactNavigation.ts +0 -15
- package/src/modules/textInputMask.ts +0 -11
- package/src/modules/types/documentPicker.d.ts +0 -215
- package/src/modules/types/fileTypes.ts +0 -138
- package/src/modules/types/textInputMask.ts +0 -9
- package/src/types/index.ts +0 -1
- package/src/types/utility.ts +0 -9
- package/src/utils/KeyboardAware/context.tsx +0 -75
- package/src/utils/KeyboardAware/index.ts +0 -17
- package/src/utils/KeyboardAware/keyboardHooks.ts +0 -124
- package/src/utils/KeyboardAware/lib/KeyboardAwareFlatList.ts +0 -4
- package/src/utils/KeyboardAware/lib/KeyboardAwareHOC.tsx +0 -618
- package/src/utils/KeyboardAware/lib/KeyboardAwareInterface.ts +0 -13
- package/src/utils/KeyboardAware/lib/KeyboardAwareScrollView.ts +0 -6
- package/src/utils/KeyboardAware/lib/KeyboardAwareSectionList.ts +0 -6
- package/src/utils/KeyboardAware/types.ts +0 -159
- package/src/utils/ModalManager/components.tsx +0 -119
- package/src/utils/ModalManager/context.tsx +0 -260
- package/src/utils/ModalManager/index.ts +0 -16
- package/src/utils/OSAlert.ts +0 -180
- package/src/utils/PermissionManager/context.tsx +0 -302
- package/src/utils/PermissionManager/index.ts +0 -20
- package/src/utils/PermissionManager/types.ts +0 -24
- package/src/utils/hooks.ts +0 -163
- package/src/utils/index.ts +0 -11
- package/src/utils/input.ts +0 -51
- package/src/utils/misc.ts +0 -83
- package/src/utils/notifications.ts +0 -206
- package/src/utils/theme.ts +0 -55
package/src/utils/OSAlert.ts
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
/* eslint no-restricted-imports: 'off' */
|
|
2
|
-
/* eslint prefer-const: 'off' */
|
|
3
|
-
import { Alert, AlertButton } from 'react-native'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Alert.{function} receives three parameters, the last one being an object:
|
|
7
|
-
*
|
|
8
|
-
* @param {string} title text to appear in title
|
|
9
|
-
* @param {string} body text to appear in body
|
|
10
|
-
* @param {object} options array of buttons and callbacks
|
|
11
|
-
*
|
|
12
|
-
* options properties
|
|
13
|
-
* @property {string} name object description
|
|
14
|
-
* @property {function} run callback function to run on press
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
type NativeAlertArgs = Parameters<typeof Alert.alert>
|
|
18
|
-
|
|
19
|
-
export type OSAlertArgs = {
|
|
20
|
-
title: NativeAlertArgs['0']
|
|
21
|
-
body?: NativeAlertArgs['1']
|
|
22
|
-
options?: NativeAlertArgs['2']
|
|
23
|
-
}
|
|
24
|
-
export type AlertEvent = AlertButton['onPress']
|
|
25
|
-
export type OSAlertType = 'info' | 'error' | 'warn' | 'ask'
|
|
26
|
-
export type NamedEvents<E extends string> = Partial<Record<E, AlertEvent>>
|
|
27
|
-
|
|
28
|
-
const currentAlerts = {
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function generateAlertID(from:OSAlertArgs & {type: OSAlertType}) {
|
|
33
|
-
return [
|
|
34
|
-
from.type,
|
|
35
|
-
from.title,
|
|
36
|
-
from.body,
|
|
37
|
-
].join('-')
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function shouldShowAlert(args:OSAlertArgs, type: OSAlertType) {
|
|
41
|
-
const alertId = generateAlertID({ ...args, type })
|
|
42
|
-
|
|
43
|
-
if (!Object.keys(currentAlerts).includes(alertId)) {
|
|
44
|
-
currentAlerts[alertId] = true
|
|
45
|
-
|
|
46
|
-
return alertId
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return ''
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function popAlert(id:string) {
|
|
53
|
-
delete currentAlerts[id]
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function ask({ title, body, options = null }: OSAlertArgs) {
|
|
57
|
-
if (!title) {
|
|
58
|
-
title = 'Quick quetion'
|
|
59
|
-
}
|
|
60
|
-
_OSAlert({
|
|
61
|
-
title,
|
|
62
|
-
body,
|
|
63
|
-
options,
|
|
64
|
-
})
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function warn(args: OSAlertArgs & NamedEvents<'onReject' | 'onAccept'>) {
|
|
68
|
-
const id = shouldShowAlert(args, 'warn')
|
|
69
|
-
|
|
70
|
-
if (!id) return
|
|
71
|
-
let {
|
|
72
|
-
title,
|
|
73
|
-
body,
|
|
74
|
-
onAccept,
|
|
75
|
-
onReject,
|
|
76
|
-
} = args
|
|
77
|
-
|
|
78
|
-
if (!title) {
|
|
79
|
-
title = 'Hang on'
|
|
80
|
-
}
|
|
81
|
-
if (!body) {
|
|
82
|
-
body = 'Are you sure?'
|
|
83
|
-
}
|
|
84
|
-
if (!onReject) {
|
|
85
|
-
onReject = () => null
|
|
86
|
-
}
|
|
87
|
-
_OSAlert({
|
|
88
|
-
title,
|
|
89
|
-
body,
|
|
90
|
-
options: [
|
|
91
|
-
{
|
|
92
|
-
text: 'Cancel',
|
|
93
|
-
onPress: () => {
|
|
94
|
-
popAlert(id)
|
|
95
|
-
onReject()
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
text: 'OK',
|
|
100
|
-
style: 'destructive',
|
|
101
|
-
onPress: () => {
|
|
102
|
-
popAlert(id)
|
|
103
|
-
onAccept?.()
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
],
|
|
107
|
-
})
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function info(args: OSAlertArgs & NamedEvents<'onDismiss'>) {
|
|
111
|
-
const id = shouldShowAlert(args, 'info')
|
|
112
|
-
|
|
113
|
-
if (!id) return
|
|
114
|
-
let {
|
|
115
|
-
title,
|
|
116
|
-
body,
|
|
117
|
-
onDismiss = () => null,
|
|
118
|
-
} = args
|
|
119
|
-
|
|
120
|
-
if (!title) {
|
|
121
|
-
title = 'FYI'
|
|
122
|
-
}
|
|
123
|
-
_OSAlert({
|
|
124
|
-
title,
|
|
125
|
-
body,
|
|
126
|
-
options: [
|
|
127
|
-
{
|
|
128
|
-
text: 'OK',
|
|
129
|
-
onPress: () => {
|
|
130
|
-
popAlert(id)
|
|
131
|
-
onDismiss?.()
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
],
|
|
135
|
-
})
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function OSError(args: OSAlertArgs & NamedEvents<'onDismiss'>) {
|
|
139
|
-
const id = shouldShowAlert(args, 'error')
|
|
140
|
-
|
|
141
|
-
if (!id) return
|
|
142
|
-
|
|
143
|
-
let {
|
|
144
|
-
title,
|
|
145
|
-
body,
|
|
146
|
-
} = args
|
|
147
|
-
|
|
148
|
-
if (!title) {
|
|
149
|
-
title = 'Whoops!'
|
|
150
|
-
}
|
|
151
|
-
if (!body) {
|
|
152
|
-
body = 'Something went wrong'
|
|
153
|
-
}
|
|
154
|
-
_OSAlert({
|
|
155
|
-
title,
|
|
156
|
-
body,
|
|
157
|
-
options: [
|
|
158
|
-
{
|
|
159
|
-
text: 'OK',
|
|
160
|
-
onPress: () => {
|
|
161
|
-
popAlert(id)
|
|
162
|
-
args?.onDismiss?.()
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
],
|
|
166
|
-
})
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function _OSAlert(params: OSAlertArgs) {
|
|
170
|
-
Alert.alert(params.title, params.body, params.options, {
|
|
171
|
-
cancelable: false,
|
|
172
|
-
})
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export const OSAlert = {
|
|
176
|
-
ask,
|
|
177
|
-
warn,
|
|
178
|
-
info,
|
|
179
|
-
error: OSError,
|
|
180
|
-
}
|
|
@@ -1,302 +0,0 @@
|
|
|
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('change', (state) => {
|
|
33
|
-
if (state === 'active') {
|
|
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) => Promise<PermissionTypes.PermissionStatus>
|
|
67
|
-
askMany<T extends PermissionNames, R = TAskManyResults<T>>(
|
|
68
|
-
perms: T[],
|
|
69
|
-
onResolve?: (res:R) => any,
|
|
70
|
-
options?: AskManyOpts<T>
|
|
71
|
-
):Promise<
|
|
72
|
-
R
|
|
73
|
-
>
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export const usePermissions:UsePermissions<any> = () => {
|
|
77
|
-
const modalCtx = ModalManager.useModalContext()
|
|
78
|
-
const permissionCtx = useContext(PermissionContext)
|
|
79
|
-
|
|
80
|
-
function askPermission(name: string, onResolve?: (status: PermissionTypes.PermissionStatus, modalName?: string) => any) {
|
|
81
|
-
return new Promise<PermissionTypes.PermissionStatus>((resolve, reject) => {
|
|
82
|
-
permissionCtx.manager.get(name, {
|
|
83
|
-
ask: false,
|
|
84
|
-
askOnDenied: false,
|
|
85
|
-
askOnPending: false,
|
|
86
|
-
}).then(status => {
|
|
87
|
-
const permissionModalName = `permissions.${name}`
|
|
88
|
-
|
|
89
|
-
if (!status.isGranted) {
|
|
90
|
-
|
|
91
|
-
modalCtx.toggleModal(permissionModalName, true, {
|
|
92
|
-
onPermissionResolve: (status) => {
|
|
93
|
-
modalCtx.toggleModal(permissionModalName, false, {})
|
|
94
|
-
setTimeout(() => {
|
|
95
|
-
onResolve?.(status, permissionModalName)
|
|
96
|
-
|
|
97
|
-
resolve(status)
|
|
98
|
-
}, modalCtx.transitionDuration)
|
|
99
|
-
},
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
} else {
|
|
103
|
-
onResolve?.(status.status as unknown as PermissionTypes.PermissionStatus)
|
|
104
|
-
resolve(status)
|
|
105
|
-
}
|
|
106
|
-
})
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const askMany = async (
|
|
112
|
-
perms: any[],
|
|
113
|
-
onResolve?: (res:any) => any,
|
|
114
|
-
options?: AskManyOpts<any>,
|
|
115
|
-
) => {
|
|
116
|
-
|
|
117
|
-
let prevModal = null
|
|
118
|
-
const results = {}
|
|
119
|
-
|
|
120
|
-
for (const _permission of perms) {
|
|
121
|
-
const permission = _permission.replace('?', '')
|
|
122
|
-
const status = await permissionCtx.manager.get(permission, {
|
|
123
|
-
ask: false,
|
|
124
|
-
askOnDenied: false,
|
|
125
|
-
askOnPending: false,
|
|
126
|
-
})
|
|
127
|
-
results[permission] = status.status
|
|
128
|
-
const permissionModalName = `permissions.${permission}`
|
|
129
|
-
|
|
130
|
-
if (!status.isGranted) {
|
|
131
|
-
let onOpen = null
|
|
132
|
-
|
|
133
|
-
if (prevModal) {
|
|
134
|
-
|
|
135
|
-
onOpen = () => new Promise((resolve) => {
|
|
136
|
-
setTimeout(() => {
|
|
137
|
-
|
|
138
|
-
modalCtx.transition(prevModal, permissionModalName, {
|
|
139
|
-
props: {
|
|
140
|
-
onPermissionResolve: (status) => {
|
|
141
|
-
resolve(status)
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
})
|
|
145
|
-
})
|
|
146
|
-
})
|
|
147
|
-
} else {
|
|
148
|
-
onOpen = () => new Promise((resolve) => {
|
|
149
|
-
setTimeout(() => {
|
|
150
|
-
modalCtx.toggleModal(permissionModalName, true, {
|
|
151
|
-
onPermissionResolve: (status) => {
|
|
152
|
-
resolve(status)
|
|
153
|
-
},
|
|
154
|
-
})
|
|
155
|
-
})
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
results[permission] = await onOpen()
|
|
161
|
-
prevModal = permissionModalName
|
|
162
|
-
|
|
163
|
-
if (!_permission.endsWith('?') && results[permission] !== 'granted') {
|
|
164
|
-
break
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
if (prevModal) {
|
|
169
|
-
|
|
170
|
-
setTimeout(() => {
|
|
171
|
-
modalCtx.toggleModal(prevModal, false, {})
|
|
172
|
-
})
|
|
173
|
-
}
|
|
174
|
-
const res:Parameters<typeof onResolve>[0] = {
|
|
175
|
-
...results,
|
|
176
|
-
overall: Object.values(results).every(x => x === 'granted') ? 'granted' : 'denied',
|
|
177
|
-
}
|
|
178
|
-
onResolve(res)
|
|
179
|
-
return res
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return {
|
|
183
|
-
askPermission,
|
|
184
|
-
askMany,
|
|
185
|
-
...permissionCtx,
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export function usePermissionModal(permissionName: string) {
|
|
190
|
-
|
|
191
|
-
const modalId = `permissions.${permissionName}`
|
|
192
|
-
const modals = ModalManager.useModalContext()
|
|
193
|
-
const permissionCtx = usePermissions()
|
|
194
|
-
const modalState = modals.state[modalId]
|
|
195
|
-
|
|
196
|
-
const currentState = permissionCtx.state[permissionName]
|
|
197
|
-
const status = currentState
|
|
198
|
-
const [debouncedStatus, reset] = useDebounce(status, modals.transitionDuration * 0.5)
|
|
199
|
-
|
|
200
|
-
function getConfig(withStatus) {
|
|
201
|
-
return {
|
|
202
|
-
...permissionCtx.modalConfig[permissionName],
|
|
203
|
-
...permissionCtx.modalConfig[permissionName]?.[withStatus],
|
|
204
|
-
} as PermissionConfig
|
|
205
|
-
}
|
|
206
|
-
const config = getConfig(debouncedStatus)
|
|
207
|
-
|
|
208
|
-
function onPermissionResolve(_status?: PermissionTypes.PermissionStatus) {
|
|
209
|
-
modalState?.props?.onPermissionResolve?.(_status || status)
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
onUpdate(() => {
|
|
214
|
-
|
|
215
|
-
if (modalState?.visible && !!status) {
|
|
216
|
-
|
|
217
|
-
if (status === 'granted') {
|
|
218
|
-
reset()
|
|
219
|
-
onPermissionResolve()
|
|
220
|
-
} else {
|
|
221
|
-
|
|
222
|
-
if (!deepEqual(config, getConfig(status))) {
|
|
223
|
-
|
|
224
|
-
modals.transition(modalId, modalId, {
|
|
225
|
-
props: modalState?.props,
|
|
226
|
-
})
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
}, [status, modalState?.visible])
|
|
232
|
-
|
|
233
|
-
async function onAllow() {
|
|
234
|
-
|
|
235
|
-
switch (config.onAllow) {
|
|
236
|
-
case 'ask':
|
|
237
|
-
const newStatus = await permissionCtx.manager.get(permissionName, {
|
|
238
|
-
ask: true,
|
|
239
|
-
askOnDenied: true,
|
|
240
|
-
askOnPending: true,
|
|
241
|
-
})
|
|
242
|
-
if (!newStatus.isGranted) {
|
|
243
|
-
onPermissionResolve(newStatus.status)
|
|
244
|
-
}
|
|
245
|
-
break
|
|
246
|
-
|
|
247
|
-
case 'openSettings':
|
|
248
|
-
default:
|
|
249
|
-
Linking.openSettings()
|
|
250
|
-
break
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function onDeny() {
|
|
256
|
-
onPermissionResolve()
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
return {
|
|
260
|
-
onAllow,
|
|
261
|
-
onDeny,
|
|
262
|
-
modalId,
|
|
263
|
-
permissionName,
|
|
264
|
-
modalState: {
|
|
265
|
-
...modalState,
|
|
266
|
-
|
|
267
|
-
},
|
|
268
|
-
currentState,
|
|
269
|
-
config,
|
|
270
|
-
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
type PermissionManagerArgTypes<M extends PermissionManager<any, any>> = {
|
|
275
|
-
perms: M extends PermissionManager<infer P, any> ? P extends Record<string, any> ? P : never : never
|
|
276
|
-
opts: M extends PermissionManager<any, infer O> ? O : never
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
type CreateTypedPermissionHooksArgs<
|
|
280
|
-
M extends PermissionManager<any, any>,
|
|
281
|
-
Args extends PermissionManagerArgTypes<M> = PermissionManagerArgTypes<M>,
|
|
282
|
-
ModalConfig extends PermissionModalsConfig<keyof Args['perms']> = PermissionModalsConfig<keyof Args['perms']>
|
|
283
|
-
> = {
|
|
284
|
-
modalConfig: ModalConfig
|
|
285
|
-
permissionsManager: M
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
export function createTypedPermissionHooks<
|
|
289
|
-
M extends PermissionManager<any, any>,
|
|
290
|
-
Args extends PermissionManagerArgTypes<M> = PermissionManagerArgTypes<M>
|
|
291
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
292
|
-
>(configuration: CreateTypedPermissionHooksArgs<M>) {
|
|
293
|
-
|
|
294
|
-
const _usePermissions = usePermissions as UsePermissions<Exclude<keyof Args['perms'], number | symbol>>
|
|
295
|
-
const _usePermissionModal = usePermissionModal as ((name: keyof Args['perms']) => ReturnType<typeof usePermissionModal>)
|
|
296
|
-
|
|
297
|
-
return {
|
|
298
|
-
usePermissions: _usePermissions,
|
|
299
|
-
usePermissionModal: _usePermissionModal,
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
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
|
-
>
|
package/src/utils/hooks.ts
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { onMount, onUpdate, shadeColor, TypeGuards, usePrevious, useRef, useState } from '@codeleap/common'
|
|
2
|
-
import { Animated, AppState, AppStateStatus, Platform, PressableAndroidRippleConfig, BackHandler } 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
|
-
}
|
|
66
|
-
|
|
67
|
-
export type FeedbackConfig =
|
|
68
|
-
| { type: 'opacity'; value?: number }
|
|
69
|
-
| {type: 'highlight'; color?: string; brightness?: number; shiftOpacity?: number}
|
|
70
|
-
| {type: 'none'}
|
|
71
|
-
|
|
72
|
-
type RippleConfig = {
|
|
73
|
-
type: 'ripple'
|
|
74
|
-
config?: PressableAndroidRippleConfig
|
|
75
|
-
iosFallback?: FeedbackConfig
|
|
76
|
-
}
|
|
77
|
-
export type TouchableFeedbackConfig = RippleConfig | FeedbackConfig
|
|
78
|
-
|
|
79
|
-
export type UsePressableFeedbackConfig = {
|
|
80
|
-
disabled?: boolean
|
|
81
|
-
feedbackConfig?: TouchableFeedbackConfig
|
|
82
|
-
hightlightPropertyIn: 'backgroundColor' | 'borderColor' | 'color'
|
|
83
|
-
hightlightPropertyOut: 'backgroundColor' | 'borderColor' | 'color'
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export function usePressableFeedback(styles: any, config:UsePressableFeedbackConfig) {
|
|
87
|
-
const {
|
|
88
|
-
disabled,
|
|
89
|
-
feedbackConfig,
|
|
90
|
-
hightlightPropertyIn = 'backgroundColor',
|
|
91
|
-
hightlightPropertyOut = 'backgroundColor',
|
|
92
|
-
} = config
|
|
93
|
-
const _feedbackConfig = {
|
|
94
|
-
...feedbackConfig,
|
|
95
|
-
}
|
|
96
|
-
const disableFeedback = disabled
|
|
97
|
-
|
|
98
|
-
const rippleEnabled = _feedbackConfig?.type === 'ripple' && !disableFeedback
|
|
99
|
-
const rippleConfig = rippleEnabled ? _feedbackConfig?.config : null
|
|
100
|
-
|
|
101
|
-
function getFeedbackStyle(pressed:boolean) {
|
|
102
|
-
if (disableFeedback) return {}
|
|
103
|
-
let feedbackConfig = { ..._feedbackConfig }
|
|
104
|
-
|
|
105
|
-
if (rippleEnabled && feedbackConfig.type === 'ripple' && Platform.OS === 'ios' && !!_feedbackConfig?.iosFallback) {
|
|
106
|
-
feedbackConfig = feedbackConfig?.iosFallback
|
|
107
|
-
}
|
|
108
|
-
switch (feedbackConfig.type) {
|
|
109
|
-
case 'highlight':
|
|
110
|
-
if (!pressed && hightlightPropertyIn !== hightlightPropertyOut) return {}
|
|
111
|
-
let highlightColorDefault = styles?.[hightlightPropertyIn] || '#0000'
|
|
112
|
-
if (pressed) {
|
|
113
|
-
if (feedbackConfig?.color) {
|
|
114
|
-
highlightColorDefault = feedbackConfig?.color
|
|
115
|
-
} else {
|
|
116
|
-
let opacity = feedbackConfig?.shiftOpacity
|
|
117
|
-
let brightness = feedbackConfig?.brightness
|
|
118
|
-
if (!TypeGuards.isNumber(opacity)) {
|
|
119
|
-
opacity = 1
|
|
120
|
-
}
|
|
121
|
-
if (!TypeGuards.isNumber(brightness)) {
|
|
122
|
-
brightness = 0
|
|
123
|
-
}
|
|
124
|
-
highlightColorDefault = shadeColor(highlightColorDefault, brightness * 100, opacity)
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return {
|
|
128
|
-
[hightlightPropertyOut]: highlightColorDefault,
|
|
129
|
-
}
|
|
130
|
-
break
|
|
131
|
-
case 'opacity':
|
|
132
|
-
return {
|
|
133
|
-
opacity: pressed ? feedbackConfig?.value : 1,
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
case 'none':
|
|
137
|
-
return {}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return {
|
|
142
|
-
getFeedbackStyle,
|
|
143
|
-
rippleConfig,
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export function useBackButton(cb: () => boolean|void, deps = []) {
|
|
148
|
-
onUpdate(() => {
|
|
149
|
-
const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
|
|
150
|
-
const stopBubbling = cb()
|
|
151
|
-
|
|
152
|
-
if (TypeGuards.isBoolean(stopBubbling)) {
|
|
153
|
-
return stopBubbling
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return false
|
|
157
|
-
|
|
158
|
-
})
|
|
159
|
-
return () => {
|
|
160
|
-
subscription.remove()
|
|
161
|
-
}
|
|
162
|
-
}, deps)
|
|
163
|
-
}
|
package/src/utils/index.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export * from './OSAlert'
|
|
2
|
-
export * from './hooks'
|
|
3
|
-
export * from './misc'
|
|
4
|
-
export * from './notifications'
|
|
5
|
-
export * from './ModalManager'
|
|
6
|
-
import * as Permissions from './PermissionManager'
|
|
7
|
-
|
|
8
|
-
export { Permissions }
|
|
9
|
-
export * from './KeyboardAware'
|
|
10
|
-
export * from './input'
|
|
11
|
-
export * from './theme'
|