react-native-my-uploader-android 1.0.28 → 1.0.30

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 (32) hide show
  1. package/android/src/main/java/com/myuploaderandroid/DownloadFileModule.kt +91 -58
  2. package/android/src/main/java/com/myuploaderandroid/MyUploaderModule.kt +93 -42
  3. package/lib/commonjs/components/DownloadFile.js +37 -47
  4. package/lib/commonjs/components/DownloadFile.js.map +1 -1
  5. package/lib/commonjs/components/MyUploader.js +57 -80
  6. package/lib/commonjs/components/MyUploader.js.map +1 -1
  7. package/lib/commonjs/index.d.js.map +1 -1
  8. package/lib/commonjs/index.js +9 -7
  9. package/lib/commonjs/index.js.map +1 -1
  10. package/lib/commonjs/types.js.map +1 -1
  11. package/lib/module/components/DownloadFile.js +38 -48
  12. package/lib/module/components/DownloadFile.js.map +1 -1
  13. package/lib/module/components/MyUploader.js +55 -79
  14. package/lib/module/components/MyUploader.js.map +1 -1
  15. package/lib/module/index.d.js +10 -0
  16. package/lib/module/index.d.js.map +1 -1
  17. package/lib/module/index.js +10 -6
  18. package/lib/module/index.js.map +1 -1
  19. package/lib/module/types.js.map +1 -1
  20. package/package.json +1 -1
  21. package/src/components/DownloadFile.tsx +40 -61
  22. package/src/components/MyUploader.tsx +59 -89
  23. package/src/index.d.ts +12 -5
  24. package/src/index.ts +12 -6
  25. package/src/types.ts +98 -41
  26. package/android/src/main/java/com/myuploader/MyUploaderModule.kt +0 -173
  27. package/android/src/main/java/com/myuploader/MyUploaderPackage.kt +0 -16
  28. package/lib/commonjs/NativeMyUploader.js +0 -15
  29. package/lib/commonjs/NativeMyUploader.js.map +0 -1
  30. package/lib/module/NativeMyUploader.js +0 -9
  31. package/lib/module/NativeMyUploader.js.map +0 -1
  32. package/src/NativeMyUploader.ts +0 -25
@@ -1,112 +1,88 @@
1
- import React from 'react';
2
- import { NativeModules, TouchableOpacity, Text, StyleSheet } from 'react-native';
3
- const LINKING_ERROR = `The package 'react-native-my-uploader' doesn't seem to be linked.`;
4
- const DocumentPicker = NativeModules.DocumentPicker ? NativeModules.DocumentPicker : new Proxy({}, {
5
- get() {
6
- throw new Error(LINKING_ERROR);
7
- }
8
- });
1
+ import React, { useState } from 'react';
2
+ import { TouchableOpacity, Text, StyleSheet, ActivityIndicator, NativeModules } from 'react-native';
3
+ const {
4
+ UploadDocumentPicker: NativeUploadPicker
5
+ } = NativeModules;
9
6
 
