mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-29 01:48:53 +03:00
add cancel upload functionality
Signed-off-by: parneet-guraya <gurayaparneet@gmail.com>
This commit is contained in:
parent
64732b8155
commit
6f88c8bcbd
3 changed files with 75 additions and 12 deletions
|
@ -60,6 +60,7 @@ import com.nextcloud.talk.utils.permissions.PlatformPermissionUtil
|
|||
import com.nextcloud.talk.utils.preferences.AppPreferences
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.OkHttpClient
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
@AutoInjector(NextcloudTalkApplication::class)
|
||||
|
@ -91,6 +92,9 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
lateinit var roomToken: String
|
||||
lateinit var conversationName: String
|
||||
lateinit var currentUser: User
|
||||
private var isChunkedUploading = false
|
||||
private var file: File? = null
|
||||
private var chunkedFileUploader: ChunkedFileUploader? = null
|
||||
|
||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
override fun doWork(): Result {
|
||||
|
@ -120,28 +124,30 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
|
||||
val sourceFileUri = Uri.parse(sourceFile)
|
||||
fileName = FileUtils.getFileName(sourceFileUri, context)
|
||||
val file = FileUtils.getFileFromUri(context, sourceFileUri)
|
||||
file = FileUtils.getFileFromUri(context, sourceFileUri)
|
||||
val remotePath = getRemotePath(currentUser)
|
||||
val uploadSuccess: Boolean
|
||||
|
||||
initNotificationSetup()
|
||||
|
||||
file?.let { isChunkedUploading = it.length() > CHUNK_UPLOAD_THRESHOLD_SIZE }
|
||||
if (file == null) {
|
||||
uploadSuccess = false
|
||||
} else if (file.length() > CHUNK_UPLOAD_THRESHOLD_SIZE) {
|
||||
Log.d(TAG, "starting chunked upload because size is " + file.length())
|
||||
} else if (isChunkedUploading) {
|
||||
Log.d(TAG, "starting chunked upload because size is " + file!!.length())
|
||||
|
||||
initNotificationWithPercentage()
|
||||
val mimeType = context.contentResolver.getType(sourceFileUri)?.toMediaTypeOrNull()
|
||||
|
||||
uploadSuccess = ChunkedFileUploader(
|
||||
chunkedFileUploader = ChunkedFileUploader(
|
||||
okHttpClient,
|
||||
currentUser,
|
||||
roomToken,
|
||||
metaData,
|
||||
this
|
||||
).upload(
|
||||
file,
|
||||
)
|
||||
|
||||
uploadSuccess = chunkedFileUploader!!.upload(
|
||||
file!!,
|
||||
mimeType,
|
||||
remotePath
|
||||
)
|
||||
|
@ -164,6 +170,9 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
if (uploadSuccess) {
|
||||
mNotifyManager?.cancel(notificationId)
|
||||
return Result.success()
|
||||
} else if (isStopped) {
|
||||
// since work is cancelled the result would be ignored anyways
|
||||
return Result.failure()
|
||||
}
|
||||
|
||||
Log.e(TAG, "Something went wrong when trying to upload file")
|
||||
|
@ -195,6 +204,15 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
mNotifyManager!!.notify(notificationId, notification)
|
||||
}
|
||||
|
||||
override fun onStopped() {
|
||||
if (file != null && isChunkedUploading) {
|
||||
chunkedFileUploader?.abortUpload {
|
||||
mNotifyManager?.cancel(notificationId)
|
||||
}
|
||||
}
|
||||
super.onStopped()
|
||||
}
|
||||
|
||||
private fun initNotificationSetup() {
|
||||
mNotifyManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
mBuilder = NotificationCompat.Builder(
|
||||
|
@ -206,13 +224,17 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
|
||||
private fun initNotificationWithPercentage() {
|
||||
notification = mBuilder!!
|
||||
.setContentTitle(context.resources.getString(R.string.nc_upload_in_progess))
|
||||
.setContentTitle(getResourceString(context, R.string.nc_upload_in_progess))
|
||||
.setContentText(getNotificationContentText(ZERO_PERCENT))
|
||||
.setSmallIcon(R.drawable.upload_white)
|
||||
.setOngoing(true)
|
||||
.setProgress(HUNDRED_PERCENT, ZERO_PERCENT, false)
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.setContentIntent(getIntentToOpenConversation())
|
||||
.addAction(
|
||||
R.drawable.ic_cancel_white_24dp, getResourceString(context, R.string.nc_cancel),
|
||||
getCancelUploadIntent()
|
||||
)
|
||||
.build()
|
||||
|
||||
notificationId = SystemClock.uptimeMillis().toInt()
|
||||
|
@ -221,7 +243,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
|
||||
private fun getNotificationContentText(percentage: Int): String {
|
||||
return String.format(
|
||||
context.resources.getString(R.string.nc_upload_notification_text),
|
||||
getResourceString(context, R.string.nc_upload_notification_text),
|
||||
getShortenedFileName(),
|
||||
conversationName,
|
||||
percentage
|
||||
|
@ -236,6 +258,11 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
}
|
||||
}
|
||||
|
||||
private fun getCancelUploadIntent(): PendingIntent {
|
||||
return WorkManager.getInstance(applicationContext)
|
||||
.createCancelPendingIntent(id)
|
||||
}
|
||||
|
||||
private fun getIntentToOpenConversation(): PendingIntent? {
|
||||
val bundle = Bundle()
|
||||
val intent = Intent(context, MainActivity::class.java)
|
||||
|
@ -257,9 +284,9 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
}
|
||||
|
||||
private fun showFailedToUploadNotification() {
|
||||
val failureTitle = context.resources.getString(R.string.nc_upload_failed_notification_title)
|
||||
val failureTitle = getResourceString(context, R.string.nc_upload_failed_notification_title)
|
||||
val failureText = String.format(
|
||||
context.resources.getString(R.string.nc_upload_failed_notification_text),
|
||||
getResourceString(context, R.string.nc_upload_failed_notification_text),
|
||||
fileName
|
||||
)
|
||||
notification = mBuilder!!
|
||||
|
@ -275,6 +302,10 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
mNotifyManager!!.notify(SystemClock.uptimeMillis().toInt(), notification)
|
||||
}
|
||||
|
||||
private fun getResourceString(context: Context, resourceId: Int): String {
|
||||
return context.resources.getString(resourceId)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = UploadAndShareFilesWorker::class.simpleName
|
||||
private const val DEVICE_SOURCE_FILE = "DEVICE_SOURCE_FILE"
|
||||
|
@ -301,6 +332,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
REQUEST_PERMISSION
|
||||
)
|
||||
}
|
||||
|
||||
Build.VERSION.SDK_INT > Build.VERSION_CODES.Q -> {
|
||||
activity.requestPermissions(
|
||||
arrayOf(
|
||||
|
@ -309,6 +341,7 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||
REQUEST_PERMISSION
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
activity.requestPermissions(
|
||||
arrayOf(
|
||||
|
|
|
@ -76,6 +76,8 @@ class ChunkedFileUploader(
|
|||
|
||||
private var okHttpClientNoRedirects: OkHttpClient? = null
|
||||
private var remoteChunkUrl: String
|
||||
private var uploadFolderUri: String = ""
|
||||
private var isUploadAborted = false
|
||||
|
||||
init {
|
||||
initHttpClient(okHttpClient, currentUser)
|
||||
|
@ -85,7 +87,7 @@ class ChunkedFileUploader(
|
|||
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||
fun upload(localFile: File, mimeType: MediaType?, targetPath: String): Boolean {
|
||||
try {
|
||||
val uploadFolderUri: String = remoteChunkUrl + "/" + FileUtils.md5Sum(localFile)
|
||||
uploadFolderUri = remoteChunkUrl + "/" + FileUtils.md5Sum(localFile)
|
||||
val davResource = DavResource(
|
||||
okHttpClientNoRedirects!!,
|
||||
uploadFolderUri.toHttpUrlOrNull()!!
|
||||
|
@ -100,6 +102,7 @@ class ChunkedFileUploader(
|
|||
Log.d(TAG, "missingChunks: " + missingChunks.size)
|
||||
|
||||
for (missingChunk in missingChunks) {
|
||||
if (isUploadAborted) return false
|
||||
uploadChunk(localFile, uploadFolderUri, mimeType, missingChunk, missingChunk.length())
|
||||
}
|
||||
|
||||
|
@ -327,6 +330,19 @@ class ChunkedFileUploader(
|
|||
}
|
||||
}
|
||||
|
||||
fun abortUpload(onSuccess: () -> Unit) {
|
||||
isUploadAborted = true
|
||||
DavResource(
|
||||
okHttpClientNoRedirects!!,
|
||||
uploadFolderUri.toHttpUrlOrNull()!!
|
||||
).delete { response: Response ->
|
||||
when {
|
||||
response.isSuccessful -> onSuccess()
|
||||
else -> isUploadAborted = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getModelFromResponse(response: at.bitfire.dav4jvm.Response, remotePath: String): RemoteFileBrowserItem {
|
||||
val remoteFileBrowserItem = RemoteFileBrowserItem()
|
||||
remoteFileBrowserItem.path = Uri.decode(remotePath)
|
||||
|
@ -353,30 +369,39 @@ class ChunkedFileUploader(
|
|||
is OCId -> {
|
||||
remoteFileBrowserItem.remoteId = property.ocId
|
||||
}
|
||||
|
||||
is ResourceType -> {
|
||||
remoteFileBrowserItem.isFile = !property.types.contains(ResourceType.COLLECTION)
|
||||
}
|
||||
|
||||
is GetLastModified -> {
|
||||
remoteFileBrowserItem.modifiedTimestamp = property.lastModified
|
||||
}
|
||||
|
||||
is GetContentType -> {
|
||||
remoteFileBrowserItem.mimeType = property.type
|
||||
}
|
||||
|
||||
is OCSize -> {
|
||||
remoteFileBrowserItem.size = property.ocSize
|
||||
}
|
||||
|
||||
is NCPreview -> {
|
||||
remoteFileBrowserItem.hasPreview = property.isNcPreview
|
||||
}
|
||||
|
||||
is OCFavorite -> {
|
||||
remoteFileBrowserItem.isFavorite = property.isOcFavorite
|
||||
}
|
||||
|
||||
is DisplayName -> {
|
||||
remoteFileBrowserItem.displayName = property.displayName
|
||||
}
|
||||
|
||||
is NCEncrypted -> {
|
||||
remoteFileBrowserItem.isEncrypted = property.isNcEncrypted
|
||||
}
|
||||
|
||||
is NCPermission -> {
|
||||
remoteFileBrowserItem.permissions = property.ncPermission
|
||||
}
|
||||
|
|
5
app/src/main/res/drawable/ic_cancel_white_24dp.xml
Normal file
5
app/src/main/res/drawable/ic_cancel_white_24dp.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>
|
||||
</vector>
|
Loading…
Reference in a new issue