esoftplay 0.0.141 → 0.0.142-b

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/bin/build.js CHANGED
@@ -234,7 +234,7 @@ if (fs.existsSync(packjson)) {
234
234
  "lib": [\n\
235
235
  "es2017"\n\
236
236
  ],\n\
237
- "module": "es2015",\n\
237
+ "module": "ES2020",\n\
238
238
  "moduleResolution": "node", \n\
239
239
  "noEmitHelpers": true,\n\
240
240
  "noImplicitReturns": true,\n\
@@ -278,9 +278,9 @@ yarn-error.log\n\
278
278
  const AppJS = `import { LibNotification } from 'esoftplay/cache/lib/notification/import';
279
279
  import { UserIndex } from 'esoftplay/cache/user/index/import';
280
280
  import * as Notifications from 'expo-notifications';
281
- import { /* enableFreeze, */ enableScreens } from 'react-native-screens';
281
+ import { enableFreeze, enableScreens } from 'react-native-screens';
282
282
 
283
- /* enableFreeze() */
283
+ enableFreeze()
284
284
  enableScreens()
285
285
 
286
286
  Notifications.addNotificationResponseReceivedListener(x => LibNotification.onAction(x));
@@ -305,6 +305,7 @@ export default UserIndex`;
305
305
  'expo-dev-client',
306
306
  'expo-file-system',
307
307
  'expo-font',
308
+ 'expo-image',
308
309
  'expo-image-manipulator',
309
310
  'expo-image-picker',
310
311
  'expo-linear-gradient',
@@ -313,13 +314,14 @@ export default UserIndex`;
313
314
  'expo-status-bar',
314
315
  'expo-splash-screen',
315
316
  'expo-secure-store',
317
+ // 'expo-sqlite',
316
318
  'expo-updates',
317
319
  'immhelper',
318
320
  'dayjs',
319
321
  'react-fast-compare',
320
322
  'react-native-gesture-handler',
321
323
  'react-native-awesome-gallery',
322
- 'react-native-fast-image',
324
+ // 'react-native-fast-image',
323
325
  'react-native-keyboard-controller',
324
326
  'react-native-mmkv',
325
327
  'react-native-pan-pinch-view',
package/error.ts CHANGED
@@ -14,14 +14,15 @@ function getTime() {
14
14
  const isoStringWithGMTPlus7 = new Date(adjustedDate).toISOString();
15
15
  return isoStringWithGMTPlus7.replace('T', ' ').replace(/\.[0-9]+Z/g, "")
16
16
  }
17
- // const defaultErrorHandler = ErrorUtils?.getGlobalHandler?.()
17
+ const defaultErrorHandler = ErrorUtils?.getGlobalHandler?.()
18
18
 
19
19
  const myErrorHandler = (e: any, isFatal: any) => {
20
- if (!expoConfig?.packagerOpts)
20
+ if (!__DEV__)
21
21
  setError(e)
22
- // defaultErrorHandler?.(e, isFatal)
22
+ defaultErrorHandler?.(e, isFatal)
23
23
  }
24
24
 
25
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/error.md#setError) untuk melihat dokumentasi*/
25
26
  export function setError(error?: any) {
26
27
  const config = esp?.config?.();
27
28
  const routes = UserRoutes?.state()?.get?.();
@@ -42,6 +43,7 @@ export function setError(error?: any) {
42
43
  }
43
44
 
44
45
 
46
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/error.md#reportApiError) untuk melihat dokumentasi*/
45
47
  export function reportApiError(fetch: any, error: any) {
46
48
  let routes = UserRoutes?.state?.()?.get?.()
47
49
  let lastIndex = routes?.routes?.length - 1 ?? 0
@@ -59,7 +61,7 @@ export function reportApiError(fetch: any, error: any) {
59
61
  'fetch: ' + String(JSON.stringify(fetch || {}, undefined, 2)).replace(/[\[\]\{\}\"]+/g, ''),
60
62
  ].join('\n')
61
63
 
62
- if (expoConfig?.packagerOpts) {
64
+ if (__DEV__) {
63
65
  let post = {
64
66
  text: msg,
65
67
  chat_id: '-1001737180019',
@@ -79,6 +81,7 @@ export function reportApiError(fetch: any, error: any) {
79
81
  }
80
82
  }
81
83
 
84
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/error.md#sendTm) untuk melihat dokumentasi*/
82
85
  export function sendTm(message: string, chat_id?: string, bot?: string, res?: (result: any) => void): void {
83
86
  let _chatids: string[] = []
84
87
  if (chat_id) {
@@ -123,9 +126,15 @@ export function getError() {
123
126
  // remove error that unsolved
124
127
  } else if (msg.includes(`SyntaxError: JSON Parse error: Unexpected token:`)) {
125
128
  // remove error that unsolved
129
+ } else if (msg.includes(`FirebaseError: [code=invalid-argument]`)) {
130
+ let post = {
131
+ text: msg,
132
+ chat_id: '-1001737180019',
133
+ disable_web_page_preview: true
134
+ }
135
+ new LibCurl()?.custom?.('https://api.telegram.org/bot923808407:AAEFBlllQNKCEn8E66fwEzCj5vs9qGwVGT4/sendMessage', post)
126
136
  } else {
127
137
  const telegramIds = config?.errorReport?.telegramIds || {}
128
-
129
138
  Object.values(telegramIds).forEach?.(id => {
130
139
  let post = {
131
140
  text: msg,
@@ -140,4 +149,4 @@ export function getError() {
140
149
  }
141
150
  })
142
151
  }
143
- //ErrorUtils[REMOVED by esoftplay web].setGlobalHandler(myErrorHandler)
152
+ ErrorUtils.setGlobalHandler(myErrorHandler)
@@ -3,7 +3,9 @@
3
3
  import { InteractionManager } from 'react-native'
4
4
 
5
5
  let updater: any
6
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/autoreload.md) untuk melihat dokumentasi*/
6
7
  export default {
8
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/autoreload.md#set) untuk melihat dokumentasi*/
7
9
  set(callback: () => void, duration?: number): void {
8
10
  if (updater != undefined) {
9
11
  clearInterval(updater)
@@ -15,6 +17,7 @@ export default {
15
17
  });
16
18
  }, duration || 6000)
17
19
  },
20
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/autoreload.md#clear) untuk melihat dokumentasi*/
18
21
  clear(): void {
19
22
  if (updater != undefined) {
20
23
  clearInterval(updater)
@@ -39,6 +39,7 @@ export interface LibCarrouselState {
39
39
  childrenLength: number,
40
40
  }
41
41
 
42
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/carrousel.md) untuk melihat dokumentasi*/
42
43
  export default class m extends LibComponent<LibCarrouselProps, LibCarrouselState> {
43
44
 
44
45
  static defaultProps = {
@@ -18,6 +18,7 @@ export interface LibCarrousel_snapProps {
18
18
  initialPage?: number,
19
19
  renderItem: (item: any, key: number | string, itemWidth: number) => any
20
20
  }
21
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/carrousel_snap.md) untuk melihat dokumentasi*/
21
22
  export default function m(props: LibCarrousel_snapProps): any {
22
23
  const LibFocus = useRef(esp.mod("lib/focus")).current
23
24
  const autoCycle = props.autoCycle || false
@@ -3,7 +3,7 @@
3
3
  import useSafeState from 'esoftplay/state';
4
4
  import React, { useEffect } from 'react';
5
5
  import { Pressable, ViewStyle } from 'react-native';
6
- import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
6
+ import Animated, { ReduceMotion, runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
7
7
 
8
8
 
9
9
  export interface LibCollapsArgs {
@@ -15,6 +15,7 @@ export interface LibCollapsProps {
15
15
  onToggle?: (expanded: boolean) => void,
16
16
  style?: ViewStyle
17
17
  }
18
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/collaps.md) untuk melihat dokumentasi*/
18
19
  export default function m(props: LibCollapsProps): any {
19
20
  const [expand, setExpand] = useSafeState(props.show)
20
21
  const opacity = useSharedValue(0);
@@ -34,7 +35,7 @@ export default function m(props: LibCollapsProps): any {
34
35
  }, [expand])
35
36
 
36
37
  const toggleAnimation = () => {
37
- opacity.value = withTiming(opacity.value === 0 ? 1 : 0, { duration: 300 }, (status) => {
38
+ opacity.value = withTiming(opacity.value === 0 ? 1 : 0, { duration: 300, reduceMotion: ReduceMotion.Never }, (status) => {
38
39
  if (opacity.value == 0 && status) {
39
40
  runOnJS(setExpand)(false)
40
41
  }
@@ -2,6 +2,7 @@
2
2
  import { Component } from "react";
3
3
  import isEqual from "react-fast-compare";
4
4
 
5
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/component.md) untuk melihat dokumentasi*/
5
6
  export default class m<K, S> extends Component<K, S> {
6
7
  private _isMounted: boolean = false;
7
8
 
@@ -0,0 +1,178 @@
1
+ // withHooks
2
+ import { LibNavigationRoutes } from 'esoftplay';
3
+ import { LibNavigation } from 'esoftplay/cache/lib/navigation/import';
4
+ import { LibObject } from 'esoftplay/cache/lib/object/import';
5
+ import { LibUtils } from 'esoftplay/cache/lib/utils/import';
6
+ import { EspRouterInterface } from 'esoftplay/cache/routers';
7
+ import esp from 'esoftplay/esp';
8
+ import useGlobalState from 'esoftplay/global';
9
+ import React, { createElement, ReactElement } from 'react';
10
+ import { ScrollView, Text, View } from "react-native";
11
+
12
+ export interface RNTypes extends EspRouterInterface {
13
+ "View": typeof View,
14
+ "Text": typeof Text,
15
+ "ScrollView": typeof ScrollView,
16
+ // "TouchableOpacity": typeof TouchableOpacity,
17
+ // "TextInput": typeof TextInput,
18
+ }
19
+
20
+ const formState = useGlobalState({})
21
+
22
+ function buildUIFromJSON(json: any): ReactElement {
23
+ const { component, props } = json;
24
+
25
+ let children = null;
26
+ if (props?.children) {
27
+ if (Array.isArray(props?.children)) {
28
+ children = props?.children?.map?.((child: any) => buildUIFromJSON(child));
29
+ } else if (typeof props.children != 'string') {
30
+ children = buildUIFromJSON(props?.children);
31
+ } else {
32
+ children = props.children;
33
+ }
34
+ }
35
+ let _props = props
36
+
37
+ if (props) {
38
+ Object.keys(props).map((key) => {
39
+ if (typeof props[key] == 'string' && String(props[key]).includes("#esp|")) {
40
+ const cleanFunction = (props[key]).replace("#esp|", "")
41
+ const [modules, func, args] = cleanFunction.split("|")
42
+ _props[key] = () => {
43
+ esp.mod(modules)[func](...eval(args))
44
+ }
45
+ } else if (typeof props[key] == 'string' && String(props[key]).includes("#espProp|")) {
46
+ const cleanFunction = (props[key]).replace("#espProp|", "")
47
+ const [modules, func, args] = cleanFunction.split("|")
48
+ _props[key] = () => {
49
+ esp.modProp(modules)[func](...eval(args))
50
+ }
51
+ } else if (typeof props[key] == 'string' && String(props[key]).includes("#action.")) {
52
+ const cleanFunction = (props[key]).replace("#action.", "")
53
+ const [func, argument] = cleanFunction.split('.')
54
+ _props[key] = () => {
55
+ action[func](eval(argument))
56
+ }
57
+ } else if (typeof props[key] == 'string' && String(props[key]).includes("#form.")) {
58
+ const cleanForm = (props[key]).replace("#form.", "")
59
+ const [type, postkey] = cleanForm.split('.')
60
+ if (type == 'input') {
61
+ _props[key] = (input: string) => {
62
+ formState.set(LibObject.set(formState.get(), input)(postkey))
63
+ }
64
+ }
65
+ if (type == 'select') {
66
+ console.log(type, postkey, key)
67
+ const [_key, _value] = postkey.split(":")
68
+ _props[key] = () => {
69
+ formState.set(LibObject.set(formState.get(), _value)(_key))
70
+ }
71
+ }
72
+ } else {
73
+ _props[key] = props[key]
74
+ }
75
+ })
76
+ }
77
+
78
+ // Create the element based on the component type
79
+ if (component?.includes?.('/')) {
80
+ return esp.mod(component)(_props);
81
+ } else {
82
+ return createElement("RCT" + component, { ..._props, children });
83
+ }
84
+ }
85
+
86
+
87
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/compose.md) untuk melihat dokumentasi*/
88
+ export default function m({ schema }: { schema: any }): ReactElement {
89
+ return buildUIFromJSON(schema)
90
+ }
91
+
92
+ const action: any = {
93
+ "navigate": (args: any[]) => esp.mod("lib/navigation").navigate(args[0], args[1]),
94
+ "replace": (args: any[]) => esp.mod("lib/navigation").replace(args[0], args[1]),
95
+ "back": (args: any[]) => esp.mod("lib/navigation").back(),
96
+ "copy": (args: any[]) => {
97
+ esp.mod("lib/utils").copyToClipboard(JSON.stringify(args))
98
+ esp.modProp("lib/toast").show(args + " copied!")
99
+ },
100
+ "curl": (args: any[]) => {
101
+ esp.mod("lib/progress").show("Please Wait..")
102
+ let post = args?.[1]
103
+ try {
104
+ post = JSON.parse(args?.[1])
105
+ } catch (error) {
106
+ post = args?.[1]
107
+ }
108
+ post = Object.assign({}, post, formState.get())
109
+ new (esp.mod('lib/curl'))(args[0], post, (res, msg) => {
110
+ esp.modProp("lib/toast").show(msg)
111
+ esp.mod("lib/progress").hide()
112
+ }, (err) => {
113
+ esp.modProp("lib/toast").show(err.message)
114
+ esp.mod("lib/progress").hide()
115
+ })
116
+ }
117
+ }
118
+
119
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/compose.md#forms) untuk melihat dokumentasi*/
120
+ export const forms = {
121
+ select: (postKey: string, value: string) => `#form.select.${postKey}:${value}`,
122
+ input: (postKey: string) => `#form.input.${postKey}`,
123
+ }
124
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/compose.md#actions) untuk melihat dokumentasi*/
125
+ export const actions = {
126
+ navigate: (module: LibNavigationRoutes, params: any) => {
127
+ LibNavigation.navigate(module, params)
128
+ },
129
+ replace: (module: LibNavigationRoutes, params: any) => {
130
+ LibNavigation.replace(module, params)
131
+ },
132
+ back: () => {
133
+ LibNavigation.back()
134
+ },
135
+ copy: (args: string) => {
136
+ LibUtils.copyToClipboard(args)
137
+ esp.modProp("lib/toast").show(args + " copied!")
138
+ },
139
+ curl: (uri: string, post?: any) => {
140
+ new (esp.mod('lib/curl'))(uri, post, (res, msg) => {
141
+ esp.modProp("lib/toast").show(msg)
142
+ }, (err) => {
143
+ esp.modProp("lib/toast").show(err.message)
144
+ }, 1)
145
+ }
146
+ }
147
+
148
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/lib/compose.md#build) untuk melihat dokumentasi*/
149
+ export function build<T extends keyof RNTypes>(cmpn: T, props: React.ComponentProps<RNTypes[T]>): any {
150
+ let obj: any = {};
151
+ obj.component = cmpn;
152
+ let _props = props
153
+ if (props) {
154
+ Object.keys(props).map((key) => {
155
+ if (typeof props[key] == 'function') {
156
+ _props[key] = `@clientFn` + String(props[key])
157
+ } else {
158
+ _props[key] = props[key]
159
+ }
160
+ })
161
+ }
162
+ obj.props = { ..._props }; // Shallow copy the props
163
+
164
+ // If there are children, process them
165
+ if (props?.children) {
166
+ if (Array.isArray(props.children)) {
167
+ // If children is an array, recursively build each child
168
+ obj.props.children = props.children.map((child: any) =>
169
+ typeof child === 'string' ? child : build(child.component, child.props)
170
+ );
171
+ } else if (typeof props.children !== 'string') {
172
+ // If there's only one child and it's not a string, build it
173
+ obj.props.children = build(props.children.component, props.children.props);
174
+ }
175
+ }
176
+
177
+ return obj;
178
+ }
@@ -307,7 +307,7 @@ export default class m {
307
307
  if (upload) {
308
308
  let fd = new FormData();
309
309
  Object.keys(post).map(function (key) {
310
- if (key !== undefined) {
310
+ if (key !== undefined && post[key] !== undefined) {
311
311
  fd.append(key, post[key])
312
312
  }
313
313
  });
@@ -1,9 +1,9 @@
1
1
  // withHooks
2
2
 
3
3
  import esp from 'esoftplay/esp';
4
+ import useSafeState from 'esoftplay/state';
4
5
  import React, { useEffect, useRef } from 'react';
5
- import { Linking, Pressable, Text, View } from 'react-native';
6
- import WebView from 'react-native-webview';
6
+ import { Linking } from 'react-native';
7
7
 
8
8
 
9
9
  export interface LibCustomArgs {
@@ -12,34 +12,41 @@ export interface LibCustomArgs {
12
12
  export interface LibCustomProps {
13
13
 
14
14
  }
15
+
16
+
17
+ /**
18
+ *
19
+ json_to_view
20
+ https://api.test.bbo.co.id/main?module=lib.custom&link=https%3A%2F%2Ftest.bbo.co.id%2Fsaya-tidak-bisa-login-akun-bbo_432.htm
21
+
22
+ deeplink
23
+ https://api.test.bbo.co.id/main?module=lib.custom&link=bbt%3A%2F%2Ftest.bbo.co.id%2Fjual%2Farcanealley2024
24
+ */
15
25
  export default function m(props: LibCustomProps): any {
16
- const LibIcon = useRef(esp.mod("lib/icon")).current
26
+ const LibCompose = useRef(esp.mod("lib/compose")).current
17
27
 
18
28
  const { url, title } = esp.mod("lib/navigation").getArgsAll(props)
19
-
29
+ const [schema, setSchema] = useSafeState<any>(null)
30
+
20
31
  useEffect(() => {
21
32
  if (!String(url).startsWith("http")) {
22
33
  Linking.openURL(url)
23
34
  esp.mod("lib/navigation").back()
35
+ } else {
36
+ new (esp.mod("lib/curl"))(url, null,
37
+ (res, msg) => {
38
+ setSchema(res)
39
+ },
40
+ (err) => {
41
+ esp.modProp("lib/toast").show(err?.message)
42
+ esp.mod("lib/navigation").back()
43
+ }
44
+ )
24
45
  }
25
46
  }, [])
26
47
 
27
- if (String(url).startsWith("http"))
28
- return (
29
- <View style={{ flex: 1 }} >
30
- <View style={[{ height: 60 + esp.mod("lib/style").STATUSBAR_HEIGHT, paddingTop: esp.mod("lib/style").STATUSBAR_HEIGHT, backgroundColor: "#fff", flexDirection: 'row', alignItems: 'center', marginBottom: 3 }, esp.mod("lib/style").elevation(3)]} >
31
- <Pressable onPress={() => esp.mod("lib/navigation").back()} style={{ height: 60, width: 60, alignItems: 'center', justifyContent: 'center' }} >
32
- <LibIcon name='arrow-left' />
33
- </Pressable>
34
- <Text style={{ fontWeight: "bold", marginLeft: 0 }}>{title ? title : ""}</Text>
35
- </View>
36
- <WebView
37
- style={{ flex: 1 }}
38
- source={{ uri: url }}
39
- startInLoadingState={true}
40
- />
41
- </View>
42
- )
48
+ if (String(url).startsWith("http") && schema)
49
+ return <LibCompose schema={schema} />
43
50
  else
44
51
  return null
45
52
  }
@@ -0,0 +1,50 @@
1
+ // withHooks
2
+
3
+ import useSafeState from 'esoftplay/state';
4
+ import React, { ReactElement } from 'react';
5
+ import { ViewStyle } from 'react-native';
6
+ import Animated, { Extrapolation, interpolate, runOnJS, SharedValue, useAnimatedReaction, useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
7
+
8
+
9
+ export interface LibFadescrollArgs {
10
+
11
+ }
12
+
13
+ export interface LibFadescrollProps {
14
+ scrollController: SharedValue<number>,
15
+ style?: ViewStyle,
16
+ children?: ReactElement,
17
+ interpolateOpacity: number[],
18
+ interpolateScroll: number[],
19
+ }
20
+ export default function m(props: LibFadescrollProps): any {
21
+ let opacity = useSharedValue(0)
22
+ const [pointerEvents, setPointerEvents] = useSafeState<any>('none')
23
+ const { scrollController, interpolateScroll, interpolateOpacity } = props
24
+
25
+ // Animated style for opacity based on external scrollController value
26
+ const animatedStyle = useAnimatedStyle(() => {
27
+ opacity.value = interpolate(
28
+ scrollController.value,
29
+ interpolateScroll,
30
+ interpolateOpacity,
31
+ Extrapolation.CLAMP
32
+ );
33
+
34
+ return { opacity: opacity.value };
35
+ });
36
+
37
+ useAnimatedReaction(
38
+ () => opacity.value,
39
+ (currentValue) => {
40
+ runOnJS(setPointerEvents)(currentValue == 1 ? 'auto' : 'none');
41
+ },
42
+ []
43
+ );
44
+
45
+ return (
46
+ <Animated.View style={[props.style, animatedStyle]} pointerEvents={pointerEvents}>
47
+ {props.children}
48
+ </Animated.View>
49
+ );
50
+ }
@@ -7,7 +7,7 @@ import { LibProgress } from 'esoftplay/cache/lib/progress/import';
7
7
  import { LibStyle } from 'esoftplay/cache/lib/style/import';
8
8
  import esp from 'esoftplay/esp';
9
9
  import useGlobalState from 'esoftplay/global';
10
- import { Camera } from 'expo-camera';
10
+ import { CameraView } from 'expo-camera';
11
11
  import * as ImageManipulator from 'expo-image-manipulator';
12
12
  import { SaveFormat } from 'expo-image-manipulator';
13
13
  import * as ImagePicker from 'expo-image-picker';
@@ -80,7 +80,7 @@ class m extends LibComponent<LibImageProps, LibImageState> {
80
80
  constructor(props: LibImageProps) {
81
81
  super(props);
82
82
  this.state = {
83
- type: Camera.Constants.Type.back,
83
+ type: 'back',
84
84
  loading: false,
85
85
  image: null,
86
86
  flashLight: 'off'
@@ -302,17 +302,17 @@ class m extends LibComponent<LibImageProps, LibImageState> {
302
302
  return (
303
303
  <View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }} >
304
304
  <View style={{ flex: 1 }} >
305
- <Camera
305
+ <CameraView
306
306
  ref={(camera: any) => this.camera = camera}
307
- type={type}
307
+ facing={type}
308
308
  ratio={'4:3'}
309
- flashMode={flashLight}
309
+ flash={flashLight}
310
310
  zoom={0.1}
311
311
  style={{ height: LibStyle.width * 4 / 3, width: LibStyle.width }}>
312
312
  <View style={{ height: height, width: width, backgroundColor: 'transparent' }} >
313
- {image ? <Image source={image} style={{ height: LibStyle.width * 4 / 3, width: width, resizeMode: 'cover', transform: [{ scaleX: this.state.type == Camera.Constants.Type.back ? 1 : -1 }] }} /> : null}
313
+ {image ? <Image source={image} style={{ height: LibStyle.width * 4 / 3, width: width, resizeMode: 'cover', transform: [{ scaleX: this.state.type == 'back' ? 'front' : 'back' }] }} /> : null}
314
314
  </View>
315
- </Camera>
315
+ </CameraView>
316
316
  <View style={{ position: 'absolute', top: 10 + LibStyle.STATUSBAR_HEIGHT, left: 10 }} >
317
317
  <TouchableOpacity onPress={() => this.setState({ flashLight: flashLight == 'on' ? 'off' : 'on' })} >
318
318
  <LibIcon color={'white'} size={24} name={flashLight == 'on' ? 'flash' : "flash-off"} />
@@ -324,11 +324,11 @@ class m extends LibComponent<LibImageProps, LibImageState> {
324
324
  {
325
325
  image ?
326
326
  <TouchableOpacity onPress={() => this.setState({ image: false })} >
327
- <LibIcon.Ionicons name='ios-close-circle' style={{ fontSize: 40, color: 'white' }} />
327
+ <LibIcon.Ionicons name='close-circle' style={{ fontSize: 40, color: 'white' }} />
328
328
  </TouchableOpacity>
329
329
  :
330
- <TouchableOpacity onPress={() => this.setState({ type: this.state.type === Camera.Constants.Type.back ? Camera.Constants.Type.front : Camera.Constants.Type.back })} >
331
- <LibIcon.Ionicons name='ios-refresh-circle' style={{ fontSize: 40, color: 'white' }} />
330
+ <TouchableOpacity onPress={() => this.setState({ type: this.state.type === 'back' ? 'front' : 'back' })} >
331
+ <LibIcon.Ionicons name='refresh-circle' style={{ fontSize: 40, color: 'white' }} />
332
332
  </TouchableOpacity>
333
333
  }
334
334
  </View>
@@ -358,7 +358,7 @@ class m extends LibComponent<LibImageProps, LibImageState> {
358
358
  clearTimeout(timer)
359
359
  });
360
360
  }} >
361
- <LibIcon.Ionicons name='ios-checkmark-circle' style={{ fontSize: 40, color: 'white' }} />
361
+ <LibIcon.Ionicons name='checkmark-circle' style={{ fontSize: 40, color: 'white' }} />
362
362
  </TouchableOpacity>
363
363
  :
364
364
  <TouchableOpacity onPress={() => {
@@ -369,7 +369,7 @@ class m extends LibComponent<LibImageProps, LibImageState> {
369
369
  });
370
370
  clearTimeout(timer)
371
371
  }} >
372
- <LibIcon.Ionicons name='ios-close-circle' style={{ fontSize: 40, color: 'white' }} />
372
+ <LibIcon.Ionicons name='close-circle' style={{ fontSize: 40, color: 'white' }} />
373
373
  </TouchableOpacity>
374
374
  }
375
375
  </View>
@@ -12,13 +12,13 @@ export interface LibImage_cropProps {
12
12
 
13
13
  }
14
14
  export default function m(props: LibImage_cropProps): any {
15
- const LibIcon = useRef(esp.mod("lib/icon")).current
16
- const LibNavigation = useRef(esp.mod("lib/navigation")).current
17
- const LibProgress = useRef(esp.mod("lib/progress")).current
18
- const LibStatusbar = useRef(esp.mod("lib/statusbar")).current
19
- const LibStyle = useRef(esp.mod("lib/style")).current
20
- const LibTextstyle = useRef(esp.mod("lib/textstyle")).current
21
- const LibToastProperty = useRef(esp.modProp("lib/toast")).current
15
+ const LibIcon = useRef(esp.mod("lib/icon")).current
16
+ const LibNavigation = useRef(esp.mod("lib/navigation")).current
17
+ const LibProgress = useRef(esp.mod("lib/progress")).current
18
+ const LibStatusbar = useRef(esp.mod("lib/statusbar")).current
19
+ const LibStyle = useRef(esp.mod("lib/style")).current
20
+ const LibTextstyle = useRef(esp.mod("lib/textstyle")).current
21
+ const LibToastProperty = useRef(esp.modProp("lib/toast")).current
22
22
 
23
23
  const { image, ratio, forceCrop, message } = LibNavigation.getArgsAll(props)
24
24
  const [_image, setImage] = useSafeState(image)
@@ -43,6 +43,8 @@ export default function m(props: LibImage_cropProps): any {
43
43
  ratioSize[1] = _ratio[1] / _ratio[0] * minimalRatioSize
44
44
  }
45
45
 
46
+
47
+
46
48
  function resize(image: string) {
47
49
  LibProgress.show(esp.lang("lib/image_crop", "waiting"))
48
50
  Image.getSize(image, async (actualWidth, actualHeight) => {
@@ -179,37 +181,7 @@ export default function m(props: LibImage_cropProps): any {
179
181
  return (
180
182
  <View style={{ flex: 1, backgroundColor: "#000" }} key={counter} >
181
183
  <LibStatusbar style="light" />
182
- <Image
183
- ref={imageRef}
184
- style={{ resizeMode: "contain", marginTop: marginTop, height: size, width: LibStyle.width }} source={{ uri: _image }} />
185
- <View style={{ flex: 1, marginTop: -(LibStyle.height - marginTop - (LibStyle.isIphoneX ? 35 : 0)) + LibStyle.STATUSBAR_HEIGHT, alignItems: 'center', justifyContent: 'center' }} >
186
- <PanPinchView
187
- key={_image}
188
- minScale={0.5}
189
- containerDimensions={{
190
- width: LibStyle.width,
191
- height: size,
192
- }}
193
- contentDimensions={{
194
- width: ratioSize[0],
195
- height: ratioSize[1]
196
- }}
197
- // style={{ backgroundColor: "transparent", flex: undefined, width: LibStyle.height * 100, height: LibStyle.height * 100, alignSelf: 'center', justifyContent: 'center' }}
198
- maxScale={2}>
199
- {/* <> */}
200
- {/* <View style={{ backgroundColor: "rgba(0,0,0,0.5 )", flex: 1 }} />
201
- <View style={{ flexDirection: "row" }} >
202
- <View style={{ backgroundColor: "rgba(0,0,0,0.5 )", flex: 1 }} /> */}
203
- <View ref={viewRef} style={{ height: ratioSize[1], width: ratioSize[0], backgroundColor: 'transparent', borderWidth: 1.5, borderColor: "white", borderStyle: 'dashed' }} >
204
- <View style={{ flex: 1, backgroundColor: 'transparent', borderWidth: 1.5, borderColor: "black", borderStyle: 'dashed' }} />
205
- </View>
206
- {/* <View style={{ backgroundColor: "rgba(0,0,0,0.5 )", flex: 1 }} />
207
- </View>
208
- <View style={{ backgroundColor: "rgba(0,0,0,0.5 )", flex: 1 }} /> */}
209
- {/* </> */}
210
- </PanPinchView>
211
- </View>
212
- <View style={{ position: "absolute", top: LibStyle.STATUSBAR_HEIGHT, left: 0, right: 0, height: 50, flexDirection: "row", justifyContent: 'space-between' }} >
184
+ <View style={{ marginTop: LibStyle.STATUSBAR_HEIGHT, height: 50, flexDirection: "row", justifyContent: 'space-between' }} >
213
185
  <TouchableOpacity
214
186
  onPress={() => LibNavigation.back()}
215
187
  style={{ height: 50, width: 50, alignItems: 'center', justifyContent: 'center' }} >
@@ -228,28 +200,62 @@ export default function m(props: LibImage_cropProps): any {
228
200
  </TouchableOpacity>
229
201
  </View>
230
202
  </View>
231
- {
232
- // hint &
233
- <Pressable
234
- onPress={() => setHint(!hint)}
235
- style={{ opacity: hint ? 1 : 0, position: 'absolute', left: 0, right: 0, bottom: 50, backgroundColor: 'rgba(0,0,0,0.5)', alignItems: 'center', justifyContent: 'center', padding: 30 }} >
236
- <Text style={{ color: "white", textAlign: 'center' }} >{message || esp.lang("lib/image_crop", "text_msg")}</Text>
237
- </Pressable>
238
- }
239
- {
240
- (!forceCrop || cropCount > 0) &&
241
- <View style={{ position: "absolute", bottom: 10, left: 0, right: 0 }} >
242
- <TouchableOpacity
243
- onPress={() => {
244
- Image.getSize(_image, (width, height) => {
245
- LibNavigation.sendBackResult({ uri: _image, width, height }, LibNavigation.getResultKey(props))
246
- }, () => { })
203
+ <View style={{ flex: 1 }} >
204
+
205
+ <Image
206
+ ref={imageRef}
207
+ style={{ resizeMode: "contain", height: size, width: LibStyle.width }} source={{ uri: _image }} />
208
+ <View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, alignItems: 'center', justifyContent: 'center' }} >
209
+ <PanPinchView
210
+ key={_image}
211
+ minScale={0.5}
212
+ containerDimensions={{
213
+ width: LibStyle.width,
214
+ height: size,
247
215
  }}
248
- style={{ height: 50, alignItems: 'center', justifyContent: 'center', backgroundColor: 'rgba(255,255,255,0.3)' }} >
249
- <LibTextstyle textStyle="body" text={esp.lang("lib/image_crop", "btn_save")} style={{ color: "white" }} />
250
- </TouchableOpacity>
216
+ contentDimensions={{
217
+ width: ratioSize[0],
218
+ height: ratioSize[1]
219
+ }}
220
+ // style={{ backgroundColor: "transparent", flex: undefined, width: LibStyle.height * 100, height: LibStyle.height * 100, alignSelf: 'center', justifyContent: 'center' }}
221
+ maxScale={2}>
222
+ {/* <> */}
223
+ {/* <View style={{ backgroundColor: "rgba(0,0,0,0.5 )", flex: 1 }} />
224
+ <View style={{ flexDirection: "row" }} >
225
+ <View style={{ backgroundColor: "rgba(0,0,0,0.5 )", flex: 1 }} /> */}
226
+ <View ref={viewRef} style={{ height: ratioSize[1], width: ratioSize[0], backgroundColor: 'transparent', borderWidth: 1, borderColor: "white", borderStyle: 'dashed', zIndex: 100 }} >
227
+ <View style={{ flex: 1, backgroundColor: 'transparent', borderWidth: 1, borderColor: "black", borderStyle: 'dashed' }} />
228
+ </View>
229
+ {/* <View style={{ backgroundColor: "rgba(0,0,0,0.5 )", flex: 1 }} />
230
+ </View>
231
+ <View style={{ backgroundColor: "rgba(0,0,0,0.5 )", flex: 1 }} /> */}
232
+ {/* </> */}
233
+ </PanPinchView>
251
234
  </View>
252
- }
235
+
236
+ {
237
+ // hint &
238
+ <Pressable
239
+ onPress={() => setHint(!hint)}
240
+ style={{ opacity: hint ? 1 : 0, position: 'absolute', left: 0, right: 0, bottom: 50, backgroundColor: 'rgba(0,0,0,0.5)', alignItems: 'center', justifyContent: 'center', padding: 30 }} >
241
+ <Text style={{ color: "white", textAlign: 'center' }} >{message || esp.lang("lib/image_crop", "text_msg")}</Text>
242
+ </Pressable>
243
+ }
244
+ {
245
+ (!forceCrop || cropCount > 0) &&
246
+ <View style={{ position: "absolute", bottom: 10, left: 0, right: 0 }} >
247
+ <TouchableOpacity
248
+ onPress={() => {
249
+ Image.getSize(_image, (width, height) => {
250
+ LibNavigation.sendBackResult({ uri: _image, width, height }, LibNavigation.getResultKey(props))
251
+ }, () => { })
252
+ }}
253
+ style={{ height: 50, alignItems: 'center', justifyContent: 'center', backgroundColor: 'rgba(255,255,255,0.3)' }} >
254
+ <LibTextstyle textStyle="body" text={esp.lang("lib/image_crop", "btn_save")} style={{ color: "white" }} />
255
+ </TouchableOpacity>
256
+ </View>
257
+ }
258
+ </View>
253
259
  </View>
254
260
  )
255
261
  }
@@ -130,6 +130,7 @@ export default class m extends LibComponent<LibInfiniteProps, LibInfiniteState>
130
130
  this.isStop = true
131
131
  this.setState((state: LibInfiniteState, props: LibInfiniteProps) => {
132
132
  return {
133
+ isStop: this.isStop,
133
134
  error: this.props.error || esp.lang("lib/infinite", "empty_data"),
134
135
  data: page == 0
135
136
  ? []
@@ -142,6 +143,7 @@ export default class m extends LibComponent<LibInfiniteProps, LibInfiniteState>
142
143
  this.setState((state: LibInfiniteState, props: LibInfiniteProps) => {
143
144
  const latestData = [...state.data, ...mainIndex.list]
144
145
  return {
146
+ isStop: this.isStop,
145
147
  error: '',
146
148
  data: page == 0
147
149
  ? (typeof this.props?.filterData == 'function' ? mainIndex.list.filter(this.props.filterData) : mainIndex.list)
@@ -1,23 +1,17 @@
1
1
  // withHooks
2
2
  // noPage
3
3
 
4
- import NavigationContainerRefContext from '@react-navigation/core/src/NavigationContainerRefContext';
5
- import NavigationContext from '@react-navigation/core/src/NavigationContext';
6
- import type { NavigationProp } from '@react-navigation/core/src/types';
7
- import React, { useRef, useState } from 'react';
8
- import { KeyboardAvoidingView, Platform, ViewStyle } from 'react-native';
9
-
4
+ import React from 'react';
5
+ import { Platform, ViewStyle } from 'react-native';
6
+ import { KeyboardAvoidingView } from 'react-native-keyboard-controller';
10
7
 
11
8
  export interface LibKeyboard_avoidProps {
12
9
  children?: any,
13
10
  style?: ViewStyle
14
11
  }
15
- export default function m(props: LibKeyboard_avoidProps): any {
16
-
17
- // const isFocussed = useIsFocused();
18
12
 
19
- // const Custom = isFocussed ? KeyboardAvoidingView : View
20
13
 
14
+ export default function m(props: LibKeyboard_avoidProps): any {
21
15
  return (
22
16
  <KeyboardAvoidingView behavior={Platform.OS == 'android' ? 'height' : 'padding'} style={[{ flex: 1 }, props.style]} >
23
17
  {props.children}
@@ -25,55 +19,3 @@ export default function m(props: LibKeyboard_avoidProps): any {
25
19
  )
26
20
  }
27
21
 
28
-
29
- /**
30
- * Hook to access the navigation prop of the parent screen anywhere.
31
- *
32
- * @returns Navigation prop of the parent screen.
33
- */
34
- function useNavigation<T = NavigationProp<ReactNavigation.RootParamList>>(): T {
35
- const root = React.useContext(NavigationContainerRefContext);
36
- const navigation = React.useContext(NavigationContext);
37
-
38
- if (navigation === undefined && root === undefined) {
39
-
40
- }
41
- return (navigation ?? root) as unknown as T;
42
- }
43
-
44
- function useIsFocused(): boolean {
45
- const navigation = useNavigation();
46
-
47
- const forceTrue = useRef(false)
48
-
49
- if (navigation == undefined) {
50
- forceTrue.current = true
51
- }
52
-
53
- const [isFocused, setIsFocused] = useState(navigation?.isFocused);
54
-
55
- const valueToReturn = !!navigation?.isFocused?.();
56
-
57
- if (isFocused !== valueToReturn) {
58
- setIsFocused(valueToReturn);
59
- }
60
-
61
- React.useEffect(() => {
62
- const unsubscribeFocus = navigation?.addListener?.('focus', () =>
63
- setIsFocused(true)
64
- );
65
-
66
- const unsubscribeBlur = navigation?.addListener?.('blur', () =>
67
- setIsFocused(false)
68
- );
69
-
70
- return () => {
71
- unsubscribeFocus?.();
72
- unsubscribeBlur?.();
73
- };
74
- }, [navigation]);
75
-
76
- React.useDebugValue(valueToReturn);
77
-
78
- return (forceTrue.current || valueToReturn);
79
- }
@@ -1,8 +1,8 @@
1
1
  // withHooks
2
2
  // noPage
3
+ import { Image } from 'expo-image';
3
4
  import React from 'react';
4
5
  import { ImageStyle } from 'react-native';
5
- import FastImage from 'react-native-fast-image';
6
6
 
7
7
  export interface LibPictureSource {
8
8
  uri: string
@@ -11,7 +11,6 @@ export interface LibPictureProps {
11
11
  source: LibPictureSource | any,
12
12
  style: ImageStyle,
13
13
  resizeMode?: "contain" | "cover",
14
- noCache?: boolean,
15
14
  onError?: () => void,
16
15
  }
17
16
 
@@ -19,15 +18,17 @@ export default function m(props: LibPictureProps): any {
19
18
 
20
19
  let resizeMode
21
20
  if (props?.style?.resizeMode == 'cover')
22
- resizeMode = FastImage.resizeMode.cover
21
+ resizeMode = "cover"
23
22
  else if (props?.style?.resizeMode == 'contain')
24
- resizeMode = FastImage.resizeMode.contain
23
+ resizeMode = "contain"
25
24
  else if (props?.resizeMode == 'cover')
26
- resizeMode = FastImage.resizeMode.cover
25
+ resizeMode = "cover"
27
26
  else if (props?.resizeMode == 'contain')
28
- resizeMode = FastImage.resizeMode.contain
27
+ resizeMode = "contain"
29
28
  else
30
- resizeMode = FastImage.resizeMode.cover
29
+ resizeMode = "cover"
31
30
 
32
- return <FastImage {...props} resizeMode={resizeMode} />
31
+ return (
32
+ <Image {...props} contentFit={resizeMode} allowDownscaling cachePolicy={"memory-disk"} />
33
+ )
33
34
  }
@@ -3,9 +3,9 @@
3
3
 
4
4
  import { LibStyle } from 'esoftplay/cache/lib/style/import';
5
5
  import useGlobalState from 'esoftplay/global';
6
- import React, { useEffect } from 'react';
6
+ import React, { useEffect, useRef } from 'react';
7
7
  import { Text, View } from 'react-native';
8
- import Animated, { interpolate, useAnimatedProps, useSharedValue, withTiming } from 'react-native-reanimated';
8
+ import Animated, { interpolate, ReduceMotion, useAnimatedProps, useSharedValue, withTiming } from 'react-native-reanimated';
9
9
 
10
10
  export interface LibToastProps {
11
11
 
@@ -16,7 +16,7 @@ const initState = {
16
16
  timeout: 3000
17
17
  }
18
18
 
19
- const state = useGlobalState<any>(initState)
19
+ const state = useGlobalState(initState)
20
20
 
21
21
  let _timeout: any = undefined
22
22
 
@@ -34,12 +34,13 @@ export function show(message: string, timeout?: number): void {
34
34
  _timeout = undefined
35
35
  }
36
36
  _timeout = setTimeout(() => {
37
- hide()
38
37
  clearTimeout(_timeout)
38
+ hide()
39
39
  }, timeout || initState.timeout);
40
40
  }
41
41
 
42
42
  export default function m(props: LibToastProps): any {
43
+ const isFirstInit = useRef(true)
43
44
  const [data] = state.useState()
44
45
  const anim = useSharedValue(0)
45
46
 
@@ -51,11 +52,17 @@ export default function m(props: LibToastProps): any {
51
52
  }))
52
53
 
53
54
  useEffect(() => {
54
- anim.value = withTiming(data?.message ? 1 : 0, { duration: 500 })
55
+ if (!isFirstInit.current && data.message == undefined) {
56
+ anim.value = 1
57
+ }
58
+ if (isFirstInit.current) {
59
+ isFirstInit.current = false
60
+ }
61
+ anim.value = withTiming(data.message != undefined ? 1 : 0, { duration: 500, reduceMotion: ReduceMotion.Never })
55
62
  }, [data])
56
63
 
57
64
  return (
58
- <Animated.View pointerEvents={'none'} style={[{ flex: 1, position: 'absolute', justifyContent: 'center', alignContent: 'center', alignItems: 'center', top: LibStyle.STATUSBAR_HEIGHT + 20, left: 0, right: 0, }, style, LibStyle.elevation(2)]} >
65
+ <Animated.View pointerEvents={'none'} style={[{ flex: 1, position: 'absolute', justifyContent: 'center', alignContent: 'center', alignItems: 'center', top: LibStyle.STATUSBAR_HEIGHT + 20, opacity: 0, left: 0, right: 0, }, style, LibStyle.elevation(2)]} >
59
66
  <View style={{ maxWidth: Math.min(500, LibStyle.width - 30), minWidth: Math.min(500, LibStyle.width - 30), marginHorizontal: 15, marginVertical: 4, borderRadius: 4, borderWidth: 1, borderColor: '#505050', backgroundColor: '#323232', paddingVertical: 13, paddingHorizontal: 16, }} >
60
67
  <Text style={{ fontSize: 14, textAlign: "center", color: 'white' }} >{String(data?.message || '')}</Text>
61
68
  </View>
@@ -22,7 +22,7 @@ export interface LibVersionState {
22
22
  export default class m extends LibComponent<LibVersionProps, LibVersionState> {
23
23
 
24
24
  static appVersion(): string {
25
- let version: any = (Platform.OS == 'android' ? Constants?.expoConfig?.android?.versionCode : Constants?.expoConfig?.ios?.buildNumber)
25
+ let version: any = (Platform.OS == 'android' ? Constants?.manifest?.android?.versionCode : Constants?.manifest?.ios?.buildNumber)
26
26
  return version
27
27
  }
28
28
 
@@ -43,7 +43,7 @@ export default class m extends LibComponent<LibVersionProps, LibVersionState> {
43
43
  }
44
44
 
45
45
  static onDone(res: any, msg: string): void {
46
- const { title, version, android, ios, isForceUpdate } = res
46
+ const { title, version, android, ios, version_publish } = res
47
47
 
48
48
  function isAvailableNewVersion(newVersion: string): boolean {
49
49
  let oldVersion = m.appVersion()
@@ -51,10 +51,13 @@ export default class m extends LibComponent<LibVersionProps, LibVersionState> {
51
51
  }
52
52
  if (isAvailableNewVersion(version)) {
53
53
  LibNavigation.backToRoot()
54
- LibNavigation.replace("lib/version", { res, msg: msg == 'success' ? esp.lang("lib/version", "update_now") : msg })
55
- }
56
- if (isForceUpdate == 1) {
57
- LibUpdaterProperty.check((isNew) => { if (isNew) LibUpdaterProperty.install() })
54
+ LibNavigation.replace("lib/version", { res, msg: msg == 'success' ? 'Update to a new version now' : msg })
55
+ } else {
56
+ const currentVersion = esp.config('publish_id')
57
+ if (currentVersion < version_publish && !__DEV__) {
58
+ LibNavigation.reset("lib/version_view")
59
+ LibUpdaterProperty.check((isNew) => { if (isNew) LibUpdaterProperty.install() })
60
+ }
58
61
  }
59
62
  }
60
63
  static check(): void {
@@ -67,7 +70,7 @@ export default class m extends LibComponent<LibVersionProps, LibVersionState> {
67
70
  return (
68
71
  <ImageBackground source={esp.assets("splash.png")} blurRadius={100} style={{ flex: 1, justifyContent: 'center', alignItems: 'center', borderStartColor: 'white', paddingHorizontal: 17 }} >
69
72
  <LibIcon.SimpleLineIcons name="info" size={60} />
70
- <LibTextstyle textStyle="headline" text={title || esp.lang("lib/version", "version_available")} style={{ textAlign: 'center', marginTop: 10 }} />
73
+ <LibTextstyle textStyle="headline" text={title || 'A new version is available'} style={{ textAlign: 'center', marginTop: 10 }} />
71
74
  <LibTextstyle textStyle="callout" text={msg} style={{ textAlign: 'center', marginTop: 10, color: '#333' }} />
72
75
  <TouchableOpacity
73
76
  onPress={() => { Linking.openURL(link) }}
@@ -0,0 +1,34 @@
1
+ // withHooks
2
+
3
+ import { LibTextstyle } from 'esoftplay/cache/lib/textstyle/import';
4
+ import esp from 'esoftplay/esp';
5
+ import { useTimeout } from 'esoftplay/timeout';
6
+ import * as Updates from 'expo-updates';
7
+ import React, { useEffect } from 'react';
8
+ import { ActivityIndicator, ImageBackground, View } from 'react-native';
9
+
10
+ export interface LibVersion_viewArgs {
11
+
12
+ }
13
+ export interface LibVersion_viewProps {
14
+
15
+ }
16
+ export default function m(props: LibVersion_viewProps): any {
17
+ const timeout = useTimeout()
18
+ useEffect(() => {
19
+ timeout(() => {
20
+ Updates.reloadAsync()
21
+ }, 15000);
22
+ }, [])
23
+
24
+ return (
25
+ <ImageBackground source={esp.assets('splash.png')} style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} >
26
+ <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} >
27
+ <LibTextstyle style={{ textAlign: 'center' }} textStyle='headline' text={esp.lang("lib/version_view", "msg")} />
28
+ </View>
29
+ <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} >
30
+ <ActivityIndicator size={'large'} />
31
+ </View>
32
+ </ImageBackground>
33
+ )
34
+ }
@@ -12,7 +12,7 @@ export default function m(props: MainIndexProps): any {
12
12
 
13
13
  return (
14
14
  <View style={{ flex: 1, backgroundColor: "white", justifyContent: 'center', alignItems: 'center' }} >
15
- <Text>{`Hellow Esoftplay Developer, jangan lupa bismillah dulu ଘ(੭ˊᵕˋ)੭*`}</Text>
15
+ <Text style={{ textAlign: 'center' }} >{`Hellow Esoftplay Developer, jangan lupa bismillah dulu ଘ(੭ˊᵕˋ)੭*`}</Text>
16
16
  </View>
17
17
  )
18
18
  }
@@ -47,10 +47,12 @@ export default function m(defaultUrl?: string): void {
47
47
  useEffect(() => {
48
48
  (async () => {
49
49
  const url = await Linking.getInitialURL();
50
- doLink({ url: url })
50
+ if (url) {
51
+ doLink({ url: url })
52
+ }
51
53
  })()
52
54
 
53
55
  Linking.addEventListener('url', doLink);
54
- return () => Linking.removeEventListener('url', doLink)
56
+ return () => Linking.removeAllListeners('url')
55
57
  }, [])
56
58
  }
@@ -5,7 +5,9 @@ import { userDataReset } from 'esoftplay/global';
5
5
  import FastStorage from 'esoftplay/mmkv';
6
6
  import Storage from 'esoftplay/storage';
7
7
 
8
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/data.md) untuk melihat dokumentasi*/
8
9
  export default {
10
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/data.md#register) untuk melihat dokumentasi*/
9
11
  register(name: string): void {
10
12
  AsyncStorage.getItem("user_data_dependent").then((x) => {
11
13
  let all: string[] = []
@@ -7,6 +7,7 @@ export interface UserHookArgs {
7
7
  export interface UserHookProps {
8
8
 
9
9
  }
10
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/hook.md) untuk melihat dokumentasi*/
10
11
  export default function m(props: UserHookProps): any {
11
12
  return null
12
13
  }
@@ -24,6 +24,8 @@ import { useFonts } from 'expo-font';
24
24
  import React, { useLayoutEffect } from 'react';
25
25
  import { View } from 'react-native';
26
26
  import { GestureHandlerRootView } from 'react-native-gesture-handler';
27
+ import { KeyboardProvider } from "react-native-keyboard-controller";
28
+
27
29
 
28
30
  export interface UserIndexProps {
29
31
 
@@ -44,6 +46,8 @@ function getFontConfig() {
44
46
  }
45
47
 
46
48
 
49
+
50
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/index.md) untuk melihat dokumentasi*/
47
51
  export default function m(props: UserIndexProps): any {
48
52
  moment().locale(LibLocale.state().get())
49
53
  const [loading, setLoading] = useSafeState(true)
@@ -69,26 +73,28 @@ export default function m(props: UserIndexProps): any {
69
73
  //esoftplay-chatting
70
74
 
71
75
  return (
72
- <GestureHandlerRootView style={{ flex: 1 }}>
73
- <View style={{ flex: 1 }}>
74
- <LibWorker />
75
- {
76
- loading ?
77
- <UserLoading />
78
- :
79
- <>
80
- <LibWorkloop />
81
- <Navs />
82
- <LibNet_status />
83
- <LibDialog style={'default'} />
84
- <LibImage />
85
- <LibProgress />
86
- <LibToast />
87
- <UserHook />
88
- </>
89
- }
90
- </View>
91
- <View style={{ backgroundColor: LibStyle?.colorNavigationBar || 'white', height: LibStyle.isIphoneX ? 35 : 0 }} />
92
- </GestureHandlerRootView>
76
+ <KeyboardProvider>
77
+ <GestureHandlerRootView style={{ flex: 1 }}>
78
+ <View style={{ flex: 1 }}>
79
+ <LibWorker />
80
+ {
81
+ loading ?
82
+ <UserLoading />
83
+ :
84
+ <>
85
+ <LibWorkloop />
86
+ <Navs />
87
+ <LibNet_status />
88
+ <LibDialog style={'default'} />
89
+ <LibImage />
90
+ <LibProgress />
91
+ <LibToast />
92
+ <UserHook />
93
+ </>
94
+ }
95
+ </View>
96
+ <View style={{ backgroundColor: LibStyle?.colorNavigationBar || 'white', height: LibStyle.isIphoneX ? 35 : 0 }} />
97
+ </GestureHandlerRootView>
98
+ </KeyboardProvider>
93
99
  )
94
100
  }
@@ -11,6 +11,7 @@ export interface UserLoadingArgs {
11
11
  export interface UserLoadingProps {
12
12
 
13
13
  }
14
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/loading.md) untuk melihat dokumentasi*/
14
15
  export default function m(props: UserLoadingProps): any {
15
16
  return <ImageBackground source={esp.assets('splash.gif') || esp.assets('splash.png')} style={{ flex: 1 }} />
16
17
  }
@@ -28,6 +28,7 @@ const initState = {
28
28
  };
29
29
 
30
30
  const state = useGlobalState<any>(initState, { persistKey: "user_notification_data", isUserData: true, loadOnInit: true })
31
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/notification.md) untuk melihat dokumentasi*/
31
32
  export default class m extends LibComponent<UserNotificationProps, UserNotificationState> {
32
33
 
33
34
  static state(): useGlobalReturn<any> {
@@ -18,6 +18,7 @@ export interface UserNotification_itemProps {
18
18
  updated: string,
19
19
  user_id: number,
20
20
  }
21
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/notification_item.md) untuk melihat dokumentasi*/
21
22
  export default function m(props: UserNotification_itemProps): any {
22
23
  const LibStyle = useRef(esp.mod("lib/style")).current
23
24
  const LibUtils = useRef(esp.mod("lib/utils")).current
@@ -4,13 +4,17 @@ import useGlobalState, { useGlobalReturn } from 'esoftplay/global';
4
4
 
5
5
  const state = useGlobalState(undefined)
6
6
 
7
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/routes.md) untuk melihat dokumentasi*/
7
8
  export default {
9
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/routes.md#state) untuk melihat dokumentasi*/
8
10
  state(): useGlobalReturn<any> {
9
11
  return state
10
12
  },
13
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/routes.md#set) untuk melihat dokumentasi*/
11
14
  set(routes: any): void {
12
15
  state.set(routes)
13
16
  },
17
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/modules/user/routes.md#getCurrentRouteName) untuk melihat dokumentasi*/
14
18
  getCurrentRouteName(): string {
15
19
  let lastIdx = state.get()?.routes?.length - 1
16
20
  let currentName = state.get()?.routes?.[lastIdx]?.name
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esoftplay",
3
- "version": "0.0.141",
3
+ "version": "0.0.142-b",
4
4
  "description": "embedding data from esoftplay framework (web based) into mobile app",
5
5
  "main": "cache/index.js",
6
6
  "types": "../../index.d.ts",
package/render.tsx CHANGED
@@ -3,15 +3,25 @@
3
3
 
4
4
  import { useEffect, useRef } from 'react';
5
5
  import { Text } from 'react-native';
6
+ import Animated, { useAnimatedStyle, useSharedValue, withDelay, withTiming } from 'react-native-reanimated';
6
7
 
8
+
9
+ const AnimatedText = Animated.createAnimatedComponent(Text)
7
10
  export default function useRenderCounter(module: string): any {
8
11
  const counter = useRef(1)
12
+ const value = useSharedValue(0)
9
13
 
10
14
  useEffect(() => {
11
15
  counter.current += 1
16
+ value.value = 1
17
+ value.value = withDelay(1000, withTiming(0, { duration: 500 }))
12
18
  })
13
19
 
20
+ const style = useAnimatedStyle(() => ({
21
+ opacity: value.value
22
+ }))
23
+
14
24
  return () => (
15
- <Text style={{ position: 'absolute', fontSize: 7, zIndex: 999, color: 'white', backgroundColor: 'black', bottom: 0, left: 0 }} >{module}: {counter.current}</Text>
25
+ <AnimatedText pointerEvent={'none'} style={[{ position: 'absolute', fontSize: 10, zIndex: 999, color: 'white', backgroundColor: 'black', bottom: 0, left: 0 }, style]} >{module}: {counter.current}</AnimatedText>
16
26
  )
17
27
  }
package/timeout.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useRef } from "react";
2
2
 
3
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/timeout.md#createTimeout) untuk melihat dokumentasi*/
3
4
  export function createTimeout() {
4
5
  let timeoutId: any = undefined;
5
6
  function set(callback: Function, delay: number) {
@@ -20,6 +21,7 @@ export function createTimeout() {
20
21
  return { set, clear };
21
22
  }
22
23
 
24
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/timeout.md#useTimeout) untuk melihat dokumentasi*/
23
25
  export function useTimeout() {
24
26
  const smartTimeout = useRef(createTimeout());
25
27
 
@@ -31,6 +33,7 @@ export function useTimeout() {
31
33
  }
32
34
 
33
35
 
36
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/timeout.md#createInterval) untuk melihat dokumentasi*/
34
37
  export function createInterval() {
35
38
  let timeoutId: any = undefined;
36
39
  function set(callback: Function, delay: number) {
@@ -50,6 +53,7 @@ export function createInterval() {
50
53
  return { set, clear };
51
54
  }
52
55
 
56
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/timeout.md#useInterval) untuk melihat dokumentasi*/
53
57
  export function useInterval() {
54
58
  const smartInterval = useRef(createInterval());
55
59
 
@@ -60,6 +64,7 @@ export function useInterval() {
60
64
  return smartInterval.current?.set;
61
65
  }
62
66
 
67
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/timeout.md#createDebounce) untuk melihat dokumentasi*/
63
68
  export function createDebounce() {
64
69
  let timeoutId: any = undefined;
65
70
  function set(callback: Function, delay: number) {
@@ -80,6 +85,7 @@ export function createDebounce() {
80
85
  return { set, clear };
81
86
  }
82
87
 
88
+ /** Klik [disini](https://github.com/dev-esoftplay/mobile-docs/blob/main/timeout.md#useDebounce) untuk melihat dokumentasi*/
83
89
  export function useDebounce() {
84
90
  const smartDebounce = useRef(createDebounce());
85
91