10
- // Mevcut pickFile fonksiyonunu dahili (internal) olarak kullanmak üzere saklayalım.
11
- // İsterseniz bunu dışa aktarmaya devam edebilirsiniz.
12
- async function pickFile(options = {}) {
13
- var _options$excludedUris, _options$fileTypes, _options$maxSize;
14
- const {
15
- multipleFiles = false,
16
- maxFiles = 0,
17
- ...rest
18
- } = options;
19
- if (!multipleFiles && maxFiles > 1) {
20
- throw new Error('`maxFiles` cannot be greater than 1 when `multipleFiles` is false.');
21
- }
22
- let effectiveMaxFiles = maxFiles;
23
- if (multipleFiles && maxFiles === 0) {
24
- effectiveMaxFiles = 3;
25
- }
26
- const finalOptions = {
27
- ...rest,
28
- multipleFiles,
29
- maxFiles: effectiveMaxFiles,
30
- excludedUris: (_options$excludedUris = options.excludedUris) !== null && _options$excludedUris !== void 0 ? _options$excludedUris : [],
7
+ // 1. Standalone pickFile Fonksiyonu
8
+ export const pickFile = async (options = {}) => {
9
+ var _options$multipleFile, _options$maxFiles, _options$maxSize, _options$fileTypes, _options$excludedUris;
10
+ if (!NativeUploadPicker) throw new Error("DocumentPicker module is not linked.");
11
+
12
+ // Native tarafa gönderilecek options
13
+ const nativeOptions = {
14
+ multipleFiles: (_options$multipleFile = options.multipleFiles) !== null && _options$multipleFile !== void 0 ? _options$multipleFile : false,
15
+ maxFiles: (_options$maxFiles = options.maxFiles) !== null && _options$maxFiles !== void 0 ? _options$maxFiles : 0,
16
+ maxSize: (_options$maxSize = options.maxSize) !== null && _options$maxSize !== void 0 ? _options$maxSize : 0,
31
17
  fileTypes: (_options$fileTypes = options.fileTypes) !== null && _options$fileTypes !== void 0 ? _options$fileTypes : ['*/*'],
32
- maxSize: (_options$maxSize = options.maxSize) !== null && _options$maxSize !== void 0 ? _options$maxSize : 0
18
+ excludedUris: (_options$excludedUris = options.excludedUris) !== null && _options$excludedUris !== void 0 ? _options$excludedUris : []
33
19
  };
34
- return DocumentPicker.openDocument(finalOptions);
35
- }
20
+ return await NativeUploadPicker.openDocument(nativeOptions);
21
+ };
36
22
 
37
- // YENİ: MyUploader Component'i
38
- const MyUploaderAndroid = ({
39
- // DocumentPickerOptions
40
- multipleFiles = false,
41
- maxFiles = 0,
42
- fileTypes = ['*/*'],
43
- maxSize = 0,
44
- excludedUris = [],
45
- // UI Props with defaults
46
- buttonPlaceHolder = 'Dosya Seçin...',
23
+ // 2. MyUploader Bileşeni
24
+ const MyUploader = ({
25
+ onSelect,
26
+ onError,
27
+ buttonPlaceHolder = "Dosya Seç",
47
28
  ButtonStyle,
48
29
  ButtonTextStyle,
49
30
  disabled = false,
50
- // Callbacks
51
- onSelect,
52
- onError = error => console.error('MyUploader Error:', error)
31
+ multipleFiles = false,
32
+ fileTypes = ['*/*'],
33
+ maxSize = 0,
34
+ maxFiles = 0,
35
+ excludedUris = []
53
36
  }) => {
37
+ const [isLoading, setIsLoading] = useState(false);
54
38
  const handlePress = async () => {
39
+ if (disabled || isLoading) return;
40
+ setIsLoading(true);
55
41
  try {
56
- const options = {
42
+ const files = await pickFile({
57
43
  multipleFiles,
58
- maxFiles,
59
44
  fileTypes,
60
45
  maxSize,
46
+ maxFiles,
61
47
  excludedUris
62
- };
63
- const selectedFiles = await pickFile(options);
64
-
65
- // Eğer kullanıcı seçim yapmadan kapatırsa bazı sistemler boş array dönebilir.
66
- // Sadece doluysa callback'i tetikleyelim.
67
- if (selectedFiles && selectedFiles.length > 0) {
68
- onSelect(selectedFiles);
69
- }
48
+ });
49
+ onSelect(files);
70
50
  } catch (error) {
71
- // Kullanıcının seçimi iptal etmesi bir "hata" sayılmamalı,
72
- // bu yüzden sadece konsola yazdırıp onError'ı tetiklemeyebiliriz.
73
- // Native kodunuz "E_PICKER_CANCELLED" koduyla reject ediyor.
74
- if (error.code !== 'E_PICKER_CANCELLED') {
51
+ if (onError) {
75
52
  onError(error);
53
+ } else {
54
+ console.error("MyUploader Error:", error);
76
55
  }
56
+ } finally {
57
+ setIsLoading(false);
77
58
  }
78
59
  };
79
60
  return /*#__PURE__*/React.createElement(TouchableOpacity, {
80
- style: [styles.button, ButtonStyle, disabled && styles.disabledButton],
61
+ style: [styles.button, ButtonStyle, (disabled || isLoading) && styles.disabled],
81
62
  onPress: handlePress,
82
- disabled: disabled
83
- }, /*#__PURE__*/React.createElement(Text, {
84
- style: [styles.buttonText, ButtonTextStyle]
63
+ disabled: disabled || isLoading
64
+ }, isLoading ? /*#__PURE__*/React.createElement(ActivityIndicator, {
65
+ color: "#FFF"
66
+ }) : /*#__PURE__*/React.createElement(Text, {
67
+ style: [styles.text, ButtonTextStyle]
85
68
  }, buttonPlaceHolder));
86
69
  };
87
-
88
- // Varsayılan stiller
89
70
  const styles = StyleSheet.create({
90
71
  button: {
91
- backgroundColor: '#007AFF',
92
- paddingHorizontal: 20,
93
- paddingVertical: 10,
72
+ backgroundColor: '#6200EE',
73
+ padding: 12,
94
74
  borderRadius: 8,
95
75
  alignItems: 'center',
96
76
  justifyContent: 'center'
97
77
  },
98
- buttonText: {
99
- color: '#FFFFFF',
100
- fontSize: 16,
101
- fontWeight: 'bold'
78
+ text: {
79
+ color: '#FFF',
80
+ fontWeight: '600',
81
+ fontSize: 16
102
82
  },
103
- disabledButton: {
104
- backgroundColor: '#A9A9A9'
83
+ disabled: {
84
+ backgroundColor: '#B0B0B0'
105
85
  }
106
86
  });
107
-
108
- // İhtiyaca göre pickFile'ı da export edebilirsiniz.
109
- export { pickFile };
110
- // Component'i varsayılan olarak export ediyoruz.
111
- export default MyUploaderAndroid;
87
+ export default MyUploader;
112
88
  //# sourceMappingURL=MyUploader.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["React","NativeModules","TouchableOpacity","Text","StyleSheet","LINKING_ERROR","DocumentPicker","Proxy","get","Error","pickFile","options","_options$excludedUris","_options$fileTypes","_options$maxSize","multipleFiles","maxFiles","rest","effectiveMaxFiles","finalOptions","excludedUris","fileTypes","maxSize","openDocument","MyUploaderAndroid","buttonPlaceHolder","ButtonStyle","ButtonTextStyle","disabled","onSelect","onError","error","console","handlePress","selectedFiles","length","code","createElement","style","styles","button","disabledButton","onPress","buttonText","create","backgroundColor","paddingHorizontal","paddingVertical","borderRadius","alignItems","justifyContent","color","fontSize","fontWeight"],"sources":["MyUploader.tsx"],"sourcesContent":["import React from 'react';\r\nimport {NativeModules,TouchableOpacity,Text,StyleSheet} from 'react-native';\r\nimport type {FileInfo,DocumentPickerOptions, MyUploaderProps} from '../types';\r\n\r\nconst LINKING_ERROR = `The package 'react-native-my-uploader' doesn't seem to be linked.`;\r\n\r\nconst DocumentPicker = NativeModules.DocumentPicker\r\n ? NativeModules.DocumentPicker\r\n : new Proxy(\r\n {},\r\n {\r\n get() {\r\n throw new Error(LINKING_ERROR);\r\n },\r\n }\r\n );\r\n\r\n// Mevcut pickFile fonksiyonunu dahili (internal) olarak kullanmak üzere saklayalım.\r\n// İsterseniz bunu dışa aktarmaya devam edebilirsiniz.\r\nasync function pickFile(\r\n options: DocumentPickerOptions = {}\r\n): Promise<FileInfo[]> {\r\n const { multipleFiles = false, maxFiles = 0, ...rest } = options;\r\n\r\n if (!multipleFiles && maxFiles > 1) {\r\n throw new Error(\r\n '`maxFiles` cannot be greater than 1 when `multipleFiles` is false.'\r\n );\r\n }\r\n let effectiveMaxFiles = maxFiles;\r\n if (multipleFiles && maxFiles === 0) {\r\n effectiveMaxFiles = 3;\r\n }\r\n const finalOptions: DocumentPickerOptions = {\r\n ...rest,\r\n multipleFiles,\r\n maxFiles: effectiveMaxFiles,\r\n excludedUris: options.excludedUris ?? [],\r\n fileTypes: options.fileTypes ?? ['*/*'],\r\n maxSize: options.maxSize ?? 0,\r\n };\r\n return DocumentPicker.openDocument(finalOptions);\r\n}\r\n\r\n// YENİ: MyUploader Component'i\r\nconst MyUploaderAndroid: React.FC<MyUploaderProps> = ({\r\n // DocumentPickerOptions\r\n multipleFiles = false,\r\n maxFiles = 0,\r\n fileTypes = ['*/*'],\r\n maxSize = 0,\r\n excludedUris = [],\r\n // UI Props with defaults\r\n buttonPlaceHolder = 'Dosya Seçin...',\r\n ButtonStyle,\r\n ButtonTextStyle,\r\n disabled = false,\r\n // Callbacks\r\n onSelect,\r\n onError = (error) => console.error('MyUploader Error:', error),\r\n}) => {\r\n const handlePress = async () => {\r\n try {\r\n const options: DocumentPickerOptions = {\r\n multipleFiles,\r\n maxFiles,\r\n fileTypes,\r\n maxSize,\r\n excludedUris,\r\n };\r\n const selectedFiles = await pickFile(options);\r\n \r\n // Eğer kullanıcı seçim yapmadan kapatırsa bazı sistemler boş array dönebilir.\r\n // Sadece doluysa callback'i tetikleyelim.\r\n if (selectedFiles && selectedFiles.length > 0) {\r\n onSelect(selectedFiles);\r\n }\r\n\r\n } catch (error: any) {\r\n // Kullanıcının seçimi iptal etmesi bir \"hata\" sayılmamalı,\r\n // bu yüzden sadece konsola yazdırıp onError'ı tetiklemeyebiliriz.\r\n // Native kodunuz \"E_PICKER_CANCELLED\" koduyla reject ediyor.\r\n if (error.code !== 'E_PICKER_CANCELLED') {\r\n onError(error);\r\n }\r\n }\r\n };\r\n\r\n return (\r\n <TouchableOpacity\r\n style={[styles.button, ButtonStyle, disabled && styles.disabledButton]}\r\n onPress={handlePress}\r\n disabled={disabled}\r\n >\r\n <Text style={[styles.buttonText, ButtonTextStyle]}>\r\n {buttonPlaceHolder}\r\n </Text>\r\n </TouchableOpacity>\r\n );\r\n};\r\n\r\n// Varsayılan stiller\r\nconst styles = StyleSheet.create({\r\n button: {\r\n backgroundColor: '#007AFF',\r\n paddingHorizontal: 20,\r\n paddingVertical: 10,\r\n borderRadius: 8,\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n },\r\n buttonText: {\r\n color: '#FFFFFF',\r\n fontSize: 16,\r\n fontWeight: 'bold',\r\n },\r\n disabledButton: {\r\n backgroundColor: '#A9A9A9',\r\n },\r\n});\r\n\r\n// İhtiyaca göre pickFile'ı da export edebilirsiniz.\r\nexport { pickFile };\r\nexport type { FileInfo, DocumentPickerOptions, MyUploaderProps } from \"../types\";\r\n\r\n// Component'i varsayılan olarak export ediyoruz.\r\nexport default MyUploaderAndroid;"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","useState","TouchableOpacity","Text","StyleSheet","ActivityIndicator","NativeModules","UploadDocumentPicker","NativeUploadPicker","pickFile","options","_options$multipleFile","_options$maxFiles","_options$maxSize","_options$fileTypes","_options$excludedUris","Error","nativeOptions","multipleFiles","maxFiles","maxSize","fileTypes","excludedUris","openDocument","MyUploader","onSelect","onError","buttonPlaceHolder","ButtonStyle","ButtonTextStyle","disabled","isLoading","setIsLoading","handlePress","files","error","console","createElement","style","styles","button","onPress","color","text","create","backgroundColor","padding","borderRadius","alignItems","justifyContent","fontWeight","fontSize"],"sources":["MyUploader.tsx"],"sourcesContent":["import React, { useState } from 'react';\r\nimport { TouchableOpacity, Text, StyleSheet, ActivityIndicator,NativeModules } from 'react-native';\r\nimport type { MyUploaderProps, DocumentPickerOptions, FileInfo } from '../types';\r\n\r\nconst { UploadDocumentPicker: NativeUploadPicker } = NativeModules;\r\n\r\n// 1. Standalone pickFile Fonksiyonu\r\nexport const pickFile = async (options: DocumentPickerOptions = {}): Promise<FileInfo[]> => {\r\n if (!NativeUploadPicker) throw new Error(\"DocumentPicker module is not linked.\");\r\n \r\n // Native tarafa gönderilecek options\r\n const nativeOptions = {\r\n multipleFiles: options.multipleFiles ?? false,\r\n maxFiles: options.maxFiles ?? 0,\r\n maxSize: options.maxSize ?? 0,\r\n fileTypes: options.fileTypes ?? ['*/*'],\r\n excludedUris: options.excludedUris ?? [],\r\n };\r\n\r\n return await NativeUploadPicker.openDocument(nativeOptions);\r\n};\r\n\r\n// 2. MyUploader Bileşeni\r\nconst MyUploader: React.FC<MyUploaderProps> = ({\r\n onSelect,\r\n onError,\r\n buttonPlaceHolder = \"Dosya Seç\",\r\n ButtonStyle,\r\n ButtonTextStyle,\r\n disabled = false,\r\n multipleFiles = false,\r\n fileTypes = ['*/*'],\r\n maxSize = 0,\r\n maxFiles = 0,\r\n excludedUris = [],\r\n}) => {\r\n const [isLoading, setIsLoading] = useState(false);\r\n\r\n const handlePress = async () => {\r\n if (disabled || isLoading) return;\r\n setIsLoading(true);\r\n\r\n try {\r\n const files = await pickFile({\r\n multipleFiles,\r\n fileTypes,\r\n maxSize,\r\n maxFiles,\r\n excludedUris\r\n });\r\n \r\n onSelect(files);\r\n } catch (error: any) {\r\n if (onError) {\r\n onError(error);\r\n } else {\r\n console.error(\"MyUploader Error:\", error);\r\n }\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n <TouchableOpacity\r\n style={[styles.button, ButtonStyle, (disabled || isLoading) && styles.disabled]}\r\n onPress={handlePress}\r\n disabled={disabled || isLoading}\r\n >\r\n {isLoading ? (\r\n <ActivityIndicator color=\"#FFF\" />\r\n ) : (\r\n <Text style={[styles.text, ButtonTextStyle]}>{buttonPlaceHolder}</Text>\r\n )}\r\n </TouchableOpacity>\r\n );\r\n};\r\n\r\nconst styles = StyleSheet.create({\r\n button: {\r\n backgroundColor: '#6200EE',\r\n padding: 12,\r\n borderRadius: 8,\r\n alignItems: 'center',\r\n justifyContent: 'center'\r\n },\r\n text: {\r\n color: '#FFF',\r\n fontWeight: '600',\r\n fontSize: 16\r\n },\r\n disabled: {\r\n backgroundColor: '#B0B0B0'\r\n }\r\n});\r\n\r\nexport default MyUploader;"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,QAAQ,QAAQ,OAAO;AACvC,SAASC,gBAAgB,EAAEC,IAAI,EAAEC,UAAU,EAAEC,iBAAiB,EAACC,aAAa,QAAQ,cAAc;AAGlG,MAAM;EAAEC,oBAAoB,EAAEC;AAAmB,CAAC,GAAGF,aAAa;;AAElE;AACA,OAAO,MAAMG,QAAQ,GAAG,MAAAA,CAAOC,OAA8B,GAAG,CAAC,CAAC,KAA0B;EAAA,IAAAC,qBAAA,EAAAC,iBAAA,EAAAC,gBAAA,EAAAC,kBAAA,EAAAC,qBAAA;EAC1F,IAAI,CAACP,kBAAkB,EAAE,MAAM,IAAIQ,KAAK,CAAC,sCAAsC,CAAC;;EAEhF;EACA,MAAMC,aAAa,GAAG;IACpBC,aAAa,GAAAP,qBAAA,GAAED,OAAO,CAACQ,aAAa,cAAAP,qBAAA,cAAAA,qBAAA,GAAI,KAAK;IAC7CQ,QAAQ,GAAAP,iBAAA,GAAEF,OAAO,CAACS,QAAQ,cAAAP,iBAAA,cAAAA,iBAAA,GAAI,CAAC;IAC/BQ,OAAO,GAAAP,gBAAA,GAAEH,OAAO,CAACU,OAAO,cAAAP,gBAAA,cAAAA,gBAAA,GAAI,CAAC;IAC7BQ,SAAS,GAAAP,kBAAA,GAAEJ,OAAO,CAACW,SAAS,cAAAP,kBAAA,cAAAA,kBAAA,GAAI,CAAC,KAAK,CAAC;IACvCQ,YAAY,GAAAP,qBAAA,GAAEL,OAAO,CAACY,YAAY,cAAAP,qBAAA,cAAAA,qBAAA,GAAI;EACxC,CAAC;EAED,OAAO,MAAMP,kBAAkB,CAACe,YAAY,CAACN,aAAa,CAAC;AAC7D,CAAC;;AAED;AACA,MAAMO,UAAqC,GAAGA,CAAC;EAC7CC,QAAQ;EACRC,OAAO;EACPC,iBAAiB,GAAG,WAAW;EAC/BC,WAAW;EACXC,eAAe;EACfC,QAAQ,GAAG,KAAK;EAChBZ,aAAa,GAAG,KAAK;EACrBG,SAAS,GAAG,CAAC,KAAK,CAAC;EACnBD,OAAO,GAAG,CAAC;EACXD,QAAQ,GAAG,CAAC;EACZG,YAAY,GAAG;AACjB,CAAC,KAAK;EACJ,MAAM,CAACS,SAAS,EAAEC,YAAY,CAAC,GAAG/B,QAAQ,CAAC,KAAK,CAAC;EAEjD,MAAMgC,WAAW,GAAG,MAAAA,CAAA,KAAY;IAC9B,IAAIH,QAAQ,IAAIC,SAAS,EAAE;IAC3BC,YAAY,CAAC,IAAI,CAAC;IAElB,IAAI;MACF,MAAME,KAAK,GAAG,MAAMzB,QAAQ,CAAC;QAC3BS,aAAa;QACbG,SAAS;QACTD,OAAO;QACPD,QAAQ;QACRG;MACF,CAAC,CAAC;MAEFG,QAAQ,CAACS,KAAK,CAAC;IACjB,CAAC,CAAC,OAAOC,KAAU,EAAE;MACnB,IAAIT,OAAO,EAAE;QACXA,OAAO,CAACS,KAAK,CAAC;MAChB,CAAC,MAAM;QACLC,OAAO,CAACD,KAAK,CAAC,mBAAmB,EAAEA,KAAK,CAAC;MAC3C;IACF,CAAC,SAAS;MACRH,YAAY,CAAC,KAAK,CAAC;IACrB;EACF,CAAC;EAED,oBACEhC,KAAA,CAAAqC,aAAA,CAACnC,gBAAgB;IACfoC,KAAK,EAAE,CAACC,MAAM,CAACC,MAAM,EAAEZ,WAAW,EAAE,CAACE,QAAQ,IAAIC,SAAS,KAAKQ,MAAM,CAACT,QAAQ,CAAE;IAChFW,OAAO,EAAER,WAAY;IACrBH,QAAQ,EAAEA,QAAQ,IAAIC;EAAU,GAE/BA,SAAS,gBACR/B,KAAA,CAAAqC,aAAA,CAAChC,iBAAiB;IAACqC,KAAK,EAAC;EAAM,CAAE,CAAC,gBAElC1C,KAAA,CAAAqC,aAAA,CAAClC,IAAI;IAACmC,KAAK,EAAE,CAACC,MAAM,CAACI,IAAI,EAAEd,eAAe;EAAE,GAAEF,iBAAwB,CAExD,CAAC;AAEvB,CAAC;AAED,MAAMY,MAAM,GAAGnC,UAAU,CAACwC,MAAM,CAAC;EAC/BJ,MAAM,EAAE;IACNK,eAAe,EAAE,SAAS;IAC1BC,OAAO,EAAE,EAAE;IACXC,YAAY,EAAE,CAAC;IACfC,UAAU,EAAE,QAAQ;IACpBC,cAAc,EAAE;EAClB,CAAC;EACDN,IAAI,EAAE;IACJD,KAAK,EAAE,MAAM;IACbQ,UAAU,EAAE,KAAK;IACjBC,QAAQ,EAAE;EACZ,CAAC;EACDrB,QAAQ,EAAE;IACRe,eAAe,EAAE;EACnB;AACF,CAAC,CAAC;AAEF,eAAerB,UAAU","ignoreList":[]}
@@ -1,2 +1,12 @@
1
+ // import type { DownloadFileProps } from './types';
2
+
1
3
  export * from './types';
4
+
5
+ // DownloadFile Component Tanımı (3. Bunu ekledik)
6
+ // export declare const DownloadFile: React.FC<DownloadFileProps>;
7
+
8
+ // pickFile Fonksiyon Tanımı
9
+
10
+ // Varsayılan dışa aktarım (İsteğe bağlı, genellikle ana bileşen verilir)
11
+ export {};
2
12
  //# sourceMappingURL=index.d.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["index.d.ts"],"sourcesContent":["import * as React from 'react';\r\nimport type { DocumentPickerOptions, MyUploaderProps,FileInfo,DownloadFileProps } from './types';\r\n\r\nexport * from './types';\r\n\r\ndeclare const MyUploader: React.FC<MyUploaderProps>;\r\nexport default MyUploader;\r\n\r\nexport declare const DownloadFile: React.FC<DownloadFileProps>;\r\nexport function pickFile(options?: DocumentPickerOptions): Promise<FileInfo[]>;"],"mappings":"AAGA,cAAc,SAAS","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["index.d.ts"],"sourcesContent":["import * as React from 'react';\r\nimport type { DocumentPickerOptions, MyUploaderProps, FileInfo } from './types';\r\n// import type { DownloadFileProps } from './types';\r\n\r\nexport * from './types';\r\n\r\n// DownloadFile Component Tanımı (3. Bunu ekledik)\r\n// export declare const DownloadFile: React.FC<DownloadFileProps>;\r\n\r\n// pickFile Fonksiyon Tanımı\r\nexport declare function pickFile(options?: DocumentPickerOptions): Promise<FileInfo[]>;\r\n\r\nexport declare const MyUploader: React.FC<MyUploaderProps>;\r\n\r\n// Varsayılan dışa aktarım (İsteğe bağlı, genellikle ana bileşen verilir)\r\ndeclare const _default: React.FC<MyUploaderProps>;\r\nexport default _default;"],"mappings":"AAEA;;AAEA,cAAc,SAAS;;AAEvB;AACA;;AAEA;;AAKA;AAAA","ignoreList":[]}
@@ -1,9 +1,13 @@
1
- import MyUploaderAndroid from "./components/MyUploader";
2
- import DownloadFileAndroid from "./components/DownloadFile";
3
- import { pickFile } from './components/MyUploader';
1
+ import MyUploader, { pickFile } from "./components/MyUploader";
2
+ // import DownloadFile from "./components/DownloadFile";
4
3
 
5
- // Component'leri ve fonksiyonları dışa aktar
6
- export { DownloadFileAndroid, pickFile };
4
+ // 2. Diğerlerini NAMED olarak dışa aktar (import { DownloadFile, pickFile } ... için)
5
+ // export { DownloadFile, pickFile };
6
+
7
+ // Sadece bu paketle ilgili olanları dışa aktar
8
+ export { MyUploader, pickFile };
7
9
  export * from './types';
8
- export default MyUploaderAndroid;
10
+
11
+ // Varsayılan dışa aktarım olarak da ana bileşeni verelim
12
+ export default MyUploader;
9
13
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["MyUploaderAndroid","DownloadFileAndroid","pickFile"],"sources":["index.ts"],"sourcesContent":["import MyUploaderAndroid from \"./components/MyUploader\";\r\nimport DownloadFileAndroid from \"./components/DownloadFile\";\r\nimport { pickFile } from './components/MyUploader';\r\n\r\n// Component'leri ve fonksiyonları dışa aktar\r\nexport { DownloadFileAndroid, pickFile };\r\nexport * from './types';\r\nexport default MyUploaderAndroid;\r\n\r\n\r\n"],"mappings":"AAAA,OAAOA,iBAAiB,MAAM,yBAAyB;AACvD,OAAOC,mBAAmB,MAAM,2BAA2B;AAC3D,SAASC,QAAQ,QAAQ,yBAAyB;;AAElD;AACA,SAASD,mBAAmB,EAAEC,QAAQ;AACtC,cAAc,SAAS;AACvB,eAAeF,iBAAiB","ignoreList":[]}
1
+ {"version":3,"names":["MyUploader","pickFile"],"sources":["index.ts"],"sourcesContent":["import MyUploader,{pickFile} from \"./components/MyUploader\";\r\n// import DownloadFile from \"./components/DownloadFile\";\r\n\r\n// 2. Diğerlerini NAMED olarak dışa aktar (import { DownloadFile, pickFile } ... için)\r\n// export { DownloadFile, pickFile };\r\n\r\n\r\n// Sadece bu paketle ilgili olanları dışa aktar\r\nexport { MyUploader, pickFile };\r\nexport * from './types';\r\n\r\n// Varsayılan dışa aktarım olarak da ana bileşeni verelim\r\nexport default MyUploader;\r\n\r\n\r\n\r\n"],"mappings":"AAAA,OAAOA,UAAU,IAAEC,QAAQ,QAAO,yBAAyB;AAC3D;;AAEA;AACA;;AAGA;AACA,SAASD,UAAU,EAAEC,QAAQ;AAC7B,cAAc,SAAS;;AAEvB;AACA,eAAeD,UAAU","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { StyleProp, TextStyle, ViewStyle } from 'react-native';\r\n\r\nexport interface FileInfo {\r\n fileName: string;\r\n fileSize: number; // in bytes\r\n fileType: string | null;\r\n fileUri: string;\r\n base64: string;\r\n}\r\n\r\nexport interface DocumentPickerOptions {\r\n multipleFiles?: boolean;\r\n fileTypes?: string[];\r\n maxSize?: number;\r\n maxFiles?: number;\r\n excludedUris?: string[];\r\n}\r\nexport interface MyUploaderProps extends DocumentPickerOptions {\r\n // Geri bildirim (callback) fonksiyonları\r\n onSelect: (files: FileInfo[]) => void;\r\n onError?: (error: Error) => void;\r\n buttonPlaceHolder?: string;\r\n ButtonStyle?: StyleProp<ViewStyle>;\r\n ButtonTextStyle?: StyleProp<TextStyle>;\r\n disabled?: boolean;\r\n}\r\n\r\n//download File Module Props\r\nexport interface DownloadedFileInfo {\r\n originalUrl: string;\r\n localUri: string; // Cihazdaki dosyanın URI'si\r\n}\r\n\r\n// YENİ: Atlanan dosyalar hakkında bilgi vermek için arayüz\r\nexport interface SkippedFileInfo {\r\n originalUrl: string;\r\n reason: string; // Neden atlandığı (örn: \"Dosya çok büyük\")\r\n}\r\n\r\n// YENİ: onSUCCESS callback'inin döndüreceği sonuç nesnesi\r\nexport interface DownloadResult {\r\n successful: DownloadedFileInfo[];\r\n skipped: SkippedFileInfo[];\r\n}\r\n\r\n// GÜNCELLENDİ: DownloadFileProps arayüzü\r\nexport interface DownloadFileProps {\r\n files: string[];\r\n // YENİ PROPLAR\r\n multipleLoad?: boolean;\r\n disabled?: boolean;\r\n debug?: boolean; // Mevcut debug prop'u\r\n\r\n maxSize?: number;\r\n fileTypes?: string[];\r\n buttonPlaceHolder?: string;\r\n buttonIcon?: React.ReactNode;\r\n ButtonStyle?: StyleProp<ViewStyle>;\r\n ButtonTextStyle?: StyleProp<TextStyle>;\r\n \r\n // GÜNCELLENDİ: Callback daha zengin bir nesne döndürecek\r\n onSuccess?: (result: DownloadResult) => void;\r\n onError?: (error: Error) => void;\r\n}"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["// import type { StyleProp, TextStyle, ViewStyle } from 'react-native';\r\n\r\n// export interface FileInfo {\r\n// fileName: string;\r\n// fileSize: number; \r\n// fileType: string | null;\r\n// fileUri: string;\r\n// base64: string;\r\n// }\r\n\r\n// export interface MyUploaderProps{\r\n// onSelect: (files: FileInfo[]) => void;\r\n// onError?: (error: Error) => void;\r\n// buttonPlaceHolder?: string;\r\n// ButtonStyle?: StyleProp<ViewStyle>;\r\n// ButtonTextStyle?: StyleProp<TextStyle>;\r\n// disabled?: boolean; \r\n// multipleFiles?: boolean;\r\n// fileTypes?: string[];\r\n// maxSize?: number;\r\n// maxFiles?: number;\r\n// excludedUris?: string[];\r\n// }\r\n\r\n// export interface DownloadedFileInfo {\r\n// originalUrl: string;\r\n// localUri: string;\r\n// }\r\n\r\n// export interface SkippedFileInfo {\r\n// originalUrl: string;\r\n// reason: string; \r\n// }\r\n\r\n\r\n\r\n// export interface UploadFileProps {\r\n// files: string[];\r\n// multipleLoad?: boolean;\r\n// disabled?: boolean;\r\n// debug?: boolean; \r\n// maxSize?: number;\r\n// fileTypes?: string[];\r\n// buttonPlaceHolder?: string;\r\n// buttonIcon?: React.ReactNode;\r\n// ButtonStyle?: StyleProp<ViewStyle>;\r\n// ButtonTextStyle?: StyleProp<TextStyle>;\r\n// onSuccess?: (result: DownloadResult) => void;\r\n// onError?: (error: Error) => void;\r\n// }\r\n\r\n// export interface DownloadFileProps {\r\n// files: string[];\r\n// multipleDownload?: boolean;\r\n// disabled?: boolean;\r\n// debug?: boolean;\r\n// maxSize?: number; // MB\r\n// fileTypes?: string[];\r\n// buttonPlaceHolder?: string;\r\n// buttonIcon?: React.ReactNode;\r\n// ButtonStyle?: ViewStyle;\r\n// ButtonTextStyle?: TextStyle;\r\n// onSuccess?: (result: DownloadResult) => void;\r\n// onError?: (error: any) => void;\r\n// }\r\n// export interface DownloadResult {\r\n// successful: { originalUrl: string; localUri: string | null }[];\r\n// skipped: { originalUrl: string; reason: string }[];\r\n// }\r\n\r\n\r\nimport type { ViewStyle, TextStyle } from 'react-native';\r\n\r\nexport interface FileInfo {\r\n uri: string;\r\n name: string;\r\n type: string;\r\n size: number;\r\n base64?: string | null;\r\n}\r\n\r\n\r\n// ----- MyUploader & pickFile Props -----\r\nexport interface DocumentPickerOptions {\r\n multipleFiles?: boolean;\r\n fileTypes?: string[]; // örn: ['image/*', 'application/pdf']\r\n maxSize?: number; // MB cinsinden\r\n maxFiles?: number;\r\n excludedUris?: string[];\r\n}\r\n\r\nexport interface MyUploaderProps extends DocumentPickerOptions {\r\n onSelect: (files: FileInfo[]) => void;\r\n onError?: (error: Error) => void;\r\n buttonPlaceHolder?: string;\r\n ButtonStyle?: ViewStyle;\r\n ButtonTextStyle?: TextStyle;\r\n disabled?: boolean;\r\n}\r\n\r\n// ----- DownloadFile Props -----\r\nexport interface DownloadFileProps {\r\n files: string[];\r\n multipleDownload?: boolean; // multipleFiles yerine multipleDownload (İsim karışmaması için)\r\n disabled?: boolean;\r\n debug?: boolean;\r\n maxSize?: number; // MB\r\n fileTypes?: string[]; // İndirilecek dosyanın Content-Type kontrolü\r\n buttonPlaceHolder?: string;\r\n buttonIcon?: React.ReactNode;\r\n ButtonStyle?: ViewStyle;\r\n ButtonTextStyle?: TextStyle;\r\n onSuccess?: (result: DownloadResult) => void;\r\n onError?: (error: any) => void;\r\n}\r\n\r\n\r\nexport interface DownloadResult {\r\n successful: { originalUrl: string; localUri: string | null }[];\r\n skipped: { originalUrl: string; reason: string }[];\r\n}"],"mappings":"","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-my-uploader-android",
3
- "version": "1.0.28",
3
+ "version": "1.0.30",
4
4
  "description": "file uploader for android",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./src/index.d.ts",
@@ -1,12 +1,14 @@
1
1
  import React, { useState } from 'react';
2
- import { NativeModules, TouchableOpacity, Text, StyleSheet, ActivityIndicator } from 'react-native';
2
+ import { TouchableOpacity, Text, StyleSheet, ActivityIndicator,NativeModules } from 'react-native';
3
3
  import type { DownloadFileProps, DownloadResult } from '../types';
4
4
 
5
- const { DownloadFile: DownloadFileModule } = NativeModules;
5
+
6
+ const { DownloadFile: NativeDownload } = NativeModules;
7
+
6
8
 
7
9
  const DownloadFile: React.FC<DownloadFileProps> = ({
8
10
  files,
9
- multipleLoad = false,
11
+ multipleDownload = false,
10
12
  disabled = false,
11
13
  debug = false,
12
14
  maxSize = 0,
@@ -15,92 +17,69 @@ const DownloadFile: React.FC<DownloadFileProps> = ({
15
17
  buttonIcon,
16
18
  ButtonStyle,
17
19
  ButtonTextStyle,
18
- onSuccess = () => {},
19
- onError = (error) => console.error('DownloadFile Error:', error),
20
+ onSuccess,
21
+ onError,
20
22
  }) => {
21
23
  const [isLoading, setIsLoading] = useState(false);
22
24
 
23
25
  const handlePress = async () => {
24
- if (!DownloadFileModule) {
25
- onError(new Error("DownloadFile native module is not available."));
26
- return;
27
- }
28
-
26
+ if (disabled || isLoading || !files.length) return;
29
27
  setIsLoading(true);
30
- const downloadOptions = { maxSize, fileTypes, debug };
31
-
32
- try {
33
- const filesToProcess = multipleLoad ? files : files.slice(0, 1);
34
- const downloadPromises = filesToProcess.map(url =>
35
- DownloadFileModule.downloadFile(url, downloadOptions)
36
- );
37
-
38
- const settledResults = await Promise.allSettled(downloadPromises);
39
28
 
40
- const finalResult: DownloadResult = { successful: [], skipped: [] };
29
+ const options = { debug, maxSize, fileTypes };
30
+ const targetFiles = multipleDownload ? files : [files[0]];
41
31
 
42
- settledResults.forEach((result, index) => {
43
- // DÜZELTME: `filesToProcess[index]` ifadesinin sonuna `!` ekleyerek
44
- // TypeScript'e bu değerin asla undefined olmayacağını bildiriyoruz.
45
- const originalUrl = filesToProcess[index]!;
32
+ try {
33
+ const promises = targetFiles.map(url => NativeDownload.downloadFile(url, options));
34
+ const results = await Promise.allSettled(promises);
35
+
36
+ const final: DownloadResult = { successful: [], skipped: [] };
46
37
 
47
- if (result.status === 'fulfilled') {
48
- finalResult.successful.push({
49
- originalUrl, // Artık hata vermeyecek
50
- localUri: result.value,
51
- });
38
+ results.forEach((res, index) => {
39
+ const originalUrl = targetFiles[index] ?? "";
40
+ if (res.status === 'fulfilled') {
41
+ final.successful.push({ originalUrl, localUri: res.value });
52
42
  } else {
53
- finalResult.skipped.push({
54
- originalUrl, // Artık hata vermeyecek
55
- reason: result.reason.message,
43
+ final.skipped.push({
44
+ originalUrl,
45
+ reason: res.reason?.message || "Bilinmeyen Hata"
56
46
  });
57
47
  }
58
48
  });
59
-
60
- onSuccess(finalResult);
61
49
 
62
- } catch (error: any) {
63
- onError(error);
50
+ if (onSuccess) onSuccess(final);
51
+ } catch (e) {
52
+ if (onError) onError(e);
53
+ else console.error(e);
64
54
  } finally {
65
55
  setIsLoading(false);
66
56
  }
67
57
  };
68
58
 
69
- const content = isLoading ? (
70
- <ActivityIndicator color="#FFFFFF" />
71
- ) : (
72
- buttonIcon || <Text style={[styles.buttonText, ButtonTextStyle]}>{buttonPlaceHolder}</Text>
73
- );
74
-
75
59
  return (
76
60
  <TouchableOpacity
77
- style={[styles.button, ButtonStyle, (disabled || isLoading) && styles.disabledButton]}
61
+ style={[styles.button, ButtonStyle, (disabled || isLoading) && styles.disabled]}
78
62
  onPress={handlePress}
79
63
  disabled={disabled || isLoading}
80
64
  >
81
- {content}
65
+ {isLoading ? (
66
+ <ActivityIndicator color="#FFF" />
67
+ ) : (
68
+ buttonIcon ? buttonIcon : <Text style={[styles.text, ButtonTextStyle]}>{buttonPlaceHolder}</Text>
69
+ )}
82
70
  </TouchableOpacity>
83
71
  );
84
72
  };
85
73
 
86
74
  const styles = StyleSheet.create({
87
- button: {
88
- backgroundColor: '#008CBA',
89
- paddingHorizontal: 20,
90
- paddingVertical: 10,
91
- borderRadius: 8,
92
- alignItems: 'center',
93
- justifyContent: 'center',
94
- flexDirection: 'row',
95
- },
96
- buttonText: {
97
- color: '#FFFFFF',
98
- fontSize: 16,
99
- fontWeight: 'bold',
100
- },
101
- disabledButton: {
102
- backgroundColor: '#A9A9A9',
103
- },
75
+ button: {
76
+ backgroundColor: '#03DAC6',
77
+ padding: 12,
78
+ borderRadius: 8,
79
+ alignItems: 'center',
80
+ },
81
+ text: { color: '#000', fontWeight: 'bold' },
82
+ disabled: { backgroundColor: '#AAA' }
104
83
  });
105
84
 
106
85
  export default DownloadFile;
@@ -1,127 +1,97 @@
1
- import React from 'react';
2
- import {NativeModules,TouchableOpacity,Text,StyleSheet} from 'react-native';
3
- import type {FileInfo,DocumentPickerOptions, MyUploaderProps} from '../types';
1
+ import React, { useState } from 'react';
2
+ import { TouchableOpacity, Text, StyleSheet, ActivityIndicator,NativeModules } from 'react-native';
3
+ import type { MyUploaderProps, DocumentPickerOptions, FileInfo } from '../types';
4
4
 
5
- const LINKING_ERROR = `The package 'react-native-my-uploader' doesn't seem to be linked.`;
5
+ const { UploadDocumentPicker: NativeUploadPicker } = NativeModules;
6
6
 
7
- const DocumentPicker = NativeModules.DocumentPicker
8
- ? NativeModules.DocumentPicker
9
- : new Proxy(
10
- {},
11
- {
12
- get() {
13
- throw new Error(LINKING_ERROR);
14
- },
15
- }
16
- );
17
-
18
- // Mevcut pickFile fonksiyonunu dahili (internal) olarak kullanmak üzere saklayalım.
19
- // İsterseniz bunu dışa aktarmaya devam edebilirsiniz.
20
- async function pickFile(
21
- options: DocumentPickerOptions = {}
22
- ): Promise<FileInfo[]> {
23
- const { multipleFiles = false, maxFiles = 0, ...rest } = options;
24
-
25
- if (!multipleFiles && maxFiles > 1) {
26
- throw new Error(
27
- '`maxFiles` cannot be greater than 1 when `multipleFiles` is false.'
28
- );
29
- }
30
- let effectiveMaxFiles = maxFiles;
31
- if (multipleFiles && maxFiles === 0) {
32
- effectiveMaxFiles = 3;
33
- }
34
- const finalOptions: DocumentPickerOptions = {
35
- ...rest,
36
- multipleFiles,
37
- maxFiles: effectiveMaxFiles,
38
- excludedUris: options.excludedUris ?? [],
39
- fileTypes: options.fileTypes ?? ['*/*'],
7
+ // 1. Standalone pickFile Fonksiyonu
8
+ export const pickFile = async (options: DocumentPickerOptions = {}): Promise<FileInfo[]> => {
9
+ if (!NativeUploadPicker) throw new Error("DocumentPicker module is not linked.");
10
+
11
+ // Native tarafa gönderilecek options
12
+ const nativeOptions = {
13
+ multipleFiles: options.multipleFiles ?? false,
14
+ maxFiles: options.maxFiles ?? 0,
40
15
  maxSize: options.maxSize ?? 0,
16
+ fileTypes: options.fileTypes ?? ['*/*'],
17
+ excludedUris: options.excludedUris ?? [],
41
18
  };
42
- return DocumentPicker.openDocument(finalOptions);
43
- }
44
19
 
45
- // YENİ: MyUploader Component'i
46
- const MyUploaderAndroid: React.FC<MyUploaderProps> = ({
47
- // DocumentPickerOptions
20
+ return await NativeUploadPicker.openDocument(nativeOptions);
21
+ };
22
+
23
+ // 2. MyUploader Bileşeni
24
+ const MyUploader: React.FC<MyUploaderProps> = ({
25
+ onSelect,
26
+ onError,
27
+ buttonPlaceHolder = "Dosya Seç",
28
+ ButtonStyle,
29
+ ButtonTextStyle,
30
+ disabled = false,
48
31
  multipleFiles = false,
49
- maxFiles = 0,
50
32
  fileTypes = ['*/*'],
51
33
  maxSize = 0,
34
+ maxFiles = 0,
52
35
  excludedUris = [],
53
- // UI Props with defaults
54
- buttonPlaceHolder = 'Dosya Seçin...',
55
- ButtonStyle,
56
- ButtonTextStyle,
57
- disabled = false,
58
- // Callbacks
59
- onSelect,
60
- onError = (error) => console.error('MyUploader Error:', error),
61
36
  }) => {
37
+ const [isLoading, setIsLoading] = useState(false);
38
+
62
39
  const handlePress = async () => {
40
+ if (disabled || isLoading) return;
41
+ setIsLoading(true);
42
+
63
43
  try {
64
- const options: DocumentPickerOptions = {
44
+ const files = await pickFile({
65
45
  multipleFiles,
66
- maxFiles,
67
46
  fileTypes,
68
47
  maxSize,
69
- excludedUris,
70
- };
71
- const selectedFiles = await pickFile(options);
48
+ maxFiles,
49
+ excludedUris
50
+ });
72
51
 
73
- // Eğer kullanıcı seçim yapmadan kapatırsa bazı sistemler boş array dönebilir.
74
- // Sadece doluysa callback'i tetikleyelim.
75
- if (selectedFiles && selectedFiles.length > 0) {
76
- onSelect(selectedFiles);
77
- }
78
-
52
+ onSelect(files);
79
53
  } catch (error: any) {
80
- // Kullanıcının seçimi iptal etmesi bir "hata" sayılmamalı,
81
- // bu yüzden sadece konsola yazdırıp onError'ı tetiklemeyebiliriz.
82
- // Native kodunuz "E_PICKER_CANCELLED" koduyla reject ediyor.
83
- if (error.code !== 'E_PICKER_CANCELLED') {
54
+ if (onError) {
84
55
  onError(error);
56
+ } else {
57
+ console.error("MyUploader Error:", error);
85
58
  }
59
+ } finally {
60
+ setIsLoading(false);
86
61
  }
87
62
  };
88
63
 
89
64
  return (
90
65
  <TouchableOpacity
91
- style={[styles.button, ButtonStyle, disabled && styles.disabledButton]}
66
+ style={[styles.button, ButtonStyle, (disabled || isLoading) && styles.disabled]}
92
67
  onPress={handlePress}
93
- disabled={disabled}
68
+ disabled={disabled || isLoading}
94
69
  >
95
- <Text style={[styles.buttonText, ButtonTextStyle]}>
96
- {buttonPlaceHolder}
97
- </Text>
70
+ {isLoading ? (
71
+ <ActivityIndicator color="#FFF" />
72
+ ) : (
73
+ <Text style={[styles.text, ButtonTextStyle]}>{buttonPlaceHolder}</Text>
74
+ )}
98
75
  </TouchableOpacity>
99
76
  );
100
77
  };
101
78
 
102
- // Varsayılan stiller
103
79
  const styles = StyleSheet.create({
104
80
  button: {
105
- backgroundColor: '#007AFF',
106
- paddingHorizontal: 20,
107
- paddingVertical: 10,
81
+ backgroundColor: '#6200EE',
82
+ padding: 12,
108
83
  borderRadius: 8,
109
84
  alignItems: 'center',
110
- justifyContent: 'center',
85
+ justifyContent: 'center'
111
86
  },
112
- buttonText: {
113
- color: '#FFFFFF',
114
- fontSize: 16,
115
- fontWeight: 'bold',
116
- },
117
- disabledButton: {
118
- backgroundColor: '#A9A9A9',
87
+ text: {
88
+ color: '#FFF',
89
+ fontWeight: '600',
90
+ fontSize: 16
119
91
  },
92
+ disabled: {
93
+ backgroundColor: '#B0B0B0'
94
+ }
120
95
  });
121
96
 
122
- // İhtiyaca göre pickFile'ı da export edebilirsiniz.
123
- export { pickFile };
124
- export type { FileInfo, DocumentPickerOptions, MyUploaderProps } from "../types";
125
-
126
- // Component'i varsayılan olarak export ediyoruz.
127
- export default MyUploaderAndroid;
97
+ export default MyUploader;