PreviewUrl: handle close (in memory)

This commit is contained in:
Benoit Marty 2020-12-04 12:41:26 +01:00
parent 9089c54990
commit c08c652080
7 changed files with 69 additions and 9 deletions

View file

@ -140,6 +140,7 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageInformationD
import im.vector.app.features.home.room.detail.timeline.item.MessageTextItem
import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData
import im.vector.app.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
import im.vector.app.features.home.room.detail.widget.RoomWidgetsBottomSheet
import im.vector.app.features.html.EventHtmlRenderer
import im.vector.app.features.html.PillImageSpan
@ -215,6 +216,7 @@ class RoomDetailFragment @Inject constructor(
private val session: Session,
private val avatarRenderer: AvatarRenderer,
private val timelineEventController: TimelineEventController,
private val previewUrlRetriever: PreviewUrlRetriever,
autoCompleterFactory: AutoCompleter.Factory,
private val permalinkHandler: PermalinkHandler,
private val notificationDrawerManager: NotificationDrawerManager,
@ -1656,8 +1658,8 @@ class RoomDetailFragment @Inject constructor(
onUrlClicked(url, url)
}
override fun onPreviewUrlCloseClicked(url: String) {
TODO("Not yet implemented")
override fun onPreviewUrlCloseClicked(eventId: String, url: String) {
previewUrlRetriever.doNotShowPreviewUrlFor(eventId, url)
}
private fun onShareActionClicked(action: EventSharedAction.Share) {

View file

@ -126,7 +126,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
interface PreviewUrlCallback {
fun onPreviewUrlClicked(url: String)
fun onPreviewUrlCloseClicked(url: String)
fun onPreviewUrlCloseClicked(eventId: String, url: String)
}
// Map eventId to adapter position

View file

@ -32,13 +32,18 @@ class PreviewUrlRetriever @Inject constructor(
private val data = mutableMapOf<String, PreviewUrlUiState>()
private val listeners = mutableMapOf<String, MutableSet<PreviewUrlRetrieverListener>>()
// In memory list
private val blockedUrl = mutableSetOf<String>()
fun getPreviewUrl(event: Event, coroutineScope: CoroutineScope) {
val eventId = event.eventId ?: return
synchronized(data) {
if (data[eventId] == null) {
// Keep only the first URL for the moment
val url = session.mediaService().extractUrls(event).firstOrNull()
val url = session.mediaService().extractUrls(event)
.firstOrNull()
?.takeIf { it !in blockedUrl }
if (url == null) {
updateState(eventId, PreviewUrlUiState.NoUrl)
} else {
@ -60,7 +65,12 @@ class PreviewUrlRetriever @Inject constructor(
}.fold(
{
synchronized(data) {
updateState(eventId, PreviewUrlUiState.Data(urlToRetrieve, it))
// Blocked after the request has been sent?
if (urlToRetrieve in blockedUrl) {
updateState(eventId, PreviewUrlUiState.NoUrl)
} else {
updateState(eventId, PreviewUrlUiState.Data(eventId, urlToRetrieve, it))
}
}
},
{
@ -73,6 +83,19 @@ class PreviewUrlRetriever @Inject constructor(
}
}
fun doNotShowPreviewUrlFor(eventId: String, url: String) {
blockedUrl.add(url)
// Notify the listener
synchronized(data) {
data[eventId]
?.takeIf { it is PreviewUrlUiState.Data && it.url == url }
?.let {
updateState(eventId, PreviewUrlUiState.NoUrl)
}
}
}
private fun updateState(eventId: String, state: PreviewUrlUiState) {
data[eventId] = state
// Notify the listener

View file

@ -35,5 +35,7 @@ sealed class PreviewUrlUiState {
data class Error(val throwable: Throwable) : PreviewUrlUiState()
// PreviewUrl data
data class Data(val url: String, val previewUrlData: PreviewUrlData) : PreviewUrlUiState()
data class Data(val eventId: String,
val url: String,
val previewUrlData: PreviewUrlData) : PreviewUrlUiState()
}

View file

@ -53,6 +53,9 @@ class PreviewUrlView @JvmOverloads constructor(
@BindView(R.id.url_preview_site)
lateinit var siteView: TextView
@BindView(R.id.url_preview_close)
lateinit var closeView: View
var delegate: TimelineEventController.PreviewUrlCallback? = null
init {
@ -78,10 +81,10 @@ class PreviewUrlView @JvmOverloads constructor(
hideAll()
when (newState) {
PreviewUrlUiState.Unknown,
PreviewUrlUiState.NoUrl -> renderHidden()
PreviewUrlUiState.Loading -> renderLoading()
PreviewUrlUiState.NoUrl -> renderHidden()
PreviewUrlUiState.Loading -> renderLoading()
is PreviewUrlUiState.Error -> renderHidden()
is PreviewUrlUiState.Data -> renderData(newState.previewUrlData, imageContentRenderer)
is PreviewUrlUiState.Data -> renderData(newState.previewUrlData, imageContentRenderer)
}
}
@ -92,6 +95,13 @@ class PreviewUrlView @JvmOverloads constructor(
}
}
private fun onCloseClick() {
when (val finalState = state) {
is PreviewUrlUiState.Data -> delegate?.onPreviewUrlCloseClicked(finalState.eventId, finalState.url)
else -> Unit
}
}
// PRIVATE METHODS ****************************************************************************************************************************************
private fun setupView() {
@ -99,6 +109,7 @@ class PreviewUrlView @JvmOverloads constructor(
ButterKnife.bind(this)
setOnClickListener(this)
closeView.setOnClickListener { onCloseClick() }
}
private fun renderHidden() {

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="24dp"
android:viewportWidth="25"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:fillType="evenOdd"
android:pathData="M17.7929,5.2929C18.1834,4.9024 18.8166,4.9024 19.2071,5.2929C19.5976,5.6834 19.5976,6.3166 19.2071,6.7071L13.9142,12L19.2071,17.2929C19.5976,17.6834 19.5976,18.3166 19.2071,18.7071C18.8166,19.0976 18.1834,19.0976 17.7929,18.7071L12.5,13.4142L7.2071,18.7071C6.8166,19.0976 6.1834,19.0976 5.7929,18.7071C5.4024,18.3166 5.4024,17.6834 5.7929,17.2929L11.0858,12L5.7929,6.7071C5.4024,6.3166 5.4024,5.6834 5.7929,5.2929C6.1834,4.9024 6.8166,4.9024 7.2071,5.2929L12.5,10.5858L17.7929,5.2929Z" />
</vector>

View file

@ -26,6 +26,7 @@
android:textColor="?riotx_text_primary"
android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/url_preview_close"
app:layout_constraintStart_toStartOf="@+id/url_preview_left_border"
app:layout_constraintTop_toTopOf="parent"
tools:text="Jo Malone denounces her former brand's John Boyega decision" />
@ -71,4 +72,15 @@
app:layout_constraintTop_toBottomOf="@+id/url_preview_description"
tools:text="BBC News" />
<ImageView
android:id="@+id/url_preview_close"
android:layout_width="@dimen/layout_touch_size"
android:layout_height="@dimen/layout_touch_size"
android:scaleType="center"
android:src="@drawable/ic_close_24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="?riotx_text_secondary"
tools:ignore="MissingPrefix" />
</merge>