Bug fix redraft and refactor
This commit is contained in:
parent
91819dd4db
commit
069c11478a
|
@ -64,6 +64,12 @@ data class PhotoData(
|
||||||
|
|
||||||
class PostCreationActivity : BaseThemedWithoutBarActivity() {
|
class PostCreationActivity : BaseThemedWithoutBarActivity() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal const val PICTURE_DESCRIPTION = "picture_description"
|
||||||
|
internal const val TEMP_FILES = "temp_files"
|
||||||
|
internal const val POST_REDRAFT = "post_redraft"
|
||||||
|
}
|
||||||
|
|
||||||
private var user: UserDatabaseEntity? = null
|
private var user: UserDatabaseEntity? = null
|
||||||
private lateinit var instance: InstanceDatabaseEntity
|
private lateinit var instance: InstanceDatabaseEntity
|
||||||
|
|
||||||
|
@ -105,9 +111,6 @@ class PostCreationActivity : BaseThemedWithoutBarActivity() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get initial text value from model (for template)
|
|
||||||
binding.newPostDescriptionInputField.setText(model.uiState.value.newPostDescriptionText)
|
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
model.uiState.collect { uiState ->
|
model.uiState.collect { uiState ->
|
||||||
|
@ -167,9 +170,13 @@ class PostCreationActivity : BaseThemedWithoutBarActivity() {
|
||||||
model.newPostDescriptionChanged(binding.newPostDescriptionInputField.text)
|
model.newPostDescriptionChanged(binding.newPostDescriptionInputField.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch existing description passed through putExtra (if any)
|
val existingDescription: String? = intent.getStringExtra(PICTURE_DESCRIPTION)
|
||||||
val existingDescription = intent.getStringExtra(PhotoEditActivity.PICTURE_DESCRIPTION)
|
|
||||||
binding.newPostDescriptionInputField.setText(existingDescription)
|
binding.newPostDescriptionInputField.setText(
|
||||||
|
// Set description from redraft if any, otherwise from the template
|
||||||
|
existingDescription ?: model.uiState.value.newPostDescriptionText
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
binding.postTextInputLayout.counterMaxLength = instance.maxStatusChars
|
binding.postTextInputLayout.counterMaxLength = instance.maxStatusChars
|
||||||
|
|
||||||
|
@ -219,15 +226,15 @@ class PostCreationActivity : BaseThemedWithoutBarActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up temporary files, if any
|
// Clean up temporary files, if any
|
||||||
val tempFiles = intent.getStringArrayExtra(PhotoEditActivity.TEMP_FILES)
|
val tempFiles = intent.getStringArrayExtra(TEMP_FILES)
|
||||||
tempFiles?.asList()?.map { uri -> uri.toString() }?.forEach {
|
tempFiles?.asList()?.forEach {
|
||||||
val file = File(binding.root.context.cacheDir, it)
|
val file = File(binding.root.context.cacheDir, it)
|
||||||
file.delete()
|
model.trackTempFile(file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
val redraft = intent.getBooleanExtra(PhotoEditActivity.POST_REDRAFT, false)
|
val redraft = intent.getBooleanExtra(POST_REDRAFT, false)
|
||||||
if (redraft) {
|
if (redraft) {
|
||||||
val builder = AlertDialog.Builder(binding.root.context)
|
val builder = AlertDialog.Builder(binding.root.context)
|
||||||
builder.apply {
|
builder.apply {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.pixeldroid.app.postCreation
|
package org.pixeldroid.app.postCreation
|
||||||
|
|
||||||
import android.R.attr.orientation
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
|
|
@ -80,9 +80,6 @@ class PhotoEditActivity : BaseThemedWithBarActivity() {
|
||||||
companion object{
|
companion object{
|
||||||
internal const val PICTURE_URI = "picture_uri"
|
internal const val PICTURE_URI = "picture_uri"
|
||||||
internal const val PICTURE_POSITION = "picture_position"
|
internal const val PICTURE_POSITION = "picture_position"
|
||||||
internal const val PICTURE_DESCRIPTION = "picture_description"
|
|
||||||
internal const val TEMP_FILES = "temp_files"
|
|
||||||
internal const val POST_REDRAFT = "post_redraft"
|
|
||||||
|
|
||||||
private var executor: ExecutorService = newSingleThreadExecutor()
|
private var executor: ExecutorService = newSingleThreadExecutor()
|
||||||
private var future: Future<*>? = null
|
private var future: Future<*>? = null
|
||||||
|
|
|
@ -473,125 +473,129 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
||||||
setPositiveButton(android.R.string.ok) { _, _ ->
|
setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val user = db.userDao().getActiveUser()!!
|
try {
|
||||||
status?.id?.let { id ->
|
// Create new post creation activity
|
||||||
try {
|
val intent =
|
||||||
// Create new post creation activity
|
Intent(context, PostCreationActivity::class.java)
|
||||||
val intent = Intent(context, PostCreationActivity::class.java)
|
|
||||||
|
|
||||||
// Get descriptions and images from original post
|
// Get descriptions and images from original post
|
||||||
val postDescription = status?.content?: ""
|
val postDescription = status?.content ?: ""
|
||||||
val postAttachments = status?.media_attachments!! // Catch possible exception from !! (?)
|
val postAttachments =
|
||||||
val imageUris: MutableList<Uri> = mutableListOf()
|
status?.media_attachments!! // Catch possible exception from !! (?)
|
||||||
val imageNames: MutableList<String> = mutableListOf()
|
val imageUris: MutableList<Uri> = mutableListOf()
|
||||||
val imageDescriptions: MutableList<String> = mutableListOf()
|
val imageNames: MutableList<String> = mutableListOf()
|
||||||
|
val imageDescriptions: MutableList<String> =
|
||||||
|
mutableListOf()
|
||||||
|
|
||||||
for (currentAttachment in postAttachments) {
|
for (currentAttachment in postAttachments) {
|
||||||
val imageUri = currentAttachment.url ?: ""
|
val imageUri = currentAttachment.url ?: ""
|
||||||
val imageName =
|
val imageName =
|
||||||
Uri.parse(imageUri).lastPathSegment.toString()
|
Uri.parse(imageUri).lastPathSegment.toString()
|
||||||
val imageDescription =
|
val imageDescription =
|
||||||
currentAttachment.description ?: ""
|
currentAttachment.description ?: ""
|
||||||
val downloadedFile =
|
val downloadedFile =
|
||||||
File(context.cacheDir, imageName)
|
File(context.cacheDir, imageName)
|
||||||
val downloadedUri = Uri.fromFile(downloadedFile)
|
val downloadedUri = Uri.fromFile(downloadedFile)
|
||||||
|
|
||||||
imageUris.add(downloadedUri)
|
imageUris.add(downloadedUri)
|
||||||
imageNames.add(imageName)
|
imageNames.add(imageName)
|
||||||
imageDescriptions.add(imageDescription)
|
imageDescriptions.add(imageDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
val counter = AtomicInteger(0)
|
val counter = AtomicInteger(0)
|
||||||
|
|
||||||
// Define callback function for after downloading the images
|
// Define callback function for after downloading the images
|
||||||
fun continuation() {
|
fun continuation() {
|
||||||
// Wait for all outstanding downloads to finish
|
// Wait for all outstanding downloads to finish
|
||||||
if (counter.incrementAndGet() == imageUris.size) {
|
if (counter.incrementAndGet() == imageUris.size) {
|
||||||
if (allFilesExist(imageNames)) {
|
if (allFilesExist(imageNames)) {
|
||||||
val counterInt = counter.get()
|
val counterInt = counter.get()
|
||||||
if (counterInt < 2) {
|
Toast.makeText(
|
||||||
Toast.makeText(
|
binding.root.context,
|
||||||
binding.root.context,
|
binding.root.context.resources.getQuantityString(
|
||||||
binding.root.context.getString(R.string.item_load_success, counterInt),
|
R.plurals.items_load_success,
|
||||||
Toast.LENGTH_SHORT
|
counterInt,
|
||||||
).show()
|
counterInt
|
||||||
} else {
|
),
|
||||||
Toast.makeText(
|
Toast.LENGTH_SHORT
|
||||||
binding.root.context,
|
).show()
|
||||||
binding.root.context.getString(R.string.items_load_success, counterInt),
|
// Pass downloaded images to new post creation activity
|
||||||
Toast.LENGTH_SHORT
|
intent.apply {
|
||||||
).show()
|
assert(imageUris.size == imageDescriptions.size)
|
||||||
}
|
|
||||||
|
|
||||||
// Pass downloaded images to new post creation activity
|
for (i in 0 until imageUris.size) {
|
||||||
intent.apply {
|
val imageUri = imageUris[i]
|
||||||
assert(imageUris.size == imageDescriptions.size)
|
val imageDescription =
|
||||||
|
fromHtml(imageDescriptions[i]).toString()
|
||||||
for (i in 0 until imageUris.size) {
|
val imageItem = ClipData.Item(
|
||||||
val imageUri = imageUris[i]
|
imageDescription,
|
||||||
val imageDescription =
|
null,
|
||||||
fromHtml(imageDescriptions[i]).toString()
|
imageUri
|
||||||
val imageItem = ClipData.Item(
|
)
|
||||||
imageDescription,
|
if (clipData == null) {
|
||||||
null,
|
clipData = ClipData(
|
||||||
imageUri
|
"",
|
||||||
|
emptyArray(),
|
||||||
|
imageItem
|
||||||
)
|
)
|
||||||
if (clipData == null) {
|
} else {
|
||||||
clipData = ClipData(
|
clipData!!.addItem(imageItem)
|
||||||
"",
|
|
||||||
emptyArray(),
|
|
||||||
imageItem
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
clipData!!.addItem(imageItem)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
|
|
||||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass post description of existing post to new post creation activity
|
addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
|
||||||
if (postDescription != null) {
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
intent.putExtra(
|
|
||||||
PhotoEditActivity.PICTURE_DESCRIPTION,
|
|
||||||
fromHtml(postDescription!!).toString()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (imageUris.isNotEmpty()) {
|
|
||||||
intent.putExtra(
|
|
||||||
PhotoEditActivity.TEMP_FILES,
|
|
||||||
imageUris.map{ uri -> uri.toString() }.toTypedArray()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
intent.putExtra(PhotoEditActivity.POST_REDRAFT, true)
|
|
||||||
|
|
||||||
// Launch post creation activity
|
|
||||||
binding.root.context.startActivity(intent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pass post description of existing post to new post creation activity
|
||||||
|
intent.putExtra(
|
||||||
|
PostCreationActivity.PICTURE_DESCRIPTION,
|
||||||
|
fromHtml(postDescription).toString()
|
||||||
|
)
|
||||||
|
if (imageNames.isNotEmpty()) {
|
||||||
|
intent.putExtra(
|
||||||
|
PostCreationActivity.TEMP_FILES,
|
||||||
|
imageNames.toTypedArray()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
intent.putExtra(
|
||||||
|
PostCreationActivity.POST_REDRAFT,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
// Launch post creation activity
|
||||||
|
binding.root.context.startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!allFilesExist(imageNames)) {
|
if (!allFilesExist(imageNames)) {
|
||||||
// Track download progress
|
// Track download progress
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
binding.root.context,
|
binding.root.context,
|
||||||
binding.root.context.getString(R.string.image_download_downloading),
|
binding.root.context.getString(R.string.image_download_downloading),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through all pictures of the original post
|
// Iterate through all pictures of the original post
|
||||||
for (currentAttachment in postAttachments) {
|
for (currentAttachment in postAttachments) {
|
||||||
val imageUri = currentAttachment.url?: ""
|
val imageUri = currentAttachment.url ?: ""
|
||||||
val imageName = Uri.parse(imageUri).lastPathSegment.toString()
|
val imageName =
|
||||||
val downloadedFile = File(context.cacheDir, imageName)
|
Uri.parse(imageUri).lastPathSegment.toString()
|
||||||
val downloadRequest: Request = Request.Builder().url(imageUri).build()
|
val downloadedFile =
|
||||||
|
File(context.cacheDir, imageName)
|
||||||
|
val downloadRequest: Request =
|
||||||
|
Request.Builder().url(imageUri).build()
|
||||||
|
|
||||||
// Check whether image is in cache directory already (maybe rather do so using Glide in the future?)
|
// Check whether image is in cache directory already (maybe rather do so using Glide in the future?)
|
||||||
if (!downloadedFile.exists()) {
|
if (!downloadedFile.exists()) {
|
||||||
OkHttpClient().newCall(downloadRequest).enqueue(object : Callback {
|
OkHttpClient().newCall(downloadRequest)
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
.enqueue(object : Callback {
|
||||||
|
override fun onFailure(
|
||||||
|
call: Call,
|
||||||
|
e: IOException
|
||||||
|
) {
|
||||||
Looper.prepare()
|
Looper.prepare()
|
||||||
downloadedFile.delete()
|
downloadedFile.delete()
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
|
@ -602,7 +606,10 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
override fun onResponse(call: Call, response: Response) {
|
override fun onResponse(
|
||||||
|
call: Call,
|
||||||
|
response: Response
|
||||||
|
) {
|
||||||
val sink: BufferedSink =
|
val sink: BufferedSink =
|
||||||
downloadedFile.sink().buffer()
|
downloadedFile.sink().buffer()
|
||||||
sink.writeAll(response.body!!.source())
|
sink.writeAll(response.body!!.source())
|
||||||
|
@ -611,28 +618,34 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
||||||
continuation()
|
continuation()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
continuation()
|
continuation()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (exception: HttpException) {
|
|
||||||
Toast.makeText(
|
|
||||||
binding.root.context,
|
|
||||||
binding.root.context.getString(R.string.redraft_post_failed_error, exception.code()),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
} catch (exception: IOException) {
|
|
||||||
Toast.makeText(
|
|
||||||
binding.root.context,
|
|
||||||
binding.root.context.getString(R.string.redraft_post_failed_io_except),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete original post
|
} catch (exception: HttpException) {
|
||||||
deletePost(apiHolder.api ?: apiHolder.setToCurrentUser(), db)
|
Toast.makeText(
|
||||||
|
binding.root.context,
|
||||||
|
binding.root.context.getString(
|
||||||
|
R.string.redraft_post_failed_error,
|
||||||
|
exception.code()
|
||||||
|
),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
} catch (exception: IOException) {
|
||||||
|
Toast.makeText(
|
||||||
|
binding.root.context,
|
||||||
|
binding.root.context.getString(R.string.redraft_post_failed_io_except),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete original post
|
||||||
|
deletePost(
|
||||||
|
apiHolder.api ?: apiHolder.setToCurrentUser(),
|
||||||
|
db
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setNegativeButton(android.R.string.cancel) { _, _ -> }
|
setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||||
|
|
|
@ -148,8 +148,10 @@ For more info about Pixelfed, you can check here: https://pixelfed.org"</string>
|
||||||
<string name="image_download_failed">Download has failed, please try again</string>
|
<string name="image_download_failed">Download has failed, please try again</string>
|
||||||
<string name="image_download_downloading">Downloading…</string>
|
<string name="image_download_downloading">Downloading…</string>
|
||||||
<string name="image_download_success">Image downloaded successfully</string>
|
<string name="image_download_success">Image downloaded successfully</string>
|
||||||
<string name="item_load_success">%1$d item loaded successfully</string>
|
<plurals name="items_load_success">
|
||||||
<string name="items_load_success">%1$d items loaded successfully</string>
|
<item quantity="one">%d item loaded successfully</item>
|
||||||
|
<item quantity="other">%d items loaded successfully</item>
|
||||||
|
</plurals>
|
||||||
<!-- Post attributes -->
|
<!-- Post attributes -->
|
||||||
<string name="no_description">No description</string>
|
<string name="no_description">No description</string>
|
||||||
<plurals name="likes">
|
<plurals name="likes">
|
||||||
|
|
Loading…
Reference in New Issue