forked from GitHub-Mirror/riotX-android
Send reaction view quick react and picker
+ fix / Error when to many reactions in cells (more than placeholders -8-) + fix / DefaultTimeline quick map access was not shifted when items inserted at given index
This commit is contained in:
@ -49,4 +49,6 @@ interface SendService {
|
||||
fun sendMedias(attachments: List<ContentAttachmentData>): Cancelable
|
||||
|
||||
|
||||
fun sendReaction(reaction: String, targetEventId: String) : Cancelable
|
||||
|
||||
}
|
@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.session.room
|
||||
|
||||
import im.vector.matrix.android.api.session.events.model.Content
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.room.model.annotation.ReactionContent
|
||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomResponse
|
||||
import im.vector.matrix.android.internal.network.NetworkConstants
|
||||
@ -156,4 +157,20 @@ internal interface RoomAPI {
|
||||
@Path("state_event_type") stateEventType: String,
|
||||
@Path("state_key") stateKey: String,
|
||||
@Body params: Map<String, String>): Call<Unit>
|
||||
|
||||
/**
|
||||
* Send a relation event to a room.
|
||||
*
|
||||
* @param txId the transaction Id
|
||||
* @param roomId the room id
|
||||
* @param eventType the event type
|
||||
* @param content the event content
|
||||
*/
|
||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/send_relation/{parent_id}/{relation_type}/{event_type}")
|
||||
fun sendRelation(@Path("roomId") roomId: String,
|
||||
@Path("parentId") parent_id: String,
|
||||
@Path("relation_type") relationType: String,
|
||||
@Path("eventType") eventType: String,
|
||||
@Body content: Content?
|
||||
): Call<SendResponse>
|
||||
}
|
@ -74,6 +74,18 @@ internal class DefaultSendService(private val roomId: String,
|
||||
return cancelableBag
|
||||
}
|
||||
|
||||
|
||||
override fun sendReaction(reaction: String, targetEventId: String) : Cancelable {
|
||||
val event = eventFactory.createReactionEvent(roomId,targetEventId,reaction).also {
|
||||
saveLocalEcho(it)
|
||||
}
|
||||
val sendRelationWork = createSendRelationWork(event)
|
||||
WorkManager.getInstance()
|
||||
.beginUniqueWork(buildWorkIdentifier(SEND_WORK), ExistingWorkPolicy.APPEND, sendRelationWork)
|
||||
.enqueue()
|
||||
return CancelableWork(sendRelationWork.id)
|
||||
}
|
||||
|
||||
override fun sendMedia(attachment: ContentAttachmentData): Cancelable {
|
||||
// Create an event with the media file path
|
||||
val event = eventFactory.createMediaEvent(roomId, attachment).also {
|
||||
@ -116,6 +128,19 @@ internal class DefaultSendService(private val roomId: String,
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun createSendRelationWork(event: Event): OneTimeWorkRequest {
|
||||
//TODO use the new API to send relation (for now use regular send)
|
||||
val sendContentWorkerParams = SendEventWorker.Params(
|
||||
roomId, event)
|
||||
val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams)
|
||||
|
||||
return OneTimeWorkRequestBuilder<SendEventWorker>()
|
||||
.setConstraints(WORK_CONSTRAINTS)
|
||||
.setInputData(sendWorkData)
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, BACKOFF_DELAY, TimeUnit.MILLISECONDS)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun createUploadMediaWork(event: Event, attachment: ContentAttachmentData): OneTimeWorkRequest {
|
||||
val uploadMediaWorkerParams = UploadContentWorker.Params(roomId, event, attachment)
|
||||
val uploadWorkData = WorkerParamsFactory.toData(uploadMediaWorkerParams)
|
||||
|
@ -21,18 +21,11 @@ import im.vector.matrix.android.api.auth.data.Credentials
|
||||
import im.vector.matrix.android.api.session.content.ContentAttachmentData
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.RelationType
|
||||
import im.vector.matrix.android.api.session.events.model.toContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.AudioInfo
|
||||
import im.vector.matrix.android.api.session.room.model.message.FileInfo
|
||||
import im.vector.matrix.android.api.session.room.model.message.ImageInfo
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageType
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.ThumbnailInfo
|
||||
import im.vector.matrix.android.api.session.room.model.message.VideoInfo
|
||||
import im.vector.matrix.android.api.session.room.model.annotation.ReactionContent
|
||||
import im.vector.matrix.android.api.session.room.model.annotation.ReactionInfo
|
||||
import im.vector.matrix.android.api.session.room.model.message.*
|
||||
import im.vector.matrix.android.internal.session.content.ThumbnailExtractor
|
||||
|
||||
internal class LocalEchoEventFactory(private val credentials: Credentials) {
|
||||
@ -47,10 +40,29 @@ internal class LocalEchoEventFactory(private val credentials: Credentials) {
|
||||
ContentAttachmentData.Type.IMAGE -> createImageEvent(roomId, attachment)
|
||||
ContentAttachmentData.Type.VIDEO -> createVideoEvent(roomId, attachment)
|
||||
ContentAttachmentData.Type.AUDIO -> createAudioEvent(roomId, attachment)
|
||||
ContentAttachmentData.Type.FILE -> createFileEvent(roomId, attachment)
|
||||
ContentAttachmentData.Type.FILE -> createFileEvent(roomId, attachment)
|
||||
}
|
||||
}
|
||||
|
||||
fun createReactionEvent(roomId: String, targetEventId: String, reaction: String): Event {
|
||||
val content = ReactionContent(
|
||||
ReactionInfo(
|
||||
RelationType.ANNOTATION,
|
||||
targetEventId,
|
||||
reaction
|
||||
)
|
||||
)
|
||||
return Event(
|
||||
roomId = roomId,
|
||||
originServerTs = dummyOriginServerTs(),
|
||||
sender = credentials.userId,
|
||||
eventId = dummyEventId(roomId),
|
||||
type = EventType.REACTION,
|
||||
content = content.toContent()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun createImageEvent(roomId: String, attachment: ContentAttachmentData): Event {
|
||||
val content = MessageImageContent(
|
||||
type = MessageType.MSGTYPE_IMAGE,
|
||||
|
@ -0,0 +1,55 @@
|
||||
package im.vector.matrix.android.internal.session.room.send
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.annotation.ReactionContent
|
||||
import im.vector.matrix.android.api.session.room.model.annotation.ReactionInfo
|
||||
import im.vector.matrix.android.internal.di.MatrixKoinComponent
|
||||
import im.vector.matrix.android.internal.network.executeRequest
|
||||
import im.vector.matrix.android.internal.session.room.RoomAPI
|
||||
import im.vector.matrix.android.internal.util.WorkerParamsFactory
|
||||
import org.koin.standalone.inject
|
||||
|
||||
class SendRelationWorker(context: Context, params: WorkerParameters)
|
||||
: Worker(context, params), MatrixKoinComponent {
|
||||
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class Params(
|
||||
val roomId: String,
|
||||
val event: Event,
|
||||
val relationType: String? = null
|
||||
)
|
||||
|
||||
private val roomAPI by inject<RoomAPI>()
|
||||
|
||||
override fun doWork(): Result {
|
||||
val params = WorkerParamsFactory.fromData<SendRelationWorker.Params>(inputData)
|
||||
?: return Result.failure()
|
||||
|
||||
val localEvent = params.event
|
||||
if (localEvent.eventId == null) {
|
||||
return Result.failure()
|
||||
}
|
||||
val relationContent = localEvent.content.toModel<ReactionContent>()
|
||||
?: return Result.failure()
|
||||
val relatedEventId = relationContent.relatesTo?.eventId ?: return Result.failure()
|
||||
val relationType = (relationContent.relatesTo as? ReactionInfo)?.type ?: params.relationType
|
||||
?: return Result.failure()
|
||||
|
||||
val result = executeRequest<SendResponse> {
|
||||
apiCall = roomAPI.sendRelation(
|
||||
roomId = params.roomId,
|
||||
parent_id = relatedEventId,
|
||||
relationType = relationType,
|
||||
eventType = localEvent.type,
|
||||
content = localEvent.content
|
||||
)
|
||||
}
|
||||
return result.fold({ Result.retry() }, { Result.success() })
|
||||
}
|
||||
}
|
@ -419,6 +419,8 @@ internal class DefaultTimeline(
|
||||
val timelineEvent = timelineEventFactory.create(eventEntity)
|
||||
val position = if (direction == Timeline.Direction.FORWARDS) 0 else builtEvents.size
|
||||
builtEvents.add(position, timelineEvent)
|
||||
//Need to shift :/
|
||||
builtEventsIdMap.entries.filter { it.value >= position }.forEach { it.setValue(it.value + 1) }
|
||||
builtEventsIdMap[eventEntity.eventId] = position
|
||||
}
|
||||
Timber.v("Built ${offsetResults.size} items from db")
|
||||
|
Reference in New Issue
Block a user