mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
PreviewUrl: handle close (in memory)
This commit is contained in:
parent
9089c54990
commit
c08c652080
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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() {
|
||||
|
10
vector/src/main/res/drawable/ic_close_24dp.xml
Normal file
10
vector/src/main/res/drawable/ic_close_24dp.xml
Normal 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>
|
@ -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>
|
Loading…
Reference in New Issue
Block a user