react-native-android-media-fetcher 1.0.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/LICENSE +21 -0
- package/README.md +398 -0
- package/android/build.gradle +111 -0
- package/android/gradle.properties +3 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/androidmediafetcher/AndroidMediaFetcherPackage.kt +21 -0
- package/android/src/main/java/com/androidmediafetcher/models/AudioFile.kt +57 -0
- package/android/src/main/java/com/androidmediafetcher/providers/AudioMediaProvider.kt +361 -0
- package/android/src/main/java/com/androidmediafetcher/providers/BaseMediaProvider.kt +43 -0
- package/android/src/newarch/java/com/androidmediafetcher/AndroidMediaFetcherModule.kt +173 -0
- package/android/src/newarch/java/com/androidmediafetcher/NativeAndroidMediaFetcherSpec.kt +21 -0
- package/android/src/oldarch/java/com/androidmediafetcher/AndroidMediaFetcherModule.kt +170 -0
- package/app.plugin.js +1 -0
- package/lib/commonjs/AudioFetcher.js +153 -0
- package/lib/commonjs/AudioFetcher.js.map +1 -0
- package/lib/commonjs/NativeModule.js +37 -0
- package/lib/commonjs/NativeModule.js.map +1 -0
- package/lib/commonjs/events.js +73 -0
- package/lib/commonjs/events.js.map +1 -0
- package/lib/commonjs/index.js +32 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/types.js +2 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/AudioFetcher.js +147 -0
- package/lib/module/AudioFetcher.js.map +1 -0
- package/lib/module/NativeModule.js +31 -0
- package/lib/module/NativeModule.js.map +1 -0
- package/lib/module/events.js +65 -0
- package/lib/module/events.js.map +1 -0
- package/lib/module/index.js +17 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/types.js +2 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/src/AudioFetcher.d.ts +93 -0
- package/lib/typescript/src/AudioFetcher.d.ts.map +1 -0
- package/lib/typescript/src/NativeModule.d.ts +21 -0
- package/lib/typescript/src/NativeModule.d.ts.map +1 -0
- package/lib/typescript/src/events.d.ts +38 -0
- package/lib/typescript/src/events.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +12 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +135 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +101 -0
- package/plugin/build/index.js +48 -0
- package/plugin/src/index.ts +63 -0
- package/plugin/tsconfig.json +34 -0
- package/react-native.config.js +12 -0
- package/src/AudioFetcher.ts +163 -0
- package/src/NativeModule.ts +44 -0
- package/src/events.ts +79 -0
- package/src/index.ts +29 -0
- package/src/types.ts +171 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
package com.androidmediafetcher
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
5
|
+
import com.facebook.react.bridge.ReactMethod
|
|
6
|
+
import com.facebook.react.bridge.Promise
|
|
7
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
8
|
+
import com.androidmediafetcher.providers.AudioMediaProvider
|
|
9
|
+
import kotlinx.coroutines.CoroutineScope
|
|
10
|
+
import kotlinx.coroutines.Dispatchers
|
|
11
|
+
import kotlinx.coroutines.SupervisorJob
|
|
12
|
+
import kotlinx.coroutines.launch
|
|
13
|
+
import kotlinx.coroutines.cancel
|
|
14
|
+
import org.json.JSONArray
|
|
15
|
+
import org.json.JSONObject
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* React Native Native Module for fetching audio files from Android MediaStore
|
|
19
|
+
* This version supports the old architecture (Bridge)
|
|
20
|
+
*/
|
|
21
|
+
class AndroidMediaFetcherModule(reactContext: ReactApplicationContext) :
|
|
22
|
+
ReactContextBaseJavaModule(reactContext) {
|
|
23
|
+
|
|
24
|
+
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
|
25
|
+
private val audioProvider by lazy { AudioMediaProvider(reactContext) }
|
|
26
|
+
|
|
27
|
+
override fun getName(): String = NAME
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Send event to JavaScript
|
|
31
|
+
*/
|
|
32
|
+
private fun sendEvent(eventName: String, params: Any?) {
|
|
33
|
+
reactApplicationContext
|
|
34
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
35
|
+
.emit(eventName, params)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get paginated audio files
|
|
40
|
+
*/
|
|
41
|
+
@ReactMethod
|
|
42
|
+
fun getAudioFiles(pageSize: Int, offset: Int, promise: Promise) {
|
|
43
|
+
scope.launch {
|
|
44
|
+
try {
|
|
45
|
+
val totalCount = audioProvider.getTotalCount()
|
|
46
|
+
val files = audioProvider.getItems(pageSize, offset)
|
|
47
|
+
|
|
48
|
+
val filesArray = JSONArray()
|
|
49
|
+
files.forEach { file ->
|
|
50
|
+
filesArray.put(file.toJson())
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
val result = JSONObject().apply {
|
|
54
|
+
put("files", filesArray)
|
|
55
|
+
put("totalCount", totalCount)
|
|
56
|
+
put("hasMore", offset + files.size < totalCount)
|
|
57
|
+
put("nextOffset", offset + files.size)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
promise.resolve(result.toString())
|
|
61
|
+
} catch (e: Exception) {
|
|
62
|
+
sendErrorEvent(e.message ?: "Unknown error", "FETCH_ERROR")
|
|
63
|
+
promise.reject("FETCH_ERROR", e.message, e)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Get all audio files with progress events
|
|
70
|
+
*/
|
|
71
|
+
@ReactMethod
|
|
72
|
+
fun getAllAudioFiles(promise: Promise) {
|
|
73
|
+
scope.launch {
|
|
74
|
+
try {
|
|
75
|
+
val files = audioProvider.getAllItems { current, total ->
|
|
76
|
+
val progress = JSONObject().apply {
|
|
77
|
+
put("current", current)
|
|
78
|
+
put("total", total)
|
|
79
|
+
put("percentage", if (total > 0) (current * 100 / total) else 0)
|
|
80
|
+
}
|
|
81
|
+
sendEvent(EVENT_PROGRESS, progress.toString())
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
val filesArray = JSONArray()
|
|
85
|
+
files.forEach { file ->
|
|
86
|
+
filesArray.put(file.toJson())
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
promise.resolve(filesArray.toString())
|
|
90
|
+
} catch (e: Exception) {
|
|
91
|
+
sendErrorEvent(e.message ?: "Unknown error", "FETCH_ALL_ERROR")
|
|
92
|
+
promise.reject("FETCH_ALL_ERROR", e.message, e)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get single audio file by ID
|
|
99
|
+
*/
|
|
100
|
+
@ReactMethod
|
|
101
|
+
fun getAudioFileById(id: String, promise: Promise) {
|
|
102
|
+
scope.launch {
|
|
103
|
+
try {
|
|
104
|
+
val file = audioProvider.getItemById(id)
|
|
105
|
+
if (file != null) {
|
|
106
|
+
promise.resolve(file.toJson().toString())
|
|
107
|
+
} else {
|
|
108
|
+
promise.resolve(null)
|
|
109
|
+
}
|
|
110
|
+
} catch (e: Exception) {
|
|
111
|
+
sendErrorEvent(e.message ?: "Unknown error", "FETCH_BY_ID_ERROR")
|
|
112
|
+
promise.reject("FETCH_BY_ID_ERROR", e.message, e)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Get total count of audio files
|
|
119
|
+
*/
|
|
120
|
+
@ReactMethod
|
|
121
|
+
fun getTotalAudioCount(promise: Promise) {
|
|
122
|
+
scope.launch {
|
|
123
|
+
try {
|
|
124
|
+
val count = audioProvider.getTotalCount()
|
|
125
|
+
promise.resolve(count)
|
|
126
|
+
} catch (e: Exception) {
|
|
127
|
+
sendErrorEvent(e.message ?: "Unknown error", "COUNT_ERROR")
|
|
128
|
+
promise.reject("COUNT_ERROR", e.message, e)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Required for NativeEventEmitter
|
|
135
|
+
*/
|
|
136
|
+
@ReactMethod
|
|
137
|
+
fun addListener(eventName: String) {
|
|
138
|
+
// Keep: Required for NativeEventEmitter
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Required for NativeEventEmitter
|
|
143
|
+
*/
|
|
144
|
+
@ReactMethod
|
|
145
|
+
fun removeListeners(count: Int) {
|
|
146
|
+
// Keep: Required for NativeEventEmitter
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Send error event to JavaScript
|
|
151
|
+
*/
|
|
152
|
+
private fun sendErrorEvent(message: String, code: String) {
|
|
153
|
+
val error = JSONObject().apply {
|
|
154
|
+
put("message", message)
|
|
155
|
+
put("code", code)
|
|
156
|
+
}
|
|
157
|
+
sendEvent(EVENT_ERROR, error.toString())
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
override fun invalidate() {
|
|
161
|
+
super.invalidate()
|
|
162
|
+
scope.cancel()
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
companion object {
|
|
166
|
+
const val NAME = "AndroidMediaFetcher"
|
|
167
|
+
private const val EVENT_PROGRESS = "MediaFetcher_Progress"
|
|
168
|
+
private const val EVENT_ERROR = "MediaFetcher_Error"
|
|
169
|
+
}
|
|
170
|
+
}
|
package/app.plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./plugin/build');
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.AudioFetcher = void 0;
|
|
7
|
+
var _reactNative = require("react-native");
|
|
8
|
+
var _NativeModule = require("./NativeModule");
|
|
9
|
+
/**
|
|
10
|
+
* Default page size for pagination
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_PAGE_SIZE = 50;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Maximum page size allowed
|
|
16
|
+
*/
|
|
17
|
+
const MAX_PAGE_SIZE = 500;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Parse JSON response from native module safely
|
|
21
|
+
*/
|
|
22
|
+
function parseNativeResponse(json) {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(json);
|
|
25
|
+
} catch {
|
|
26
|
+
throw new Error('Failed to parse response from native module');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Validate that we're running on Android
|
|
32
|
+
*/
|
|
33
|
+
function validatePlatform() {
|
|
34
|
+
if (_reactNative.Platform.OS !== 'android') {
|
|
35
|
+
throw new Error('react-native-android-media-fetcher only supports Android. ' + `Current platform: ${_reactNative.Platform.OS}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* AudioFetcher provides methods to fetch audio files from the device
|
|
41
|
+
* with full metadata including album art, artist, duration, etc.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* import { AudioFetcher } from 'react-native-android-media-fetcher';
|
|
46
|
+
*
|
|
47
|
+
* // Fetch first page of audio files
|
|
48
|
+
* const result = await AudioFetcher.getAudioFiles({ pageSize: 20 });
|
|
49
|
+
* console.log(result.files);
|
|
50
|
+
*
|
|
51
|
+
* // Fetch all audio files (with progress events)
|
|
52
|
+
* const allFiles = await AudioFetcher.getAllAudioFiles();
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
const AudioFetcher = exports.AudioFetcher = {
|
|
56
|
+
/**
|
|
57
|
+
* Fetch audio files with pagination
|
|
58
|
+
*
|
|
59
|
+
* @param options - Pagination options
|
|
60
|
+
* @returns Promise resolving to FetchResult with files and pagination info
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* // Fetch first page
|
|
65
|
+
* const result = await AudioFetcher.getAudioFiles({ pageSize: 20, offset: 0 });
|
|
66
|
+
*
|
|
67
|
+
* // Fetch next page
|
|
68
|
+
* if (result.hasMore) {
|
|
69
|
+
* const nextPage = await AudioFetcher.getAudioFiles({
|
|
70
|
+
* pageSize: 20,
|
|
71
|
+
* offset: result.nextOffset,
|
|
72
|
+
* });
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
async getAudioFiles(options) {
|
|
77
|
+
validatePlatform();
|
|
78
|
+
const pageSize = Math.min(Math.max(1, options?.pageSize ?? DEFAULT_PAGE_SIZE), MAX_PAGE_SIZE);
|
|
79
|
+
const offset = Math.max(0, options?.offset ?? 0);
|
|
80
|
+
const json = await _NativeModule.AndroidMediaFetcherModule.getAudioFiles(pageSize, offset);
|
|
81
|
+
return parseNativeResponse(json);
|
|
82
|
+
},
|
|
83
|
+
/**
|
|
84
|
+
* Fetch all audio files from the device
|
|
85
|
+
*
|
|
86
|
+
* For large libraries, use addProgressListener to track progress:
|
|
87
|
+
*
|
|
88
|
+
* @returns Promise resolving to array of all AudioFile objects
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* import { AudioFetcher, addProgressListener } from 'react-native-android-media-fetcher';
|
|
93
|
+
*
|
|
94
|
+
* const unsubscribe = addProgressListener((progress) => {
|
|
95
|
+
* console.log(`Loading: ${progress.percentage}%`);
|
|
96
|
+
* });
|
|
97
|
+
*
|
|
98
|
+
* const allFiles = await AudioFetcher.getAllAudioFiles();
|
|
99
|
+
* unsubscribe();
|
|
100
|
+
*
|
|
101
|
+
* console.log(`Found ${allFiles.length} audio files`);
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
async getAllAudioFiles() {
|
|
105
|
+
validatePlatform();
|
|
106
|
+
const json = await _NativeModule.AndroidMediaFetcherModule.getAllAudioFiles();
|
|
107
|
+
return parseNativeResponse(json);
|
|
108
|
+
},
|
|
109
|
+
/**
|
|
110
|
+
* Fetch a single audio file by its ID
|
|
111
|
+
*
|
|
112
|
+
* @param id - The unique ID of the audio file (from AudioFile.id)
|
|
113
|
+
* @returns Promise resolving to AudioFile or null if not found
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const file = await AudioFetcher.getAudioFileById('12345');
|
|
118
|
+
* if (file) {
|
|
119
|
+
* console.log(`Found: ${file.title} by ${file.artist}`);
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
async getAudioFileById(id) {
|
|
124
|
+
validatePlatform();
|
|
125
|
+
if (!id || typeof id !== 'string') {
|
|
126
|
+
throw new Error('Invalid audio file ID');
|
|
127
|
+
}
|
|
128
|
+
const json = await _NativeModule.AndroidMediaFetcherModule.getAudioFileById(id);
|
|
129
|
+
if (!json) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return parseNativeResponse(json);
|
|
133
|
+
},
|
|
134
|
+
/**
|
|
135
|
+
* Get the total count of audio files on the device
|
|
136
|
+
*
|
|
137
|
+
* This is a lightweight operation that only counts files without
|
|
138
|
+
* fetching their metadata.
|
|
139
|
+
*
|
|
140
|
+
* @returns Promise resolving to total number of audio files
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* const count = await AudioFetcher.getTotalAudioCount();
|
|
145
|
+
* console.log(`Device has ${count} audio files`);
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
async getTotalAudioCount() {
|
|
149
|
+
validatePlatform();
|
|
150
|
+
return _NativeModule.AndroidMediaFetcherModule.getTotalAudioCount();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
//# sourceMappingURL=AudioFetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_NativeModule","DEFAULT_PAGE_SIZE","MAX_PAGE_SIZE","parseNativeResponse","json","JSON","parse","Error","validatePlatform","Platform","OS","AudioFetcher","exports","getAudioFiles","options","pageSize","Math","min","max","offset","AndroidMediaFetcherModule","getAllAudioFiles","getAudioFileById","id","getTotalAudioCount"],"sourceRoot":"..\\..\\src","sources":["AudioFetcher.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,aAAA,GAAAD,OAAA;AAGA;AACA;AACA;AACA,MAAME,iBAAiB,GAAG,EAAE;;AAE5B;AACA;AACA;AACA,MAAMC,aAAa,GAAG,GAAG;;AAEzB;AACA;AACA;AACA,SAASC,mBAAmBA,CAAIC,IAAY,EAAK;EAC7C,IAAI;IACA,OAAOC,IAAI,CAACC,KAAK,CAACF,IAAI,CAAC;EAC3B,CAAC,CAAC,MAAM;IACJ,MAAM,IAAIG,KAAK,CAAC,6CAA6C,CAAC;EAClE;AACJ;;AAEA;AACA;AACA;AACA,SAASC,gBAAgBA,CAAA,EAAS;EAC9B,IAAIC,qBAAQ,CAACC,EAAE,KAAK,SAAS,EAAE;IAC3B,MAAM,IAAIH,KAAK,CACX,4DAA4D,GAC5D,qBAAqBE,qBAAQ,CAACC,EAAE,EACpC,CAAC;EACL;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,YAAY,GAAAC,OAAA,CAAAD,YAAA,GAAG;EACxB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,MAAME,aAAaA,CAACC,OAAsB,EAAwB;IAC9DN,gBAAgB,CAAC,CAAC;IAElB,MAAMO,QAAQ,GAAGC,IAAI,CAACC,GAAG,CACrBD,IAAI,CAACE,GAAG,CAAC,CAAC,EAAEJ,OAAO,EAAEC,QAAQ,IAAId,iBAAiB,CAAC,EACnDC,aACJ,CAAC;IACD,MAAMiB,MAAM,GAAGH,IAAI,CAACE,GAAG,CAAC,CAAC,EAAEJ,OAAO,EAAEK,MAAM,IAAI,CAAC,CAAC;IAEhD,MAAMf,IAAI,GAAG,MAAMgB,uCAAyB,CAACP,aAAa,CAACE,QAAQ,EAAEI,MAAM,CAAC;IAC5E,OAAOhB,mBAAmB,CAAcC,IAAI,CAAC;EACjD,CAAC;EAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,MAAMiB,gBAAgBA,CAAA,EAAyB;IAC3Cb,gBAAgB,CAAC,CAAC;IAElB,MAAMJ,IAAI,GAAG,MAAMgB,uCAAyB,CAACC,gBAAgB,CAAC,CAAC;IAC/D,OAAOlB,mBAAmB,CAAcC,IAAI,CAAC;EACjD,CAAC;EAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,MAAMkB,gBAAgBA,CAACC,EAAU,EAA6B;IAC1Df,gBAAgB,CAAC,CAAC;IAElB,IAAI,CAACe,EAAE,IAAI,OAAOA,EAAE,KAAK,QAAQ,EAAE;MAC/B,MAAM,IAAIhB,KAAK,CAAC,uBAAuB,CAAC;IAC5C;IAEA,MAAMH,IAAI,GAAG,MAAMgB,uCAAyB,CAACE,gBAAgB,CAACC,EAAE,CAAC;IACjE,IAAI,CAACnB,IAAI,EAAE;MACP,OAAO,IAAI;IACf;IACA,OAAOD,mBAAmB,CAAYC,IAAI,CAAC;EAC/C,CAAC;EAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,MAAMoB,kBAAkBA,CAAA,EAAoB;IACxChB,gBAAgB,CAAC,CAAC;IAElB,OAAOY,uCAAyB,CAACI,kBAAkB,CAAC,CAAC;EACzD;AACJ,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.MediaFetcherEventEmitter = exports.AndroidMediaFetcherModule = void 0;
|
|
7
|
+
var _reactNative = require("react-native");
|
|
8
|
+
const LINKING_ERROR = `The package 'react-native-android-media-fetcher' doesn't seem to be linked. Make sure: \n\n` + _reactNative.Platform.select({
|
|
9
|
+
ios: "- You have run 'pod install'\n",
|
|
10
|
+
default: ''
|
|
11
|
+
}) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go (use development builds instead)';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Native module interface - internal use only
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get the native module with proper error handling
|
|
19
|
+
*/
|
|
20
|
+
function getNativeModule() {
|
|
21
|
+
const module = _reactNative.NativeModules.AndroidMediaFetcher;
|
|
22
|
+
if (!module) {
|
|
23
|
+
throw new Error(LINKING_ERROR);
|
|
24
|
+
}
|
|
25
|
+
return module;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The native Android Media Fetcher module
|
|
30
|
+
*/
|
|
31
|
+
const AndroidMediaFetcherModule = exports.AndroidMediaFetcherModule = getNativeModule();
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Event emitter for native events
|
|
35
|
+
*/
|
|
36
|
+
const MediaFetcherEventEmitter = exports.MediaFetcherEventEmitter = new _reactNative.NativeEventEmitter(_reactNative.NativeModules.AndroidMediaFetcher);
|
|
37
|
+
//# sourceMappingURL=NativeModule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","default","getNativeModule","module","NativeModules","AndroidMediaFetcher","Error","AndroidMediaFetcherModule","exports","MediaFetcherEventEmitter","NativeEventEmitter"],"sourceRoot":"..\\..\\src","sources":["NativeModule.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,MAAMC,aAAa,GACf,6FAA6F,GAC7FC,qBAAQ,CAACC,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,8DAA8D;;AAElE;AACA;AACA;;AAUA;AACA;AACA;AACA,SAASC,eAAeA,CAAA,EAA6B;EACjD,MAAMC,MAAM,GAAGC,0BAAa,CAACC,mBAAmB;EAEhD,IAAI,CAACF,MAAM,EAAE;IACT,MAAM,IAAIG,KAAK,CAACT,aAAa,CAAC;EAClC;EAEA,OAAOM,MAAM;AACjB;;AAEA;AACA;AACA;AACO,MAAMI,yBAAyB,GAAAC,OAAA,CAAAD,yBAAA,GAAGL,eAAe,CAAC,CAAC;;AAE1D;AACA;AACA;AACO,MAAMO,wBAAwB,GAAAD,OAAA,CAAAC,wBAAA,GAAG,IAAIC,+BAAkB,CAC1DN,0BAAa,CAACC,mBAClB,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.addErrorListener = addErrorListener;
|
|
7
|
+
exports.addProgressListener = addProgressListener;
|
|
8
|
+
exports.removeAllListeners = removeAllListeners;
|
|
9
|
+
var _NativeModule = require("./NativeModule");
|
|
10
|
+
/**
|
|
11
|
+
* Event names used by the native module
|
|
12
|
+
*/
|
|
13
|
+
const EVENTS = {
|
|
14
|
+
PROGRESS: 'MediaFetcher_Progress',
|
|
15
|
+
ERROR: 'MediaFetcher_Error'
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Add a listener for progress updates during getAllAudioFiles operation
|
|
20
|
+
*
|
|
21
|
+
* @param listener - Callback function that receives progress updates
|
|
22
|
+
* @returns Unsubscribe function to remove the listener
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const unsubscribe = addProgressListener((progress) => {
|
|
27
|
+
* console.log(`Loading: ${progress.percentage}%`);
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // Later, when done:
|
|
31
|
+
* unsubscribe();
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
function addProgressListener(listener) {
|
|
35
|
+
const subscription = _NativeModule.MediaFetcherEventEmitter.addListener(EVENTS.PROGRESS, event => {
|
|
36
|
+
listener(event);
|
|
37
|
+
});
|
|
38
|
+
return () => {
|
|
39
|
+
subscription.remove();
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Add a listener for error events during fetch operations
|
|
45
|
+
*
|
|
46
|
+
* @param listener - Callback function that receives error information
|
|
47
|
+
* @returns Unsubscribe function to remove the listener
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const unsubscribe = addErrorListener((error) => {
|
|
52
|
+
* console.error(`Error: ${error.message} (${error.code})`);
|
|
53
|
+
* });
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
function addErrorListener(listener) {
|
|
57
|
+
const subscription = _NativeModule.MediaFetcherEventEmitter.addListener(EVENTS.ERROR, event => {
|
|
58
|
+
listener(event);
|
|
59
|
+
});
|
|
60
|
+
return () => {
|
|
61
|
+
subscription.remove();
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Remove all listeners for media fetcher events
|
|
67
|
+
* Useful for cleanup in useEffect
|
|
68
|
+
*/
|
|
69
|
+
function removeAllListeners() {
|
|
70
|
+
_NativeModule.MediaFetcherEventEmitter.removeAllListeners(EVENTS.PROGRESS);
|
|
71
|
+
_NativeModule.MediaFetcherEventEmitter.removeAllListeners(EVENTS.ERROR);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_NativeModule","require","EVENTS","PROGRESS","ERROR","addProgressListener","listener","subscription","MediaFetcherEventEmitter","addListener","event","remove","addErrorListener","removeAllListeners"],"sourceRoot":"..\\..\\src","sources":["events.ts"],"mappings":";;;;;;;;AAAA,IAAAA,aAAA,GAAAC,OAAA;AAQA;AACA;AACA;AACA,MAAMC,MAAM,GAAG;EACXC,QAAQ,EAAE,uBAAuB;EACjCC,KAAK,EAAE;AACX,CAAU;;AAEV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,mBAAmBA,CAACC,QAA0B,EAAe;EACzE,MAAMC,YAAY,GAAGC,sCAAwB,CAACC,WAAW,CACrDP,MAAM,CAACC,QAAQ,EACdO,KAAoB,IAAK;IACtBJ,QAAQ,CAACI,KAAK,CAAC;EACnB,CACJ,CAAC;EAED,OAAO,MAAM;IACTH,YAAY,CAACI,MAAM,CAAC,CAAC;EACzB,CAAC;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,gBAAgBA,CAACN,QAAuB,EAAe;EACnE,MAAMC,YAAY,GAAGC,sCAAwB,CAACC,WAAW,CACrDP,MAAM,CAACE,KAAK,EACXM,KAAwC,IAAK;IAC1CJ,QAAQ,CAACI,KAAK,CAAC;EACnB,CACJ,CAAC;EAED,OAAO,MAAM;IACTH,YAAY,CAACI,MAAM,CAAC,CAAC;EACzB,CAAC;AACL;;AAEA;AACA;AACA;AACA;AACO,SAASE,kBAAkBA,CAAA,EAAS;EACvCL,sCAAwB,CAACK,kBAAkB,CAACX,MAAM,CAACC,QAAQ,CAAC;EAC5DK,sCAAwB,CAACK,kBAAkB,CAACX,MAAM,CAACE,KAAK,CAAC;AAC7D","ignoreList":[]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "AudioFetcher", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _AudioFetcher.AudioFetcher;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "addErrorListener", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _events.addErrorListener;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "addProgressListener", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _events.addProgressListener;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "removeAllListeners", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _events.removeAllListeners;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
var _AudioFetcher = require("./AudioFetcher");
|
|
31
|
+
var _events = require("./events");
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_AudioFetcher","require","_events"],"sourceRoot":"..\\..\\src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,IAAAA,aAAA,GAAAC,OAAA;AAGA,IAAAC,OAAA,GAAAD,OAAA","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"..\\..\\src","sources":["types.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import { AndroidMediaFetcherModule } from './NativeModule';
|
|
3
|
+
/**
|
|
4
|
+
* Default page size for pagination
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_PAGE_SIZE = 50;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Maximum page size allowed
|
|
10
|
+
*/
|
|
11
|
+
const MAX_PAGE_SIZE = 500;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parse JSON response from native module safely
|
|
15
|
+
*/
|
|
16
|
+
function parseNativeResponse(json) {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(json);
|
|
19
|
+
} catch {
|
|
20
|
+
throw new Error('Failed to parse response from native module');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Validate that we're running on Android
|
|
26
|
+
*/
|
|
27
|
+
function validatePlatform() {
|
|
28
|
+
if (Platform.OS !== 'android') {
|
|
29
|
+
throw new Error('react-native-android-media-fetcher only supports Android. ' + `Current platform: ${Platform.OS}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* AudioFetcher provides methods to fetch audio files from the device
|
|
35
|
+
* with full metadata including album art, artist, duration, etc.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* import { AudioFetcher } from 'react-native-android-media-fetcher';
|
|
40
|
+
*
|
|
41
|
+
* // Fetch first page of audio files
|
|
42
|
+
* const result = await AudioFetcher.getAudioFiles({ pageSize: 20 });
|
|
43
|
+
* console.log(result.files);
|
|
44
|
+
*
|
|
45
|
+
* // Fetch all audio files (with progress events)
|
|
46
|
+
* const allFiles = await AudioFetcher.getAllAudioFiles();
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export const AudioFetcher = {
|
|
50
|
+
/**
|
|
51
|
+
* Fetch audio files with pagination
|
|
52
|
+
*
|
|
53
|
+
* @param options - Pagination options
|
|
54
|
+
* @returns Promise resolving to FetchResult with files and pagination info
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* // Fetch first page
|
|
59
|
+
* const result = await AudioFetcher.getAudioFiles({ pageSize: 20, offset: 0 });
|
|
60
|
+
*
|
|
61
|
+
* // Fetch next page
|
|
62
|
+
* if (result.hasMore) {
|
|
63
|
+
* const nextPage = await AudioFetcher.getAudioFiles({
|
|
64
|
+
* pageSize: 20,
|
|
65
|
+
* offset: result.nextOffset,
|
|
66
|
+
* });
|
|
67
|
+
* }
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
async getAudioFiles(options) {
|
|
71
|
+
validatePlatform();
|
|
72
|
+
const pageSize = Math.min(Math.max(1, options?.pageSize ?? DEFAULT_PAGE_SIZE), MAX_PAGE_SIZE);
|
|
73
|
+
const offset = Math.max(0, options?.offset ?? 0);
|
|
74
|
+
const json = await AndroidMediaFetcherModule.getAudioFiles(pageSize, offset);
|
|
75
|
+
return parseNativeResponse(json);
|
|
76
|
+
},
|
|
77
|
+
/**
|
|
78
|
+
* Fetch all audio files from the device
|
|
79
|
+
*
|
|
80
|
+
* For large libraries, use addProgressListener to track progress:
|
|
81
|
+
*
|
|
82
|
+
* @returns Promise resolving to array of all AudioFile objects
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* import { AudioFetcher, addProgressListener } from 'react-native-android-media-fetcher';
|
|
87
|
+
*
|
|
88
|
+
* const unsubscribe = addProgressListener((progress) => {
|
|
89
|
+
* console.log(`Loading: ${progress.percentage}%`);
|
|
90
|
+
* });
|
|
91
|
+
*
|
|
92
|
+
* const allFiles = await AudioFetcher.getAllAudioFiles();
|
|
93
|
+
* unsubscribe();
|
|
94
|
+
*
|
|
95
|
+
* console.log(`Found ${allFiles.length} audio files`);
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
async getAllAudioFiles() {
|
|
99
|
+
validatePlatform();
|
|
100
|
+
const json = await AndroidMediaFetcherModule.getAllAudioFiles();
|
|
101
|
+
return parseNativeResponse(json);
|
|
102
|
+
},
|
|
103
|
+
/**
|
|
104
|
+
* Fetch a single audio file by its ID
|
|
105
|
+
*
|
|
106
|
+
* @param id - The unique ID of the audio file (from AudioFile.id)
|
|
107
|
+
* @returns Promise resolving to AudioFile or null if not found
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const file = await AudioFetcher.getAudioFileById('12345');
|
|
112
|
+
* if (file) {
|
|
113
|
+
* console.log(`Found: ${file.title} by ${file.artist}`);
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
async getAudioFileById(id) {
|
|
118
|
+
validatePlatform();
|
|
119
|
+
if (!id || typeof id !== 'string') {
|
|
120
|
+
throw new Error('Invalid audio file ID');
|
|
121
|
+
}
|
|
122
|
+
const json = await AndroidMediaFetcherModule.getAudioFileById(id);
|
|
123
|
+
if (!json) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
return parseNativeResponse(json);
|
|
127
|
+
},
|
|
128
|
+
/**
|
|
129
|
+
* Get the total count of audio files on the device
|
|
130
|
+
*
|
|
131
|
+
* This is a lightweight operation that only counts files without
|
|
132
|
+
* fetching their metadata.
|
|
133
|
+
*
|
|
134
|
+
* @returns Promise resolving to total number of audio files
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* const count = await AudioFetcher.getTotalAudioCount();
|
|
139
|
+
* console.log(`Device has ${count} audio files`);
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
async getTotalAudioCount() {
|
|
143
|
+
validatePlatform();
|
|
144
|
+
return AndroidMediaFetcherModule.getTotalAudioCount();
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
//# sourceMappingURL=AudioFetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Platform","AndroidMediaFetcherModule","DEFAULT_PAGE_SIZE","MAX_PAGE_SIZE","parseNativeResponse","json","JSON","parse","Error","validatePlatform","OS","AudioFetcher","getAudioFiles","options","pageSize","Math","min","max","offset","getAllAudioFiles","getAudioFileById","id","getTotalAudioCount"],"sourceRoot":"..\\..\\src","sources":["AudioFetcher.ts"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,yBAAyB,QAAQ,gBAAgB;AAG1D;AACA;AACA;AACA,MAAMC,iBAAiB,GAAG,EAAE;;AAE5B;AACA;AACA;AACA,MAAMC,aAAa,GAAG,GAAG;;AAEzB;AACA;AACA;AACA,SAASC,mBAAmBA,CAAIC,IAAY,EAAK;EAC7C,IAAI;IACA,OAAOC,IAAI,CAACC,KAAK,CAACF,IAAI,CAAC;EAC3B,CAAC,CAAC,MAAM;IACJ,MAAM,IAAIG,KAAK,CAAC,6CAA6C,CAAC;EAClE;AACJ;;AAEA;AACA;AACA;AACA,SAASC,gBAAgBA,CAAA,EAAS;EAC9B,IAAIT,QAAQ,CAACU,EAAE,KAAK,SAAS,EAAE;IAC3B,MAAM,IAAIF,KAAK,CACX,4DAA4D,GAC5D,qBAAqBR,QAAQ,CAACU,EAAE,EACpC,CAAC;EACL;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,YAAY,GAAG;EACxB;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,MAAMC,aAAaA,CAACC,OAAsB,EAAwB;IAC9DJ,gBAAgB,CAAC,CAAC;IAElB,MAAMK,QAAQ,GAAGC,IAAI,CAACC,GAAG,CACrBD,IAAI,CAACE,GAAG,CAAC,CAAC,EAAEJ,OAAO,EAAEC,QAAQ,IAAIZ,iBAAiB,CAAC,EACnDC,aACJ,CAAC;IACD,MAAMe,MAAM,GAAGH,IAAI,CAACE,GAAG,CAAC,CAAC,EAAEJ,OAAO,EAAEK,MAAM,IAAI,CAAC,CAAC;IAEhD,MAAMb,IAAI,GAAG,MAAMJ,yBAAyB,CAACW,aAAa,CAACE,QAAQ,EAAEI,MAAM,CAAC;IAC5E,OAAOd,mBAAmB,CAAcC,IAAI,CAAC;EACjD,CAAC;EAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,MAAMc,gBAAgBA,CAAA,EAAyB;IAC3CV,gBAAgB,CAAC,CAAC;IAElB,MAAMJ,IAAI,GAAG,MAAMJ,yBAAyB,CAACkB,gBAAgB,CAAC,CAAC;IAC/D,OAAOf,mBAAmB,CAAcC,IAAI,CAAC;EACjD,CAAC;EAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,MAAMe,gBAAgBA,CAACC,EAAU,EAA6B;IAC1DZ,gBAAgB,CAAC,CAAC;IAElB,IAAI,CAACY,EAAE,IAAI,OAAOA,EAAE,KAAK,QAAQ,EAAE;MAC/B,MAAM,IAAIb,KAAK,CAAC,uBAAuB,CAAC;IAC5C;IAEA,MAAMH,IAAI,GAAG,MAAMJ,yBAAyB,CAACmB,gBAAgB,CAACC,EAAE,CAAC;IACjE,IAAI,CAAChB,IAAI,EAAE;MACP,OAAO,IAAI;IACf;IACA,OAAOD,mBAAmB,CAAYC,IAAI,CAAC;EAC/C,CAAC;EAED;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACI,MAAMiB,kBAAkBA,CAAA,EAAoB;IACxCb,gBAAgB,CAAC,CAAC;IAElB,OAAOR,yBAAyB,CAACqB,kBAAkB,CAAC,CAAC;EACzD;AACJ,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NativeModules, Platform, NativeEventEmitter } from 'react-native';
|
|
2
|
+
const LINKING_ERROR = `The package 'react-native-android-media-fetcher' doesn't seem to be linked. Make sure: \n\n` + Platform.select({
|
|
3
|
+
ios: "- You have run 'pod install'\n",
|
|
4
|
+
default: ''
|
|
5
|
+
}) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go (use development builds instead)';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Native module interface - internal use only
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Get the native module with proper error handling
|
|
13
|
+
*/
|
|
14
|
+
function getNativeModule() {
|
|
15
|
+
const module = NativeModules.AndroidMediaFetcher;
|
|
16
|
+
if (!module) {
|
|
17
|
+
throw new Error(LINKING_ERROR);
|
|
18
|
+
}
|
|
19
|
+
return module;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The native Android Media Fetcher module
|
|
24
|
+
*/
|
|
25
|
+
export const AndroidMediaFetcherModule = getNativeModule();
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Event emitter for native events
|
|
29
|
+
*/
|
|
30
|
+
export const MediaFetcherEventEmitter = new NativeEventEmitter(NativeModules.AndroidMediaFetcher);
|
|
31
|
+
//# sourceMappingURL=NativeModule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NativeModules","Platform","NativeEventEmitter","LINKING_ERROR","select","ios","default","getNativeModule","module","AndroidMediaFetcher","Error","AndroidMediaFetcherModule","MediaFetcherEventEmitter"],"sourceRoot":"..\\..\\src","sources":["NativeModule.ts"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,EAAEC,kBAAkB,QAAQ,cAAc;AAE1E,MAAMC,aAAa,GACf,6FAA6F,GAC7FF,QAAQ,CAACG,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,8DAA8D;;AAElE;AACA;AACA;;AAUA;AACA;AACA;AACA,SAASC,eAAeA,CAAA,EAA6B;EACjD,MAAMC,MAAM,GAAGR,aAAa,CAACS,mBAAmB;EAEhD,IAAI,CAACD,MAAM,EAAE;IACT,MAAM,IAAIE,KAAK,CAACP,aAAa,CAAC;EAClC;EAEA,OAAOK,MAAM;AACjB;;AAEA;AACA;AACA;AACA,OAAO,MAAMG,yBAAyB,GAAGJ,eAAe,CAAC,CAAC;;AAE1D;AACA;AACA;AACA,OAAO,MAAMK,wBAAwB,GAAG,IAAIV,kBAAkB,CAC1DF,aAAa,CAACS,mBAClB,CAAC","ignoreList":[]}
|