From 71714a5f3c7308de86d4d3985cbaea170244257c Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Sun, 7 Feb 2021 22:55:34 +0100 Subject: [PATCH] Check if size of image isn't too big, and show dialog if it is --- .../postCreation/PostCreationActivity.kt | 157 ++++++++++-------- .../res/layout/activity_post_creation.xml | 27 ++- app/src/main/res/values/strings.xml | 15 +- 3 files changed, 119 insertions(+), 80 deletions(-) diff --git a/app/src/main/java/com/h/pixeldroid/postCreation/PostCreationActivity.kt b/app/src/main/java/com/h/pixeldroid/postCreation/PostCreationActivity.kt index d0d01f9c..26267464 100644 --- a/app/src/main/java/com/h/pixeldroid/postCreation/PostCreationActivity.kt +++ b/app/src/main/java/com/h/pixeldroid/postCreation/PostCreationActivity.kt @@ -42,6 +42,7 @@ import java.io.OutputStream import java.text.SimpleDateFormat import java.util.* import kotlin.collections.ArrayList +import kotlin.math.ceil import kotlin.properties.Delegates private const val TAG = "Post Creation Activity" @@ -49,9 +50,10 @@ private const val MORE_PICTURES_REQUEST_CODE = 0xffff data class PhotoData( var imageUri: Uri, + var size: Long, var uploadId: String? = null, var progress: Int? = null, - var imageDescription: String? = null + var imageDescription: String? = null, ) class PostCreationActivity : BaseActivity() { @@ -59,10 +61,9 @@ class PostCreationActivity : BaseActivity() { private lateinit var accessToken: String private lateinit var pixelfedAPI: PixelfedAPI - private var albumLimit by Delegates.notNull() - private var positionResult = 0 private var user: UserDatabaseEntity? = null + private lateinit var instance: InstanceDatabaseEntity private val photoData: ArrayList = ArrayList() @@ -75,7 +76,7 @@ class PostCreationActivity : BaseActivity() { user = db.userDao().getActiveUser() - val instance: InstanceDatabaseEntity = user?.run { + instance = user?.run { db.instanceDao().getAll().first { instanceDatabaseEntity -> instanceDatabaseEntity.uri.contains(instance_uri) } @@ -83,8 +84,6 @@ class PostCreationActivity : BaseActivity() { binding.postTextInputLayout.counterMaxLength = instance.maxStatusChars - albumLimit = instance.albumLimit - // get image URIs intent.clipData?.let { addPossibleImages(it) } @@ -96,13 +95,13 @@ class PostCreationActivity : BaseActivity() { carousel.layoutCarouselCallback = { if(it){ // Became a carousel - binding.toolbar3.visibility = VISIBLE + binding.toolbarPostCreation.visibility = VISIBLE } else { // Became a grid - binding.toolbar3.visibility = INVISIBLE + binding.toolbarPostCreation.visibility = INVISIBLE } } - carousel.maxEntries = albumLimit + carousel.maxEntries = instance.albumLimit carousel.addPhotoButtonCallback = { addPhoto(applicationContext) } @@ -158,20 +157,51 @@ class PostCreationActivity : BaseActivity() { */ private fun addPossibleImages(clipData: ClipData){ var count = clipData.itemCount - if(count + photoData.size > albumLimit){ + if(count + photoData.size > instance.albumLimit){ AlertDialog.Builder(this).apply { - setMessage(getString(R.string.total_exceeds_album_limit).format(albumLimit)) + setMessage(getString(R.string.total_exceeds_album_limit).format(instance.albumLimit)) setNegativeButton(android.R.string.ok) { _, _ -> } }.show() - count = count.coerceAtMost(albumLimit - photoData.size) + count = count.coerceAtMost(instance.albumLimit - photoData.size) } - if (count + photoData.size >= albumLimit) { + if (count + photoData.size >= instance.albumLimit) { // Disable buttons to add more images binding.addPhotoButton.isEnabled = false } for (i in 0 until count) { clipData.getItemAt(i).uri.let { - photoData.add(PhotoData(it)) + val size: Long = + if (it.toString().startsWith("content")) { + contentResolver.query(it, null, null, null, null) + ?.use { cursor -> + /* Get the column indexes of the data in the Cursor, + * move to the first row in the Cursor, get the data, + * and display it. + */ + val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE) + cursor.moveToFirst() + cursor.getLong(sizeIndex) + } ?: 0 + } else { + it.toFile().length() + } + val sizeInkBytes = ceil(size.toDouble() / 1000).toLong() + if(sizeInkBytes > instance.maxPhotoSize || sizeInkBytes > instance.maxVideoSize){ + val maxSize = when { + instance.maxPhotoSize != instance.maxVideoSize -> { + val type = contentResolver.getType(it) + if(type?.startsWith("video/") == true){ + instance.maxVideoSize + } else instance.maxPhotoSize + } + else -> instance.maxPhotoSize + } + AlertDialog.Builder(this).apply { + setMessage(getString(R.string.size_exceeds_instance_limit).format(photoData.size + 1, sizeInkBytes, maxSize)) + setNegativeButton(android.R.string.ok) { _, _ -> } + }.show() + } + photoData.add(PhotoData(imageUri = it, size = size)) } } } @@ -196,21 +226,21 @@ class PostCreationActivity : BaseActivity() { if(path.startsWith("file")) { MediaScannerConnection.scanFile( - this, - arrayOf(path.toUri().toFile().absolutePath), - null + this, + arrayOf(path.toUri().toFile().absolutePath), + null ) { path, uri -> if (uri == null) { Log.e( - "NEW IMAGE SCAN FAILED", - "Tried to scan $path, but it failed" + "NEW IMAGE SCAN FAILED", + "Tried to scan $path, but it failed" ) } } } Snackbar.make( - button, getString(R.string.save_image_success), - Snackbar.LENGTH_LONG + button, getString(R.string.save_image_success), + Snackbar.LENGTH_LONG ).show() } @@ -223,8 +253,8 @@ class PostCreationActivity : BaseActivity() { contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name) contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/png") contentValues.put( - MediaStore.MediaColumns.RELATIVE_PATH, - Environment.DIRECTORY_PICTURES + MediaStore.MediaColumns.RELATIVE_PATH, + Environment.DIRECTORY_PICTURES ) val imageUri: Uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)!! @@ -271,23 +301,7 @@ class PostCreationActivity : BaseActivity() { val imageUri = data.imageUri val imageInputStream = contentResolver.openInputStream(imageUri)!! - val size = - if (imageUri.toString().startsWith("content")) { - contentResolver.query(imageUri, null, null, null, null) - ?.use { cursor -> - /* Get the column indexes of the data in the Cursor, - * move to the first row in the Cursor, get the data, - * and display it. - */ - val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE) - cursor.moveToFirst() - cursor.getLong(sizeIndex) - } ?: 0 - } else { - imageUri.toFile().length() - } - - val imagePart = ProgressRequestBody(imageInputStream, size) + val imagePart = ProgressRequestBody(imageInputStream, data.size) val requestBody = MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", System.currentTimeMillis().toString(), imagePart) @@ -312,26 +326,33 @@ class PostCreationActivity : BaseActivity() { .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( - { attachment: Attachment -> - data.progress = 0 - data.uploadId = attachment.id!! - }, - { e -> - binding.uploadError.visibility = View.VISIBLE - e.printStackTrace() - postSub?.dispose() - sub.dispose() - }, - { - data.progress = 100 - if(photoData.all{it.progress == 100 && it.uploadId != null}){ - binding.uploadProgressBar.visibility = View.GONE - binding.uploadCompletedTextview.visibility = View.VISIBLE - post() + { attachment: Attachment -> + data.progress = 0 + data.uploadId = attachment.id!! + }, + { e: Throwable -> + binding.uploadError.visibility = View.VISIBLE + if(e is HttpException){ + binding.uploadErrorTextExplanation.text = + getString(R.string.upload_error).format(e.code()) + binding.uploadErrorTextExplanation.visibility= VISIBLE + } else { + binding.uploadErrorTextExplanation.visibility= View.GONE + } + e.printStackTrace() + postSub?.dispose() + sub.dispose() + }, + { + data.progress = 100 + if (photoData.all { it.progress == 100 && it.uploadId != null }) { + binding.uploadProgressBar.visibility = View.GONE + binding.uploadCompletedTextview.visibility = View.VISIBLE + post() + } + postSub?.dispose() + sub.dispose() } - postSub?.dispose() - sub.dispose() - } ) } } @@ -342,23 +363,23 @@ class PostCreationActivity : BaseActivity() { lifecycleScope.launchWhenCreated { try { pixelfedAPI.postStatus( - authorization = "Bearer $accessToken", - statusText = description, - media_ids = photoData.mapNotNull { it.uploadId }.toList() + authorization = "Bearer $accessToken", + statusText = description, + media_ids = photoData.mapNotNull { it.uploadId }.toList() ) - Toast.makeText(applicationContext,getString(R.string.upload_post_success), - Toast.LENGTH_SHORT).show() + Toast.makeText(applicationContext, getString(R.string.upload_post_success), + Toast.LENGTH_SHORT).show() val intent = Intent(this@PostCreationActivity, MainActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK startActivity(intent) } catch (exception: IOException) { - Toast.makeText(applicationContext,getString(R.string.upload_post_error), - Toast.LENGTH_SHORT).show() + Toast.makeText(applicationContext, getString(R.string.upload_post_error), + Toast.LENGTH_SHORT).show() Log.e(TAG, exception.toString()) enableButton(true) } catch (exception: HttpException) { - Toast.makeText(applicationContext,getString(R.string.upload_post_failed), - Toast.LENGTH_SHORT).show() + Toast.makeText(applicationContext, getString(R.string.upload_post_failed), + Toast.LENGTH_SHORT).show() Log.e(TAG, exception.response().toString() + exception.message().toString()) enableButton(true) } diff --git a/app/src/main/res/layout/activity_post_creation.xml b/app/src/main/res/layout/activity_post_creation.xml index 1aac6446..cdbb9ecc 100644 --- a/app/src/main/res/layout/activity_post_creation.xml +++ b/app/src/main/res/layout/activity_post_creation.xml @@ -8,14 +8,15 @@ + app:layout_constraintTop_toTopOf="parent" + tools:visibility="visible"> + +