Merge branch 'view_models' into 'master'
Use ViewModel in AlbumActivity See merge request pixeldroid/PixelDroid!558
This commit is contained in:
commit
7acd4cface
|
@ -3,40 +3,99 @@ package org.pixeldroid.app.posts
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.WindowInsetsControllerCompat
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.pixeldroid.app.databinding.ActivityAlbumBinding
|
import org.pixeldroid.app.databinding.ActivityAlbumBinding
|
||||||
import org.pixeldroid.app.utils.api.objects.Attachment
|
|
||||||
|
|
||||||
|
|
||||||
class AlbumActivity : AppCompatActivity() {
|
class AlbumActivity : AppCompatActivity() {
|
||||||
|
private val model: AlbumViewModel by viewModels()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
val binding = ActivityAlbumBinding.inflate(layoutInflater)
|
|
||||||
|
|
||||||
|
val binding = ActivityAlbumBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
val mediaAttachments = intent.getSerializableExtra("images") as ArrayList<Attachment>
|
|
||||||
val index = intent.getIntExtra("index", 0)
|
binding.albumPager.adapter = AlbumViewPagerAdapter(
|
||||||
binding.albumPager.adapter = AlbumViewPagerAdapter(mediaAttachments,
|
model.uiState.value.mediaAttachments,
|
||||||
sensitive = false,
|
sensitive = false,
|
||||||
opened = true,
|
opened = true,
|
||||||
//In the activity, we assume we want to show everything
|
//In the activity, we assume we want to show everything
|
||||||
alwaysShowNsfw = true
|
alwaysShowNsfw = true,
|
||||||
|
clickCallback = ::clickCallback
|
||||||
)
|
)
|
||||||
binding.albumPager.currentItem = index
|
|
||||||
|
|
||||||
if(mediaAttachments.size == 1){
|
binding.albumPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||||
|
override fun onPageSelected(position: Int) { model.positionSelected(position) }
|
||||||
|
})
|
||||||
|
|
||||||
|
if (model.uiState.value.mediaAttachments.size == 1) {
|
||||||
binding.albumPager.isUserInputEnabled = false
|
binding.albumPager.isUserInputEnabled = false
|
||||||
}
|
} else if ((model.uiState.value.mediaAttachments.size) > 1) {
|
||||||
else if((mediaAttachments.size) > 1) {
|
|
||||||
binding.postIndicator.setViewPager(binding.albumPager)
|
binding.postIndicator.setViewPager(binding.albumPager)
|
||||||
binding.postIndicator.visibility = View.VISIBLE
|
binding.postIndicator.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
binding.postIndicator.visibility = View.GONE
|
binding.postIndicator.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not really necessary because the ViewPager saves its state in onSaveInstanceState, but
|
||||||
|
// it's good to stay consistent in case something gets out of sync
|
||||||
|
binding.albumPager.setCurrentItem(model.uiState.value.index, false)
|
||||||
|
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
supportActionBar?.setDisplayShowTitleEnabled(false)
|
supportActionBar?.setDisplayShowTitleEnabled(false)
|
||||||
supportActionBar?.setBackgroundDrawable(null)
|
supportActionBar?.setBackgroundDrawable(null)
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
model.uiState.collect { uiState ->
|
||||||
|
binding.albumPager.currentItem = uiState.index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
model.isActionBarHidden.collect { isActionBarHidden ->
|
||||||
|
val windowInsetsController =
|
||||||
|
WindowCompat.getInsetsController(this@AlbumActivity.window, binding.albumPager)
|
||||||
|
if (isActionBarHidden) {
|
||||||
|
// Configure the behavior of the hidden system bars
|
||||||
|
windowInsetsController.systemBarsBehavior =
|
||||||
|
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
|
// Hide both the status bar and the navigation bar
|
||||||
|
supportActionBar?.hide()
|
||||||
|
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
|
||||||
|
binding.postIndicator.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
// Configure the behavior of the hidden system bars
|
||||||
|
windowInsetsController.systemBarsBehavior =
|
||||||
|
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||||
|
// Show both the status bar and the navigation bar
|
||||||
|
supportActionBar?.show()
|
||||||
|
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
|
||||||
|
if ((model.uiState.value.mediaAttachments.size) > 1) {
|
||||||
|
binding.postIndicator.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback passed to the AlbumViewPagerAdapter to signal a single click on the image
|
||||||
|
*/
|
||||||
|
private fun clickCallback(){
|
||||||
|
model.barHide()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package org.pixeldroid.app.posts
|
||||||
|
|
||||||
|
import androidx.lifecycle.SavedStateHandle
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
import org.pixeldroid.app.utils.api.objects.Attachment
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
data class AlbumUiState(
|
||||||
|
val mediaAttachments: ArrayList<Attachment> = arrayListOf(),
|
||||||
|
val index: Int = 0,
|
||||||
|
)
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class AlbumViewModel @Inject constructor(state: SavedStateHandle) : ViewModel() {
|
||||||
|
companion object {
|
||||||
|
const val ALBUM_IMAGES = "AlbumViewImages"
|
||||||
|
const val ALBUM_INDEX = "AlbumViewIndex"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _uiState: MutableStateFlow<AlbumUiState>
|
||||||
|
private val _isActionBarHidden: MutableStateFlow<Boolean>
|
||||||
|
|
||||||
|
init {
|
||||||
|
_uiState = MutableStateFlow(AlbumUiState(
|
||||||
|
mediaAttachments = state[ALBUM_IMAGES] ?: ArrayList(),
|
||||||
|
index = state[ALBUM_INDEX] ?: 0
|
||||||
|
))
|
||||||
|
_isActionBarHidden = MutableStateFlow(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
val uiState: StateFlow<AlbumUiState> = _uiState.asStateFlow()
|
||||||
|
val isActionBarHidden: StateFlow<Boolean> = _isActionBarHidden
|
||||||
|
|
||||||
|
fun barHide() {
|
||||||
|
_isActionBarHidden.update { !it }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun positionSelected(position: Int) {
|
||||||
|
_uiState.update { it.copy(index = position) }
|
||||||
|
}
|
||||||
|
}
|
|
@ -88,8 +88,8 @@ class NestedScrollableHost(context: Context, attrs: AttributeSet? = null) :
|
||||||
}
|
}
|
||||||
val intent = Intent(context, AlbumActivity::class.java)
|
val intent = Intent(context, AlbumActivity::class.java)
|
||||||
|
|
||||||
intent.putExtra("images", images)
|
intent.putExtra(AlbumViewModel.ALBUM_IMAGES, images)
|
||||||
intent.putExtra("index", (child as ViewPager2).currentItem)
|
intent.putExtra(AlbumViewModel.ALBUM_INDEX, (child as ViewPager2).currentItem)
|
||||||
|
|
||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.pixeldroid.app.posts
|
package org.pixeldroid.app.posts
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager.PERMISSION_DENIED
|
import android.content.pm.PackageManager.PERMISSION_DENIED
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
|
@ -18,11 +17,7 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.WindowCompat
|
|
||||||
import androidx.core.view.WindowInsetsCompat
|
|
||||||
import androidx.core.view.WindowInsetsControllerCompat
|
|
||||||
import androidx.lifecycle.LifecycleCoroutineScope
|
import androidx.lifecycle.LifecycleCoroutineScope
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
@ -806,17 +801,15 @@ class StatusViewHolder(val binding: PostFragmentBinding) : RecyclerView.ViewHold
|
||||||
class AlbumViewPagerAdapter(
|
class AlbumViewPagerAdapter(
|
||||||
private val media_attachments: List<Attachment>, private var sensitive: Boolean?,
|
private val media_attachments: List<Attachment>, private var sensitive: Boolean?,
|
||||||
private val opened: Boolean, private val alwaysShowNsfw: Boolean,
|
private val opened: Boolean, private val alwaysShowNsfw: Boolean,
|
||||||
) :
|
private val clickCallback: (() -> Unit)? = null
|
||||||
RecyclerView.Adapter<AlbumViewPagerAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<AlbumViewPagerAdapter.ViewHolder>() {
|
||||||
|
|
||||||
private var isActionBarHidden: Boolean = false
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return if(!opened) ViewHolderClosed(AlbumImageViewBinding.inflate(
|
return if(!opened) ViewHolderClosed(AlbumImageViewBinding.inflate(
|
||||||
LayoutInflater.from(parent.context), parent, false
|
LayoutInflater.from(parent.context), parent, false
|
||||||
)) else ViewHolderOpen(OpenedAlbumBinding.inflate(
|
)) else ViewHolderOpen(OpenedAlbumBinding.inflate(
|
||||||
LayoutInflater.from(parent.context), parent, false
|
LayoutInflater.from(parent.context), parent, false
|
||||||
))
|
), clickCallback!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount() = media_attachments.size
|
override fun getItemCount() = media_attachments.size
|
||||||
|
@ -847,24 +840,6 @@ class AlbumViewPagerAdapter(
|
||||||
setDoubleTapZoomDpi(240)
|
setDoubleTapZoomDpi(240)
|
||||||
resetScaleAndCenter()
|
resetScaleAndCenter()
|
||||||
}
|
}
|
||||||
holder.image.setOnClickListener {
|
|
||||||
val windowInsetsController = WindowCompat.getInsetsController((it.context as Activity).window, it)
|
|
||||||
// Configure the behavior of the hidden system bars
|
|
||||||
if (isActionBarHidden) {
|
|
||||||
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
|
||||||
// Hide both the status bar and the navigation bar
|
|
||||||
(it.context as AppCompatActivity).supportActionBar?.show()
|
|
||||||
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
|
|
||||||
isActionBarHidden = false
|
|
||||||
} else {
|
|
||||||
// Configure the behavior of the hidden system bars
|
|
||||||
windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
|
||||||
// Hide both the status bar and the navigation bar
|
|
||||||
(it.context as AppCompatActivity).supportActionBar?.hide()
|
|
||||||
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
|
|
||||||
isActionBarHidden = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else Glide.with(holder.binding.root)
|
else Glide.with(holder.binding.root)
|
||||||
.asDrawable().fitCenter()
|
.asDrawable().fitCenter()
|
||||||
|
@ -910,9 +885,13 @@ class AlbumViewPagerAdapter(
|
||||||
abstract val videoPlayButton: ImageView
|
abstract val videoPlayButton: ImageView
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolderOpen(override val binding: OpenedAlbumBinding) : ViewHolder(binding) {
|
class ViewHolderOpen(override val binding: OpenedAlbumBinding, clickCallback: () -> Unit) : ViewHolder(binding) {
|
||||||
override val image: SubsamplingScaleImageView = binding.imageImageView
|
override val image: SubsamplingScaleImageView = binding.imageImageView
|
||||||
override val videoPlayButton: ImageView = binding.videoPlayButton
|
override val videoPlayButton: ImageView = binding.videoPlayButton
|
||||||
|
|
||||||
|
init {
|
||||||
|
image.setOnClickListener { clickCallback() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class ViewHolderClosed(override val binding: AlbumImageViewBinding) : ViewHolder(binding) {
|
class ViewHolderClosed(override val binding: AlbumImageViewBinding) : ViewHolder(binding) {
|
||||||
override val image: ImageView = binding.imageImageView
|
override val image: ImageView = binding.imageImageView
|
||||||
|
|
Loading…
Reference in New Issue