PixelDroid-App-Android/app/src/main/java/com/h/pixeldroid/PostCreationActivity.kt

161 lines
6.1 KiB
Kotlin
Raw Normal View History

Feature/post creation (#83) * added perm and features for cameraS, gps and external storage * added camera activity accessible from main activity * added button to redirect to camera activity * implementing callback flow to use camera * working camera * added texture view for camera display * added camera activity * implemented texture listener * camera not working, flow done, no feedback implemented * camera working * refactored code, still an activity * added private to internal function, better error function handling * deleted camera activity * added camera fragment * added camera fragment * refactored camera as fragment * necessary dependencies for fragment testing * initial camera fragment test * corrected access to activity form fragment * Added state changes and termination * added lines to test, to test coverage * Removed unsupported state STARTED state transition * Added basic tests to test code coverage * use layout for tests, to trigger permissions requirements * grant camera permission to app in camera test * replaced null handlers by proper function getter * changed layout, added takePictureButton * using expresso to get code coverage on camea * take picture flow not finished * dummy change to camera test to perform new build * added connection flow before test to reach main activity * can take a picture and put it to ImageView * replaced button text with images * smaller buttons * test camera fragment buttons * added orientation handler * changed icon to make travis happy * test new espresso config for travis * removed useless rule * deleted useless val * added layout ID's * moved swipes from Before to Tests, and thread sleep * stoped swiping, now tests from fragment directly * start post creation flow * use Uri when taking photo, can now go back from picture preview * adjusted test and flow idea * tests on displayed UI elements for the post creation fragment * refactor camera fragment into transition new post fragemnt * finished first phase: get a picture Uri * fixed lint error found by travis CI * added global timeout to test * test the new way of test * refactor new way of testing * added in-app camera view and linked everything to the final flow + started API to post * strugling on the upload media part * upload image on server implemented * post upload implemented * added API call to get max_toot_chars and correct def of a post description * fixed some tests * fix tests: clicking on tabs make the app crash because of the camera fragment * comment problematic chunk of code while samuel tries to fix it * switch minimumsdk to api 24 * Revert "switch minimumsdk to api 24" This reverts commit 24ce46dd82038b59732fd958e5e071ded39cd549. * deactivited live camera for API 23 * tests for post creation fragment UI elements * remove worthless UI testing and add gallery intent test * removed camera intent for now * some refactor * lint error and more refactor * more refactor on merge from master * refactor and test for PostCreationActivity * Revert "refactor and test for PostCreationActivity" This reverts commit a0c146bcc545cdc3792df4806e6b0c908bd18747. * Revert "Revert "refactor and test for PostCreationActivity"" This reverts commit 147a9ed80d5f9c9e3c38b5a977786bfb39eeb1b6. * permissions correction for test * updtated test * fix a test and refactor * relink correct fragment * save picture locally * test post button * requested changes * fixed required changes * Revert "fixed required changes" This reverts commit 405a9d4d1af05353e30028e60041cc1c97569c1b. * redo change request * added /media api response to mockserver Co-authored-by: Andrea Clement <samuel.dietz@epfl.ch>
2020-04-24 12:44:12 +02:00
package com.h.pixeldroid
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.net.toUri
import com.google.android.material.textfield.TextInputEditText
import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.objects.Attachment
import com.h.pixeldroid.objects.Status
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
class PostCreationActivity : AppCompatActivity() {
private val TAG = "Post Creation Activity"
private lateinit var accessToken: String
private lateinit var pixelfedAPI: PixelfedAPI
private lateinit var preferences: SharedPreferences
private lateinit var pictureFrame: ImageView
private lateinit var image: File
private var description: String = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_post_creation)
val imageUri: Uri = intent.getParcelableExtra<Uri>("picture_uri")!!
saveImage(imageUri)
pictureFrame = findViewById<ImageView>(R.id.post_creation_picture_frame)
pictureFrame.setImageURI(image.toUri())
preferences = getSharedPreferences(
"${BuildConfig.APPLICATION_ID}.pref", Context.MODE_PRIVATE
)
pixelfedAPI = PixelfedAPI.create("${preferences.getString("domain", "")}")
accessToken = preferences.getString("accessToken", "")!!
// check if the picture is alright
// TODO
// edit the picture
// TODO
// get the description and send the post to PixelFed
findViewById<Button>(R.id.post_creation_send_button).setOnClickListener {
if (setDescription()) upload()
}
}
private fun saveImage(imageUri: Uri) {
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val fileName = "PixelDroid_$timeStamp.png"
try {
val stream = applicationContext.contentResolver
.openAssetFileDescriptor(imageUri, "r")!!
.createInputStream()
val bm = BitmapFactory.decodeStream(stream)
val bos = ByteArrayOutputStream()
bm.compress(Bitmap.CompressFormat.PNG, 0, bos)
image = File(
applicationContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES),
fileName)
val fos = FileOutputStream(image)
fos.write(bos.toByteArray())
fos.flush()
fos.close()
} catch (error: IOException) {
error.printStackTrace()
throw error
}
}
private fun setDescription(): Boolean {
val textField = findViewById<TextInputEditText>(R.id.new_post_description_input_field)
val content = textField.text.toString()
val maxLength = preferences.getInt("max_toot_chars", 500)
if (content.length > maxLength) {
// error, too much characters
textField.error = "Description must contain $maxLength characters at most."
return false
}
// store the description
description = content
return true
}
private fun upload() {
val rBody: RequestBody = image.asRequestBody("image/*".toMediaTypeOrNull())
val part = MultipartBody.Part.createFormData("file", image.name, rBody)
pixelfedAPI.mediaUpload("Bearer $accessToken", part).enqueue(object:
Callback<Attachment> {
override fun onFailure(call: Call<Attachment>, t: Throwable) {
Log.e(TAG, t.toString() + call.request())
Toast.makeText(applicationContext,"Picture upload error!",Toast.LENGTH_SHORT).show()
}
override fun onResponse(call: Call<Attachment>, response: Response<Attachment>) {
if (response.code() == 200) {
val body = response.body()!!
if (body.type.name == "image") {
post(body.id)
} else
Toast.makeText(applicationContext, "Upload error: wrong picture format.", Toast.LENGTH_SHORT).show()
} else {
Log.e(TAG, "Server responded: $response" + call.request() + call.request().body)
Toast.makeText(applicationContext,"Upload error: bad request format",Toast.LENGTH_SHORT).show()
}
}
})
}
private fun post(id: String) {
if (id.isEmpty()) return
pixelfedAPI.postStatus(
authorization = "Bearer $accessToken",
statusText = description,
media_ids = listOf(id)
).enqueue(object: Callback<Status> {
override fun onFailure(call: Call<Status>, t: Throwable) {
Toast.makeText(applicationContext,"Post upload failed",Toast.LENGTH_SHORT).show()
Log.e(TAG, t.message + call.request())
}
override fun onResponse(call: Call<Status>, response: Response<Status>) {
if (response.code() == 200) {
Toast.makeText(applicationContext,"Post upload success",Toast.LENGTH_SHORT).show()
startActivity(Intent(applicationContext, MainActivity::class.java))
} else {
Toast.makeText(applicationContext,"Post upload failed : not 200",Toast.LENGTH_SHORT).show()
Log.e(TAG, call.request().toString() + response.raw().toString())
}
}
})
}
}