e-ntfy-android/app/src/main/java/io/heckel/ntfy/ui/ShareActivity.kt

194 lines
6.6 KiB
Kotlin
Raw Normal View History

2022-02-11 16:46:55 +01:00
package io.heckel.ntfy.ui
import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.os.Parcelable
import android.text.Editable
import android.text.TextWatcher
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
2022-02-11 21:55:08 +01:00
import androidx.lifecycle.lifecycleScope
2022-02-11 16:46:55 +01:00
import io.heckel.ntfy.R
import io.heckel.ntfy.app.Application
import io.heckel.ntfy.msg.ApiService
2022-02-11 21:55:08 +01:00
import io.heckel.ntfy.util.ContentUriRequestBody
2022-02-11 16:46:55 +01:00
import io.heckel.ntfy.util.Log
2022-02-11 21:55:08 +01:00
import io.heckel.ntfy.util.supportedImage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
2022-02-11 16:46:55 +01:00
class ShareActivity : AppCompatActivity() {
private val repository by lazy { (application as Application).repository }
private val api = ApiService()
2022-02-11 21:55:08 +01:00
// File to share
private var fileUri: Uri? = null
2022-02-11 16:46:55 +01:00
// UI elements
private lateinit var menu: Menu
private lateinit var sendItem: MenuItem
private lateinit var contentImage: ImageView
private lateinit var contentText: TextView
private lateinit var topicText: TextView
private lateinit var progress: ProgressBar
2022-02-11 21:55:08 +01:00
private lateinit var errorText: TextView
private lateinit var errorImage: ImageView
2022-02-11 16:46:55 +01:00
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_share)
Log.init(this) // Init logs in all entry points
Log.d(TAG, "Create $this")
// Action bar
title = getString(R.string.share_title)
// Show 'Back' button
supportActionBar?.setDisplayHomeAsUpEnabled(true)
// UI elements
contentText = findViewById(R.id.share_content_text)
contentImage = findViewById(R.id.share_content_image)
topicText = findViewById(R.id.share_topic_text)
progress = findViewById(R.id.share_progress)
progress.visibility = View.GONE
2022-02-11 21:55:08 +01:00
errorText = findViewById(R.id.share_error_text)
errorText.visibility = View.GONE
errorImage = findViewById(R.id.share_error_image)
errorImage.visibility = View.GONE
2022-02-11 16:46:55 +01:00
val textWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
validateInput()
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
// Nothing
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
// Nothing
}
}
2022-02-11 21:55:08 +01:00
contentText.addTextChangedListener(textWatcher)
2022-02-11 16:46:55 +01:00
topicText.addTextChangedListener(textWatcher)
// Incoming intent
val intent = intent ?: return
if (intent.action != Intent.ACTION_SEND) return
if ("text/plain" == intent.type) {
handleSendText(intent)
2022-02-11 21:55:08 +01:00
} else if (supportedImage(intent.type)) {
2022-02-11 16:46:55 +01:00
handleSendImage(intent)
2022-02-11 21:55:08 +01:00
} else {
handleSendFile(intent)
2022-02-11 16:46:55 +01:00
}
}
private fun handleSendText(intent: Intent) {
intent.getStringExtra(Intent.EXTRA_TEXT)?.let { text ->
contentImage.visibility = View.GONE
contentText.text = text
}
}
private fun handleSendImage(intent: Intent) {
2022-02-11 21:55:08 +01:00
fileUri = intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as? Uri ?: return
2022-02-11 16:46:55 +01:00
try {
val resolver = applicationContext.contentResolver
2022-02-11 21:55:08 +01:00
val bitmapStream = resolver.openInputStream(fileUri!!)
2022-02-11 16:46:55 +01:00
val bitmap = BitmapFactory.decodeStream(bitmapStream)
contentImage.setImageBitmap(bitmap)
contentImage.visibility = View.VISIBLE
contentText.text = getString(R.string.share_content_image_text)
} catch (_: Exception) {
2022-02-11 21:55:08 +01:00
fileUri = null
contentImage.visibility = View.GONE
2022-02-11 16:46:55 +01:00
contentText.text = getString(R.string.share_content_image_error)
}
}
2022-02-11 21:55:08 +01:00
private fun handleSendFile(intent: Intent) {
fileUri = intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as? Uri ?: return
contentText.text = getString(R.string.share_content_file_text)
}
2022-02-11 16:46:55 +01:00
override fun onSupportNavigateUp(): Boolean {
finish()
return true
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_share_action_bar, menu)
this.menu = menu
sendItem = menu.findItem(R.id.share_menu_send)
validateInput() // Disable icon
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.share_menu_send -> {
onShareClick()
true
}
else -> super.onOptionsItemSelected(item)
}
}
private fun onShareClick() {
2022-02-11 21:55:08 +01:00
val baseUrl = "https://ntfy.sh" // FIXME
val topic = topicText.text.toString()
val message = contentText.text.toString()
progress.visibility = View.VISIBLE
lifecycleScope.launch(Dispatchers.IO) {
val user = repository.getUser(baseUrl)
try {
val body = if (fileUri != null) {
val resolver = applicationContext.contentResolver
ContentUriRequestBody(resolver, fileUri!!)
} else {
null
}
api.publish(
baseUrl = baseUrl,
topic = topic,
user = user,
message = message,
title = "",
priority = 3,
tags = emptyList(),
delay = "",
body = body // May be null
)
runOnUiThread {
finish()
}
} catch (e: Exception) {
runOnUiThread {
progress.visibility = View.GONE
errorText.text = e.message
errorImage.visibility = View.VISIBLE
errorText.visibility = View.VISIBLE
}
}
}
2022-02-11 16:46:55 +01:00
}
private fun validateInput() {
if (!this::sendItem.isInitialized) return // Initialized late in onCreateOptionsMenu
sendItem.isEnabled = contentText.text.isNotEmpty() && topicText.text.isNotEmpty()
sendItem.icon.alpha = if (sendItem.isEnabled) 255 else 130
}
companion object {
const val TAG = "NtfyShareActivity"
}
}