@ammarahmed/react-native-upload 6.16.0 → 6.17.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.
@@ -0,0 +1 @@
1
+ <manifest />
@@ -0,0 +1,63 @@
1
+ package com.appfolio.extensions
2
+
3
+ import android.content.Context
4
+ import com.appfolio.work.TaskCompletionNotifier
5
+ import com.appfolio.work.UploadManager
6
+ import net.gotev.uploadservice.UploadTask
7
+ import net.gotev.uploadservice.data.UploadNotificationConfig
8
+ import net.gotev.uploadservice.data.UploadTaskParameters
9
+ import net.gotev.uploadservice.logger.UploadServiceLogger
10
+ import net.gotev.uploadservice.observer.task.BroadcastEmitter
11
+
12
+ data class UploadTaskCreationParameters(
13
+ val params: UploadTaskParameters,
14
+ val notificationConfig: UploadNotificationConfig
15
+ )
16
+
17
+ /**
18
+ * Creates a new task instance based on the requested task class in the intent.
19
+ * @param creationParameters task creation params
20
+ * @return task instance or null if the task class is not supported or invalid
21
+ */
22
+ @Suppress("UNCHECKED_CAST")
23
+ fun Context.getUploadTask(
24
+ creationParameters: UploadTaskCreationParameters,
25
+ notificationId: Int
26
+ ): UploadTask? {
27
+ return try {
28
+ val observers = arrayOf(
29
+ BroadcastEmitter(this),
30
+ TaskCompletionNotifier()
31
+ )
32
+
33
+ val taskClass = Class.forName(creationParameters.params.taskClass) as Class<out UploadTask>
34
+ val uploadTask = taskClass.newInstance().apply {
35
+ init(
36
+ context = this@getUploadTask,
37
+ taskParams = creationParameters.params,
38
+ notificationConfig = creationParameters.notificationConfig,
39
+ notificationId = notificationId,
40
+ taskObservers = observers
41
+ )
42
+ }
43
+
44
+ UploadServiceLogger.debug(
45
+ component = UploadManager.TAG,
46
+ uploadId = creationParameters.params.id,
47
+ message = {
48
+ "Successfully created new task with class: ${taskClass.name}"
49
+ }
50
+ )
51
+ uploadTask
52
+ } catch (exc: Throwable) {
53
+ UploadServiceLogger.error(
54
+ component = UploadManager.TAG,
55
+ uploadId = "",
56
+ exception = exc,
57
+ message = {
58
+ "Error while instantiating new task"
59
+ }
60
+ )
61
+ null
62
+ }
63
+ }
@@ -0,0 +1,57 @@
1
+ package com.appfolio.extensions
2
+
3
+ import androidx.work.Constraints
4
+ import androidx.work.Data
5
+ import androidx.work.NetworkType
6
+ import androidx.work.OneTimeWorkRequest
7
+ import com.google.gson.Gson
8
+ import net.gotev.uploadservice.data.UploadFile
9
+ import net.gotev.uploadservice.data.UploadNotificationConfig
10
+ import net.gotev.uploadservice.data.UploadTaskParameters
11
+ import net.gotev.uploadservice.extensions.setOrRemove
12
+ import net.gotev.uploadservice.persistence.PersistableData
13
+
14
+ private const val PROPERTY_PARAM_NAME = "multipartParamName"
15
+ private const val PROPERTY_REMOTE_FILE_NAME = "multipartRemoteFileName"
16
+ private const val PROPERTY_CONTENT_TYPE = "multipartContentType"
17
+ const val PARAM_KEY_TASK_PARAMS = "PARAM_KEY_TASK_PARAMS"
18
+ const val PARAM_KEY_NOTIF_CONFIG = "PARAM_KEY_NOTIF_CONFIG"
19
+
20
+ internal var UploadFile.parameterName: String?
21
+ get() = properties[PROPERTY_PARAM_NAME]
22
+ set(value) {
23
+ properties.setOrRemove(PROPERTY_PARAM_NAME, value)
24
+ }
25
+
26
+ internal var UploadFile.remoteFileName: String?
27
+ get() = properties[PROPERTY_REMOTE_FILE_NAME]
28
+ set(value) {
29
+ properties.setOrRemove(PROPERTY_REMOTE_FILE_NAME, value)
30
+ }
31
+
32
+ internal var UploadFile.contentType: String?
33
+ get() = properties[PROPERTY_CONTENT_TYPE]
34
+ set(value) {
35
+ properties.setOrRemove(PROPERTY_CONTENT_TYPE, value)
36
+ }
37
+
38
+ internal fun UploadTaskParameters.toJson(): String = toPersistableData().toJson()
39
+
40
+ internal fun String.toUploadTaskParameters(): UploadTaskParameters = UploadTaskParameters.createFromPersistableData(PersistableData.fromJson(this))
41
+
42
+ internal fun UploadNotificationConfig.toJson(): String = Gson().toJson(this)
43
+
44
+ internal fun String.toUploadNotificationConfig() = Gson().fromJson(this, UploadNotificationConfig::class.java)
45
+
46
+ internal fun OneTimeWorkRequest.Builder.setData(uploadTaskParameters: UploadTaskParameters, notificationConfig: UploadNotificationConfig) {
47
+ val data = Data.Builder()
48
+ data.putString(PARAM_KEY_TASK_PARAMS, uploadTaskParameters.toJson())
49
+ data.putString(PARAM_KEY_NOTIF_CONFIG, notificationConfig.toJson())
50
+ setInputData(data.build())
51
+ }
52
+
53
+ internal fun OneTimeWorkRequest.Builder.shouldLimitNetwork(limit: Boolean) {
54
+ val network = if (limit) NetworkType.UNMETERED else NetworkType.CONNECTED
55
+ val constraints = Constraints.Builder().setRequiredNetworkType(network).build()
56
+ setConstraints(constraints)
57
+ }
@@ -0,0 +1,62 @@
1
+ package com.appfolio.uploader
2
+
3
+ import android.content.Context
4
+ import android.util.Log
5
+ import com.facebook.react.bridge.Arguments
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.bridge.WritableMap
8
+ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
9
+ import net.gotev.uploadservice.data.UploadInfo
10
+ import net.gotev.uploadservice.network.ServerResponse
11
+ import net.gotev.uploadservice.observer.request.RequestObserverDelegate
12
+
13
+ class GlobalRequestObserverDelegate(reactContext: ReactApplicationContext) : RequestObserverDelegate {
14
+ private val TAG = "UploadReceiver"
15
+
16
+ private var reactContext: ReactApplicationContext = reactContext
17
+
18
+ override fun onCompleted(context: Context, uploadInfo: UploadInfo) {
19
+ }
20
+
21
+ override fun onCompletedWhileNotObserving() {
22
+ }
23
+
24
+ override fun onError(context: Context, uploadInfo: UploadInfo, exception: Throwable) {
25
+
26
+ val params = Arguments.createMap()
27
+ params.putString("id", uploadInfo.uploadId)
28
+
29
+ // Make sure we do not try to call getMessage() on a null object
30
+ if (exception != null) {
31
+ params.putString("error", exception.message)
32
+ } else {
33
+ params.putString("error", "Unknown exception")
34
+ }
35
+
36
+ sendEvent("error", params, context)
37
+ }
38
+
39
+ override fun onProgress(context: Context, uploadInfo: UploadInfo) {
40
+ val params = Arguments.createMap()
41
+ params.putString("id", uploadInfo.uploadId)
42
+ params.putInt("progress", uploadInfo.progressPercent) //0-100
43
+
44
+ sendEvent("progress", params, context)
45
+ }
46
+
47
+ override fun onSuccess(context: Context, uploadInfo: UploadInfo, serverResponse: ServerResponse) {
48
+ val params = Arguments.createMap()
49
+ params.putString("id", uploadInfo.uploadId)
50
+ params.putInt("responseCode", serverResponse.code)
51
+ params.putString("responseBody", serverResponse.bodyString)
52
+ sendEvent("completed", params, context)
53
+ }
54
+
55
+ /**
56
+ * Sends an event to the JS module.
57
+ */
58
+ private fun sendEvent(eventName: String, params: WritableMap?, context: Context) {
59
+ reactContext?.getJSModule(RCTDeviceEventEmitter::class.java)?.emit("RNFileUploader-$eventName", params)
60
+ ?: Log.e(TAG, "sendEvent() failed due reactContext == null!")
61
+ }
62
+ }
@@ -0,0 +1,29 @@
1
+ package com.appfolio.uploader
2
+ import android.content.Context
3
+ import net.gotev.uploadservice.UploadTask
4
+ import net.gotev.uploadservice.data.UploadFile
5
+ import net.gotev.uploadservice.protocols.binary.BinaryUploadRequest
6
+ import net.gotev.uploadservice.protocols.binary.BinaryUploadTask
7
+ import java.io.FileNotFoundException
8
+ import java.io.IOException
9
+
10
+ class ModifiedBinaryUploadRequest(context: Context, serverUrl: String, limitNetwork: Boolean) :
11
+ ModifiedHttpUploadRequest<ModifiedBinaryUploadRequest>(context, serverUrl, limitNetwork) {
12
+
13
+ override val taskClass: Class<out UploadTask>
14
+ get() = BinaryUploadTask::class.java
15
+
16
+ /**
17
+ * Sets the file used as raw body of the upload request.
18
+ *
19
+ * @param path path to the file that you want to upload
20
+ * @throws FileNotFoundException if the file to upload does not exist
21
+ * @return [BinaryUploadRequest]
22
+ */
23
+ @Throws(IOException::class)
24
+ fun setFileToUpload(path: String): ModifiedBinaryUploadRequest {
25
+ files.clear()
26
+ files.add(UploadFile(path))
27
+ return this
28
+ }
29
+ }
@@ -0,0 +1,57 @@
1
+ package com.appfolio.uploader
2
+
3
+ import android.content.Context
4
+ import androidx.work.OneTimeWorkRequest
5
+ import androidx.work.WorkManager
6
+ import com.appfolio.extensions.setData
7
+ import com.appfolio.extensions.shouldLimitNetwork
8
+ import com.appfolio.work.UploadManager
9
+ import com.appfolio.work.UploadWorker
10
+ import net.gotev.uploadservice.HttpUploadRequest
11
+ import net.gotev.uploadservice.data.UploadTaskParameters
12
+ import java.util.*
13
+
14
+ abstract class ModifiedHttpUploadRequest<B : HttpUploadRequest<B>>(context: Context, serverUrl: String, private val limitNetwork: Boolean = false) :
15
+ HttpUploadRequest<B>(context, serverUrl) {
16
+
17
+ private var started: Boolean = false
18
+ private var uploadId = UUID.randomUUID().toString()
19
+ private val uploadTaskParameters: UploadTaskParameters
20
+ get() = UploadTaskParameters(
21
+ taskClass = taskClass.name,
22
+ id = uploadId,
23
+ serverUrl = serverUrl,
24
+ maxRetries = maxRetries,
25
+ autoDeleteSuccessfullyUploadedFiles = autoDeleteSuccessfullyUploadedFiles,
26
+ files = files,
27
+ additionalParameters = getAdditionalParameters()
28
+ )
29
+
30
+ override fun startUpload(): String {
31
+ require(files.isNotEmpty()) { "Set the file to be used in the request body first!" }
32
+ check(!started) {
33
+ "You have already called startUpload() on this Upload request instance once and you " +
34
+ "cannot call it multiple times. Check your code."
35
+ }
36
+
37
+ check(!UploadManager.taskList.contains(uploadTaskParameters.id)) {
38
+ "You have tried to perform startUpload() using the same uploadID of an " +
39
+ "already running task. You're trying to use the same ID for multiple uploads."
40
+ }
41
+
42
+ started = true
43
+ val workManager: WorkManager = WorkManager.getInstance(context)
44
+ val uploadRequest = OneTimeWorkRequest.Builder(UploadWorker::class.java)
45
+ uploadRequest.shouldLimitNetwork(limitNetwork)
46
+ uploadRequest.addTag("${UploadWorker::class.java.simpleName}-$uploadId")
47
+ uploadRequest.setData(uploadTaskParameters, notificationConfig(context, uploadId))
48
+ workManager.enqueue(uploadRequest.build())
49
+
50
+ return uploadTaskParameters.id;
51
+ }
52
+
53
+ fun setCustomUploadID(uploadID: String) {
54
+ this.uploadId = uploadID
55
+ setUploadID(uploadID)
56
+ }
57
+ }
@@ -0,0 +1,60 @@
1
+ package com.appfolio.uploader
2
+
3
+ import android.content.Context
4
+ import com.appfolio.extensions.contentType
5
+ import com.appfolio.extensions.parameterName
6
+ import com.appfolio.extensions.remoteFileName
7
+ import net.gotev.uploadservice.UploadTask
8
+ import net.gotev.uploadservice.data.UploadFile
9
+ import net.gotev.uploadservice.protocols.multipart.MultipartUploadTask
10
+ import java.io.FileNotFoundException
11
+
12
+ class ModifiedMultipartUploadRequest(context: Context, serverUrl: String, limitNetwork: Boolean) :
13
+ ModifiedHttpUploadRequest<ModifiedMultipartUploadRequest>(context, serverUrl, limitNetwork) {
14
+
15
+ override val taskClass: Class<out UploadTask>
16
+ get() = MultipartUploadTask::class.java
17
+
18
+ /**
19
+ * Adds a file to this upload request.
20
+ *
21
+ * @param filePath path to the file that you want to upload
22
+ * @param parameterName Name of the form parameter that will contain file's data
23
+ * @param fileName File name seen by the server side script. If null, the original file name
24
+ * will be used
25
+ * @param contentType Content type of the file. If null or empty, the mime type will be
26
+ * automatically detected. If fore some reasons autodetection fails,
27
+ * `application/octet-stream` will be used by default
28
+ * @return [ModifiedMultipartUploadRequest]
29
+ */
30
+ @Throws(FileNotFoundException::class)
31
+ @JvmOverloads
32
+ fun addFileToUpload(
33
+ filePath: String,
34
+ parameterName: String,
35
+ fileName: String? = null,
36
+ contentType: String? = null
37
+ ): ModifiedMultipartUploadRequest {
38
+ require(filePath.isNotBlank() && parameterName.isNotBlank()) {
39
+ "Please specify valid filePath and parameterName. They cannot be blank."
40
+ }
41
+
42
+ files.add(UploadFile(filePath).apply {
43
+ this.parameterName = parameterName
44
+
45
+ this.contentType = if (contentType.isNullOrBlank()) {
46
+ handler.contentType(context)
47
+ } else {
48
+ contentType
49
+ }
50
+
51
+ remoteFileName = if (fileName.isNullOrBlank()) {
52
+ handler.name(context)
53
+ } else {
54
+ fileName
55
+ }
56
+ })
57
+
58
+ return this
59
+ }
60
+ }