kopia lustrzana https://github.com/ryukoposting/Signal-Android
173 wiersze
5.0 KiB
Kotlin
173 wiersze
5.0 KiB
Kotlin
package org.thoughtcrime.securesms.stories
|
|
|
|
import android.content.Context
|
|
import android.os.Bundle
|
|
import android.os.Parcelable
|
|
import android.util.AttributeSet
|
|
import android.view.View
|
|
import android.widget.FrameLayout
|
|
import android.widget.ImageView
|
|
import android.widget.TextView
|
|
import org.signal.core.util.getParcelableCompat
|
|
import org.thoughtcrime.securesms.R
|
|
import org.thoughtcrime.securesms.blurhash.BlurHash
|
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
|
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
|
import org.thoughtcrime.securesms.mms.GlideApp
|
|
import org.thoughtcrime.securesms.recipients.Recipient
|
|
import org.thoughtcrime.securesms.util.visible
|
|
|
|
/**
|
|
* Displays loading / error slate in Story viewer.
|
|
*/
|
|
class StorySlateView @JvmOverloads constructor(
|
|
context: Context,
|
|
attrs: AttributeSet? = null
|
|
) : FrameLayout(context, attrs) {
|
|
|
|
var callback: Callback? = null
|
|
|
|
var state: State = State.HIDDEN
|
|
private set
|
|
|
|
private var postId: Long = 0L
|
|
|
|
init {
|
|
inflate(context, R.layout.stories_slate_view, this)
|
|
}
|
|
|
|
private val background: ImageView = findViewById(R.id.background)
|
|
private val loadingSpinner: View = findViewById(R.id.loading_spinner)
|
|
private val errorCircle: View = findViewById(R.id.error_circle)
|
|
private val errorBackground: View = findViewById(R.id.stories_error_background)
|
|
private val unavailableText: TextView = findViewById(R.id.unavailable)
|
|
private val errorText: TextView = findViewById(R.id.error_text)
|
|
|
|
fun moveToState(state: State, postId: Long, sender: Recipient? = null) {
|
|
if (this.state == state && this.postId == postId) {
|
|
return
|
|
}
|
|
|
|
if (this.postId != postId) {
|
|
this.postId = postId
|
|
moveToHiddenState()
|
|
callback?.onStateChanged(State.HIDDEN, postId)
|
|
}
|
|
|
|
when (state) {
|
|
State.LOADING -> moveToProgressState(State.LOADING)
|
|
State.ERROR -> moveToErrorState()
|
|
State.RETRY -> moveToProgressState(State.RETRY)
|
|
State.NOT_FOUND, State.FAILED -> moveToNotFoundState(state, sender)
|
|
State.HIDDEN -> moveToHiddenState()
|
|
}
|
|
|
|
callback?.onStateChanged(state, postId)
|
|
}
|
|
|
|
fun setBackground(blur: BlurHash?) {
|
|
if (blur != null) {
|
|
GlideApp.with(background)
|
|
.load(blur)
|
|
.into(background)
|
|
} else {
|
|
GlideApp.with(background).clear(background)
|
|
}
|
|
}
|
|
|
|
private fun moveToProgressState(state: State) {
|
|
this.state = state
|
|
visible = true
|
|
background.visible = true
|
|
loadingSpinner.visible = true
|
|
errorCircle.visible = false
|
|
errorBackground.visible = false
|
|
unavailableText.visible = false
|
|
errorText.visible = false
|
|
}
|
|
|
|
private fun moveToErrorState() {
|
|
state = State.ERROR
|
|
visible = true
|
|
background.visible = true
|
|
loadingSpinner.visible = false
|
|
errorCircle.visible = true
|
|
errorBackground.visible = true
|
|
unavailableText.visible = false
|
|
errorText.visible = true
|
|
|
|
if (NetworkConstraint.isMet(ApplicationDependencies.getApplication())) {
|
|
errorText.setText(R.string.StorySlateView__couldnt_load_content)
|
|
} else {
|
|
errorText.setText(R.string.StorySlateView__no_internet_connection)
|
|
}
|
|
}
|
|
|
|
private fun moveToNotFoundState(state: State, sender: Recipient?) {
|
|
this.state = state
|
|
visible = true
|
|
background.visible = true
|
|
loadingSpinner.visible = false
|
|
errorCircle.visible = false
|
|
errorBackground.visible = false
|
|
unavailableText.visible = true
|
|
errorText.visible = false
|
|
|
|
if (state == State.FAILED && sender != null) {
|
|
unavailableText.text = context.getString(R.string.StorySlateView__cant_download_story_s_will_need_to_share_it_again, sender.getShortDisplayName(context))
|
|
} else {
|
|
unavailableText.setText(R.string.StorySlateView__this_story_is_no_longer_available)
|
|
}
|
|
}
|
|
|
|
private fun moveToHiddenState() {
|
|
state = State.HIDDEN
|
|
visible = false
|
|
}
|
|
|
|
override fun onSaveInstanceState(): Parcelable {
|
|
val rootState = super.onSaveInstanceState()
|
|
return Bundle().apply {
|
|
putParcelable("ROOT", rootState)
|
|
putInt("STATE", state.code)
|
|
putLong("ID", postId)
|
|
}
|
|
}
|
|
|
|
override fun onRestoreInstanceState(state: Parcelable?) {
|
|
if (state is Bundle) {
|
|
val rootState: Parcelable? = state.getParcelableCompat("ROOT", Parcelable::class.java)
|
|
this.state = State.fromCode(state.getInt("STATE", State.HIDDEN.code))
|
|
this.postId = state.getLong("ID")
|
|
super.onRestoreInstanceState(rootState)
|
|
} else {
|
|
super.onRestoreInstanceState(state)
|
|
}
|
|
}
|
|
|
|
init {
|
|
errorCircle.setOnClickListener { moveToState(State.RETRY, postId) }
|
|
}
|
|
|
|
interface Callback {
|
|
fun onStateChanged(state: State, postId: Long)
|
|
}
|
|
|
|
enum class State(val code: Int, val hasClickableContent: Boolean) {
|
|
LOADING(0, false),
|
|
ERROR(1, true),
|
|
RETRY(2, true),
|
|
NOT_FOUND(3, false),
|
|
HIDDEN(4, false),
|
|
FAILED(5, false);
|
|
|
|
companion object {
|
|
fun fromCode(code: Int): State {
|
|
return values().firstOrNull {
|
|
it.code == code
|
|
} ?: HIDDEN
|
|
}
|
|
}
|
|
}
|
|
}
|