improve composing statuses

This commit is contained in:
Konrad Pozniak 2020-06-17 14:48:18 +02:00
parent a96abd1343
commit 99c1a3ec87
8 changed files with 199 additions and 120 deletions

View File

@ -4,21 +4,24 @@ import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import at.connyduck.pixelcat.R import at.connyduck.pixelcat.R
import at.connyduck.pixelcat.components.general.BaseActivity import at.connyduck.pixelcat.components.general.BaseActivity
import at.connyduck.pixelcat.dagger.ViewModelFactory import at.connyduck.pixelcat.dagger.ViewModelFactory
import at.connyduck.pixelcat.databinding.ActivityComposeBinding import at.connyduck.pixelcat.databinding.ActivityComposeBinding
import at.connyduck.pixelcat.util.viewBinding import at.connyduck.pixelcat.util.viewBinding
import com.fxn.pix.Options
import com.fxn.pix.Pix import com.fxn.pix.Pix
import com.fxn.utility.ImageQuality
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
class ComposeActivity : BaseActivity() { class ComposeActivity : BaseActivity(), OnImageActionClickListener {
@Inject @Inject
lateinit var viewModelFactory: ViewModelFactory lateinit var viewModelFactory: ViewModelFactory
@ -27,7 +30,7 @@ class ComposeActivity : BaseActivity() {
private val binding by viewBinding(ActivityComposeBinding::inflate) private val binding by viewBinding(ActivityComposeBinding::inflate)
private val adapter = ComposeImageAdapter() private val adapter = ComposeImageAdapter(this)
private lateinit var visibilityBottomSheet: BottomSheetBehavior<*> private lateinit var visibilityBottomSheet: BottomSheetBehavior<*>
@ -44,20 +47,28 @@ class ComposeActivity : BaseActivity() {
insets.consumeSystemWindowInsets() insets.consumeSystemWindowInsets()
} }
if (viewModel.images.value.isNullOrEmpty()) { if (viewModel.imageLiveData.value.isNullOrEmpty()) {
viewModel.addImage(intent.getStringExtra(EXTRA_MEDIA_URI)!!) viewModel.addImage(intent.getStringExtra(EXTRA_MEDIA_URI)!!)
} }
setSupportActionBar(binding.composeToolBar) binding.composeToolBar.setNavigationOnClickListener {
supportActionBar?.setDisplayHomeAsUpEnabled(true) onBackPressed()
}
binding.composeImages.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false) binding.composeImages.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
binding.composeImages.adapter = adapter binding.composeImages.adapter = adapter
visibilityBottomSheet = BottomSheetBehavior.from(binding.composeVisibilityBottomSheet) visibilityBottomSheet = BottomSheetBehavior.from(binding.composeVisibilityBottomSheet)
visibilityBottomSheet.state = BottomSheetBehavior.STATE_HIDDEN
binding.composeShareButton.setOnClickListener { binding.composeShareButton.setOnClickListener {
viewModel.sendStatus() lifecycleScope.launch {
viewModel.sendStatus(
caption = binding.composeCaptionInput.text?.toString().orEmpty(),
sensitive = binding.composeNsfwSwitch.isChecked
)
finish()
}
} }
binding.composeVisibilityButton.setOnClickListener { binding.composeVisibilityButton.setOnClickListener {
@ -73,7 +84,7 @@ class ComposeActivity : BaseActivity() {
changeVisibility(VISIBILITY.FOLLOWERS_ONLY) changeVisibility(VISIBILITY.FOLLOWERS_ONLY)
} }
viewModel.images.observe( viewModel.imageLiveData.observe(
this, this,
Observer { Observer {
adapter.submitList(it) adapter.submitList(it)
@ -99,14 +110,22 @@ class ComposeActivity : BaseActivity() {
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_PICK_MEDIA) { if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_PICK_MEDIA) {
val returnValue = val returnValue =
data?.getStringArrayListExtra(Pix.IMAGE_RESULTS) data?.getStringArrayListExtra(Pix.IMAGE_RESULTS)
Log.e("Result", returnValue.toString())
viewModel.addImage(returnValue?.first()!!) viewModel.addImage(returnValue?.first()!!)
} }
} }
private fun changeVisibility(visibility: VISIBILITY) { private fun changeVisibility(visibility: VISIBILITY) {
viewModel.setVisibility(visibility) viewModel.setVisibility(visibility)
visibilityBottomSheet.state = BottomSheetBehavior.STATE_COLLAPSED visibilityBottomSheet.state = BottomSheetBehavior.STATE_HIDDEN
}
override fun onAddImage() {
val options = Options.init()
.setRequestCode(REQUEST_CODE_PICK_MEDIA)
.setImageQuality(ImageQuality.HIGH)
.setScreenOrientation(Options.SCREEN_ORIENTATION_PORTRAIT)
Pix.start(this, options)
} }
companion object { companion object {

View File

@ -2,15 +2,23 @@ package at.connyduck.pixelcat.components.compose
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.setPadding
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import at.connyduck.pixelcat.R import at.connyduck.pixelcat.R
import at.connyduck.pixelcat.databinding.ItemComposeImageBinding import at.connyduck.pixelcat.databinding.ItemComposeImageBinding
import at.connyduck.sparkbutton.helpers.Utils
import coil.api.load import coil.api.load
import java.io.File import java.io.File
class ComposeImageAdapter : ListAdapter<String, ComposeImageViewHolder>( interface OnImageActionClickListener {
fun onAddImage()
}
class ComposeImageAdapter(
private val listener: OnImageActionClickListener
) : ListAdapter<String, ComposeImageViewHolder>(
object : DiffUtil.ItemCallback<String>() { object : DiffUtil.ItemCallback<String>() {
override fun areItemsTheSame(old: String, new: String): Boolean { override fun areItemsTheSame(old: String, new: String): Boolean {
return old == new return old == new
@ -32,12 +40,26 @@ class ComposeImageAdapter : ListAdapter<String, ComposeImageViewHolder>(
getItem(position)?.let { uri -> getItem(position)?.let { uri ->
holder.binding.root.load(File(uri)) { if (uri == ADD_ITEM) {
placeholder(R.drawable.ic_cat) holder.binding.root.load(R.drawable.ic_plus_square_large)
error(R.drawable.ic_message) holder.binding.root.setPadding(Utils.dpToPx(holder.binding.root.context, 40))
holder.binding.root.setOnClickListener {
listener.onAddImage()
}
return
} else {
holder.binding.root.load(File(uri)) {
placeholder(R.drawable.ic_cat)
error(R.drawable.ic_message)
}
holder.binding.root.setOnClickListener {}
} }
} }
} }
companion object {
const val ADD_ITEM = "add_item"
}
} }
class ComposeImageViewHolder(val binding: ItemComposeImageBinding) : class ComposeImageViewHolder(val binding: ItemComposeImageBinding) :

View File

@ -4,9 +4,8 @@ import android.content.Context
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import at.connyduck.pixelcat.components.compose.ComposeImageAdapter.Companion.ADD_ITEM
import at.connyduck.pixelcat.db.AccountManager import at.connyduck.pixelcat.db.AccountManager
import kotlinx.coroutines.launch
import javax.inject.Inject import javax.inject.Inject
class ComposeViewModel @Inject constructor( class ComposeViewModel @Inject constructor(
@ -14,33 +13,41 @@ class ComposeViewModel @Inject constructor(
val accountManager: AccountManager val accountManager: AccountManager
) : ViewModel() { ) : ViewModel() {
val images = MutableLiveData<List<String>>() private val images: MutableList<String> = mutableListOf()
val imageLiveData = MutableLiveData<List<String>>()
val visibility = MutableLiveData(VISIBILITY.PUBLIC) val visibility = MutableLiveData(VISIBILITY.PUBLIC)
fun addImage(imageUri: String) { fun addImage(imageUri: String) {
images.add(imageUri)
images.value = images.value.orEmpty() + imageUri imageLiveData.value = if (images.size < MAX_IMAGE_COUNT) {
images + ADD_ITEM
} else {
images
}
} }
fun setVisibility(visibility: VISIBILITY) { fun setVisibility(visibility: VISIBILITY) {
this.visibility.value = visibility this.visibility.value = visibility
} }
fun sendStatus() { suspend fun sendStatus(caption: String, sensitive: Boolean) {
viewModelScope.launch { val statusToSend = StatusToSend(
val statusToSend = StatusToSend( accountId = accountManager.activeAccount()!!.id,
accountId = accountManager.activeAccount()!!.id, text = caption,
text = "test", visibility = visibility.value!!.serverName,
visibility = visibility.value!!.serverName, sensitive = sensitive,
sensitive = false, mediaUris = images
mediaUris = images.value!! )
)
val intent = SendStatusService.sendStatusIntent(context, statusToSend) val intent = SendStatusService.sendStatusIntent(context, statusToSend)
ContextCompat.startForegroundService(context, intent) ContextCompat.startForegroundService(context, intent)
} }
companion object {
private const val MAX_IMAGE_COUNT = 4
} }
} }

View File

@ -3,7 +3,6 @@ package at.connyduck.pixelcat.components.main
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.activity.viewModels import androidx.activity.viewModels
import at.connyduck.pixelcat.R import at.connyduck.pixelcat.R
@ -93,7 +92,6 @@ class MainActivity : BaseActivity() {
if (resultCode == Activity.RESULT_OK && requestCode == 100) { if (resultCode == Activity.RESULT_OK && requestCode == 100) {
val returnValue = val returnValue =
data?.getStringArrayListExtra(Pix.IMAGE_RESULTS) data?.getStringArrayListExtra(Pix.IMAGE_RESULTS)
Log.e("Result", returnValue.toString())
startActivity(ComposeActivity.newIntent(this, returnValue?.firstOrNull()!!)) startActivity(ComposeActivity.newIntent(this, returnValue?.firstOrNull()!!))
} }

View File

@ -3,5 +3,5 @@
<corners <corners
android:topLeftRadius="12dp" android:topLeftRadius="12dp"
android:topRightRadius="12dp" /> android:topRightRadius="12dp" />
<solid android:color="#f0f" /> <solid android:color="?attr/colorSurface" />
</shape> </shape>

View File

@ -0,0 +1,27 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="80dp"
android:height="80dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M5,3L19,3A2,2 0,0 1,21 5L21,19A2,2 0,0 1,19 21L5,21A2,2 0,0 1,3 19L3,5A2,2 0,0 1,5 3z"
android:strokeLineJoin="round"
android:strokeWidth="1"
android:fillColor="#00000000"
android:strokeColor="#777"
android:strokeLineCap="round"/>
<path
android:pathData="M12,8L12,16"
android:strokeLineJoin="round"
android:strokeWidth="1"
android:fillColor="#00000000"
android:strokeColor="#777"
android:strokeLineCap="round"/>
<path
android:pathData="M8,12L16,12"
android:strokeLineJoin="round"
android:strokeWidth="1"
android:fillColor="#00000000"
android:strokeColor="#777"
android:strokeLineCap="round"/>
</vector>

View File

@ -1,121 +1,128 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@drawable/pixelcat_gradient"> android:background="@drawable/pixelcat_gradient">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/composeAppBar" android:id="@+id/composeAppBar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/composeToolBar" android:id="@+id/composeToolBar"
style="@style/Widget.MaterialComponents.Toolbar.Surface" style="@style/Widget.MaterialComponents.Toolbar.Surface"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:navigationIcon="@drawable/ic_arrow_back" app:navigationIcon="@drawable/ic_arrow_back"
app:title="@string/compose_new_post"> app:title="@string/compose_new_post">
<Button <Button
android:id="@+id/composeShareButton" android:id="@+id/composeShareButton"
style="@style/Widget.MaterialComponents.Button.OutlinedButton" style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_gravity="end"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:text="@string/compose_action_share" /> android:text="@string/compose_action_share" />
</androidx.appcompat.widget.Toolbar> </androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorSurface" android:background="?attr/colorSurface"
android:orientation="vertical" android:orientation="vertical"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/composeAppBar"> app:layout_constraintTop_toBottomOf="@id/composeAppBar">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/composeImages" android:id="@+id/composeImages"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="200dp" android:layout_height="160dp"
android:orientation="horizontal" android:layout_marginTop="12dp"
app:layout_constraintTop_toBottomOf="@id/composeAppBar" /> android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/composeAppBar" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/composeDescriptionInputLayout" android:id="@+id/composeCaptionInputLayout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="12dp" android:layout_marginStart="12dp"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:layout_marginEnd="12dp" android:layout_marginEnd="12dp"
android:hint="@string/compose_write_caption" android:hint="@string/compose_write_caption"
app:layout_constraintTop_toBottomOf="@+id/loginImageView"> app:layout_constraintTop_toBottomOf="@+id/loginImageView">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/composeDescriptionInput" android:id="@+id/composeCaptionInput"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ems="10" android:ems="10"
android:inputType="text" /> android:inputType="textMultiLine" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.switchmaterial.SwitchMaterial <com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/composeNsfwSwitch" android:id="@+id/composeNsfwSwitch"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="12dp" android:paddingHorizontal="16dp"
android:text="@string/compose_contains_nsfw_media" android:paddingVertical="12dp"
android:textColor="?android:textColorSecondary" /> android:text="@string/compose_contains_nsfw_media"
android:textColor="?android:textColorSecondary" />
<TextView <TextView
android:id="@+id/composeVisibilityButton" android:id="@+id/composeVisibilityButton"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="12dp" android:paddingHorizontal="16dp"
tools:text="@string/compose_visibility" /> android:paddingVertical="12dp"
tools:text="@string/compose_visibility" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/composeVisibilityBottomSheet" android:id="@+id/composeVisibilityBottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/background_bottom_sheet"
android:elevation="12dp"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<TextView
android:id="@+id/composeVisibilityPublic"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/background_bottom_sheet" android:paddingHorizontal="16dp"
android:elevation="12dp" android:paddingVertical="12dp"
android:orientation="vertical" android:text="@string/compose_visibility_public" />
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<TextView <TextView
android:id="@+id/composeVisibilityPublic" android:id="@+id/composeVisibilityUnlisted"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="12dp" android:paddingHorizontal="16dp"
android:text="@string/compose_visibility_public" /> android:paddingVertical="12dp"
android:text="@string/compose_visibility_unlisted" />
<TextView <TextView
android:id="@+id/composeVisibilityUnlisted" android:id="@+id/composeVisibilityFollowers"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="12dp" android:paddingHorizontal="16dp"
android:text="@string/compose_visibility_unlisted" /> android:paddingVertical="12dp"
android:text="@string/compose_visibility_followers_only" />
<TextView
android:id="@+id/composeVisibilityFollowers"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp"
android:text="@string/compose_visibility_followers_only" />
</LinearLayout> </LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp" android:layout_width="160dp"
android:layout_height="200dp" android:layout_height="160dp" />
android:adjustViewBounds="true" />