From f050574728e943199ba06704f032677645c3ab54 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 8 Nov 2018 19:08:14 +0100 Subject: [PATCH] Start sending message : introduce WorkManager. WIP - have to clean --- .idea/caches/build_file_checksums.ser | Bin 659 -> 659 bytes .../home/room/detail/RoomDetailFragment.kt | 7 +++ .../main/res/drawable-hdpi/ic_send_white.png | Bin 0 -> 335 bytes .../main/res/drawable-mdpi/ic_send_white.png | Bin 0 -> 257 bytes .../main/res/drawable-xhdpi/ic_send_white.png | Bin 0 -> 423 bytes .../res/drawable-xxhdpi/ic_send_white.png | Bin 0 -> 550 bytes .../res/drawable-xxxhdpi/ic_send_white.png | Bin 0 -> 728 bytes .../main/res/layout/fragment_room_detail.xml | 46 +++++++++++++++++- matrix-sdk-android/build.gradle | 3 ++ .../android/api/session/events/model/Event.kt | 8 +-- .../matrix/android/api/session/room/Room.kt | 2 +- .../android/api/session/room/SendService.kt | 10 ++++ .../internal/session/room/DefaultRoom.kt | 7 ++- .../android/internal/session/room/RoomAPI.kt | 22 ++++++++- .../internal/session/room/RoomModule.kt | 9 ++-- .../session/room/send/DefaultSendService.kt | 45 +++++++++++++++++ .../session/room/send/SendContentWorker.kt | 37 ++++++++++++++ .../session/room/send/SendResponse.kt | 9 ++++ .../android/internal/util/CancelableWork.kt | 13 +++++ 19 files changed, 207 insertions(+), 11 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/ic_send_white.png create mode 100644 app/src/main/res/drawable-mdpi/ic_send_white.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_send_white.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_send_white.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_send_white.png create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/SendService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendContentWorker.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendResponse.kt create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CancelableWork.kt diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index de59e1fa0794524236c6a02938b9cd97c2c30ca2..e57bc19dc2581b5ecd95df798eb35ded56c77564 100644 GIT binary patch delta 36 ucmV+<0NekQ1(OAkm<03{tK+epH31O#yc5@sP>j-}U441lSh&2C;Q_KZA`&D3 delta 36 ucmV+<0NekQ1(OAkm<00k1{SfLH31N){kR)&!Qw{^(NrKuZ2*>&;Q_K5G7p9T diff --git a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt index bb4d617f..b9211003 100644 --- a/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt +++ b/app/src/main/java/im/vector/riotredesign/features/home/room/detail/RoomDetailFragment.kt @@ -50,6 +50,13 @@ class RoomDetailFragment : RiotFragment() { room.loadRoomMembersIfNeeded() room.liveTimeline().observe(this, Observer { renderEvents(it) }) room.roomSummary.observe(this, Observer { renderRoomSummary(it) }) + sendButton.setOnClickListener { + val textMessage = composerEditText.text.toString() + if (textMessage.isNotBlank()) { + composerEditText.text = null + room.sendTextMessage(textMessage) + } + } } private fun setupToolbar() { diff --git a/app/src/main/res/drawable-hdpi/ic_send_white.png b/app/src/main/res/drawable-hdpi/ic_send_white.png new file mode 100644 index 0000000000000000000000000000000000000000..f133cdbeb2757f5d4f51321c302c7fcd81be52fa GIT binary patch literal 335 zcmV-V0kHmwP)jA}WRMU8oC{kc85)g#pw;5z59ljG-BdP&R(yv#6YTg#Hfm zoUTIVIi*5oIemrHb7~5yx+gicg`VIQ-e3wV*yj+6B|>Sk20TL_MlgpBdJNAf zVcN%%X|KI7{+s0%pN@-Jiu}0d%3{6!aL!`2K@(@u-okok(b(jxX7M=&nPib16iu_- h^-;R~`%wzHas(7`hA~Sk`s4rr002ovPDHLkV1mtQjA#G= literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_send_white.png b/app/src/main/res/drawable-mdpi/ic_send_white.png new file mode 100644 index 0000000000000000000000000000000000000000..34e49af7ab119a8581624cba15d1874ddb3ee8d0 GIT binary patch literal 257 zcmV+c0sj7pP)IG(5t990^tH2frgqR&{1*(Y8sBf1tc7SR!1$0@ii-(STgUK*D%SiQ2mo{ z?QG3}$&cECGd@<$#Ov@pO7 z8ys=h=JS168I;gK4->4g$K_K#$v_!R^fAR62V7GI7O15qs-le{=GfvSNHjvh;vsjC z4gEKLW(fVFy<`Y=RlLpc&1L76L33S;GDto+sto`0O*ZiWxujSd^@pKl00000NkvXX Hu0mjfBSB_$ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_send_white.png b/app/src/main/res/drawable-xhdpi/ic_send_white.png new file mode 100644 index 0000000000000000000000000000000000000000..e5f9ba41acdb7d7f9353981e1aa0bcff06353b14 GIT binary patch literal 423 zcmV;Y0a*TtP)prx+ z$_|d)F5m&)eB>qlT-LgJFVHE= z%W~f$arHimd07iA!6xj(DO|!MyjKu7gH_FhR$v3wd;=dyV1##h Rc_07)002ovPDHLkV1lk5y~_Xq literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_send_white.png b/app/src/main/res/drawable-xxhdpi/ic_send_white.png new file mode 100644 index 0000000000000000000000000000000000000000..0ba718b6e25df33c10d4a2b91af75d08ccf25eff GIT binary patch literal 550 zcmV+>0@?kEP)2^SE1z*7@_A8XwdQqbbcxxfm#$i0yQJUBhX4kjY*Dg#$+aQ-5}@Qea_zJ ze0ye9>DKIZ|I={JHOO!%fr2QAf+&cBD2Re6=qGnz3rtW@IbHWX9dHC@D5zXee?Gtk zSf-$IL4(uIB|l$5ZXmzIl=G`9sF>eUPJ(*QZ<5MSLQqoqNeW6LzYu~<=NDR#x%__n zF~q3PFSa1{`DqeV%x{{4{?4xzJ3q~W2In4Z#>mf#plJD76BIl@tAc{%mx3VC{8AEB z%&#deXcEkWHLwd#!8LdSpSk4cYjzCGf)%h0j=?2(0Iw% zKaF?Lp||e^91P3P+7mv>?RziF&!V6?unKm-3Ah4};H?Hh=U~x7Vhdm$?13|I1D*vF z+Xqvc4$@LvFzP{i1B}Ny&4=8AN*PIAC~DY(TFz8eZZ$M+flo#vw;EPw4AVNVDL_ripK@?=1FD5h?{9Ic8+W-In07*qoM6N<$f?2ikg8%>k literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_send_white.png b/app/src/main/res/drawable-xxxhdpi/ic_send_white.png new file mode 100644 index 0000000000000000000000000000000000000000..f02b6453d5c3a05f683d2c49aaa8495033a14b8a GIT binary patch literal 728 zcmV;}0w?{6P)4YaZvw*Q$*X|jJas(hsmet^laJvtPmu(;%u_@GuJROFfQvj;xhT@; z<>_foc`8l7`8?f1K;d~p!0&mQK|n!yLV$6es$6tMTo+5?vDg+b#K)GOmKBkwx_@9& zTorf3L$N6iQ~!;*??Lml*JPgBZd~Nm^G2-H&6DMK;3%u7R-SU+sPeXY26>u~BEa+N zshp>%54&?&J)gzezw%V#%TN}p=jd;FDpkNWu_zviE%97@5IR2x&m@Is-WXJGhPLR$&5Dvz2j;^ zod@ATK + + + + + + + + + + \ No newline at end of file diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 5b5d5c7a..8438f451 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -75,6 +75,9 @@ dependencies { // Paging implementation "android.arch.paging:runtime:1.0.1" + // Work + implementation "android.arch.work:work-runtime-ktx:1.0.0-alpha10" + // FP implementation "io.arrow-kt:arrow-core:$arrow_version" implementation "io.arrow-kt:arrow-instances-core:$arrow_version" diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt index 2763506b..62a24bc8 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/Event.kt @@ -6,12 +6,14 @@ import com.squareup.moshi.JsonClass import im.vector.matrix.android.internal.di.MoshiProvider import im.vector.matrix.android.internal.legacy.util.JsonUtils +typealias Content = Map + @JsonClass(generateAdapter = true) data class Event( @Json(name = "type") val type: String, @Json(name = "event_id") val eventId: String?, - @Json(name = "content") val content: Map? = null, - @Json(name = "prev_content") val prevContent: Map? = null, + @Json(name = "content") val content: Content? = null, + @Json(name = "prev_content") val prevContent: Content? = null, @Json(name = "origin_server_ts") val originServerTs: Long? = null, @Json(name = "sender") val sender: String? = null, @Json(name = "state_key") val stateKey: String? = null, @@ -39,7 +41,7 @@ data class Event( return toModel(prevContent) } - inline fun toModel(data: Map?): T? { + inline fun toModel(data: Content?): T? { val moshi = MoshiProvider.providesMoshi() val moshiAdapter = moshi.adapter(T::class.java) return moshiAdapter.fromJsonValue(data) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt index ac58a11b..412131f1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/Room.kt @@ -5,7 +5,7 @@ import im.vector.matrix.android.api.session.room.model.MyMembership import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.util.Cancelable -interface Room : TimelineHolder { +interface Room : TimelineHolder, SendService { val roomId: String diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/SendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/SendService.kt new file mode 100644 index 00000000..d4b085cb --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/SendService.kt @@ -0,0 +1,10 @@ +package im.vector.matrix.android.api.session.room + +import im.vector.matrix.android.api.util.Cancelable + +interface SendService { + + fun sendTextMessage(text: String): Cancelable + + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt index c8bb8881..1388c141 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/DefaultRoom.kt @@ -7,6 +7,7 @@ import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.events.model.EnrichedEvent import im.vector.matrix.android.api.session.room.Room +import im.vector.matrix.android.api.session.room.SendService import im.vector.matrix.android.api.session.room.TimelineHolder import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.MyMembership @@ -28,11 +29,11 @@ internal data class DefaultRoom( override val myMembership: MyMembership ) : Room, KoinComponent { - private val loadRoomMembersRequest by inject() private val syncTokenStore by inject() private val monarchy by inject() private val timelineHolder by inject(parameters = { parametersOf(roomId) }) + private val sendService by inject(parameters = { parametersOf(roomId) }) override val roomSummary: LiveData by lazy { val liveData = monarchy @@ -66,4 +67,8 @@ internal data class DefaultRoom( } + override fun sendTextMessage(text: String): Cancelable { + return sendService.sendTextMessage(text) + } + } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt index 9b3d677e..655cd33d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomAPI.kt @@ -1,12 +1,14 @@ package im.vector.matrix.android.internal.session.room +import im.vector.matrix.android.api.session.room.model.MessageContent import im.vector.matrix.android.internal.network.NetworkConstants import im.vector.matrix.android.internal.session.room.members.RoomMembersResponse +import im.vector.matrix.android.internal.session.room.send.SendResponse import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEvent -import kotlinx.coroutines.Deferred import retrofit2.Call -import retrofit2.Response +import retrofit2.http.Body import retrofit2.http.GET +import retrofit2.http.PUT import retrofit2.http.Path import retrofit2.http.Query @@ -46,4 +48,20 @@ internal interface RoomAPI { ): Call + /** + * Send an event to a room. + * + * @param txId the transaction Id + * @param roomId the room id + * @param eventType the event type + * @param content the event content + */ + @PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "rooms/{roomId}/send/{eventType}/{txId}") + fun send(@Path("txId") txId: String, + @Path("roomId") roomId: String, + @Path("eventType") eventType: String, + @Body content: MessageContent + ): Call + + } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt index 6a5538b5..bfd9052e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/RoomModule.kt @@ -1,12 +1,13 @@ package im.vector.matrix.android.internal.session.room +import im.vector.matrix.android.api.session.room.SendService import im.vector.matrix.android.api.session.room.TimelineHolder import im.vector.matrix.android.internal.session.DefaultSession import im.vector.matrix.android.internal.session.room.members.LoadRoomMembersRequest +import im.vector.matrix.android.internal.session.room.send.DefaultSendService import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineHolder import im.vector.matrix.android.internal.session.room.timeline.PaginationRequest import im.vector.matrix.android.internal.session.room.timeline.TimelineBoundaryCallback -import org.koin.core.parameter.parametersOf import org.koin.dsl.context.ModuleDefinition import org.koin.dsl.module.Module import org.koin.dsl.module.module @@ -31,14 +32,16 @@ class RoomModule : Module { PaginationRequest(get(), get(), get(), get()) } + factory { val roomId: String = it[0] - TimelineBoundaryCallback(roomId, get(), get(), Executors.newSingleThreadExecutor()) + val timelineBoundaryCallback = TimelineBoundaryCallback(roomId, get(), get(), Executors.newSingleThreadExecutor()) + DefaultTimelineHolder(roomId, get(), timelineBoundaryCallback) as TimelineHolder } factory { val roomId: String = it[0] - DefaultTimelineHolder(roomId, get(), get(parameters = { parametersOf(roomId) })) as TimelineHolder + DefaultSendService(roomId) as SendService } }.invoke() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt new file mode 100644 index 00000000..347445ac --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt @@ -0,0 +1,45 @@ +package im.vector.matrix.android.internal.session.room.send + +import androidx.work.BackoffPolicy +import androidx.work.Constraints +import androidx.work.Data +import androidx.work.ExistingWorkPolicy +import androidx.work.NetworkType +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkManager +import im.vector.matrix.android.api.session.room.SendService +import im.vector.matrix.android.api.util.Cancelable +import im.vector.matrix.android.internal.util.CancelableWork +import java.util.concurrent.TimeUnit + +private const val SEND_WORK_NAME = "SEND_WORK_NAME" + +internal class DefaultSendService(private val roomId: String) : SendService { + + private val sendConstraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build() + + override fun sendTextMessage(text: String): Cancelable { + + val data = mapOf( + "roomId" to roomId, + "text" to text + ) + val workData = Data.Builder().putAll(data).build() + + val sendWork = OneTimeWorkRequestBuilder() + .setConstraints(sendConstraints) + .setInputData(workData) + .setBackoffCriteria(BackoffPolicy.LINEAR, 10_000, TimeUnit.MILLISECONDS) + .build() + + val work = WorkManager.getInstance() + .beginUniqueWork(SEND_WORK_NAME, ExistingWorkPolicy.APPEND, sendWork) + .enqueue() + + return CancelableWork(work) + + } + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendContentWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendContentWorker.kt new file mode 100644 index 00000000..1f972dfe --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendContentWorker.kt @@ -0,0 +1,37 @@ +package im.vector.matrix.android.internal.session.room.send + +import android.content.Context +import androidx.work.Worker +import androidx.work.WorkerParameters +import im.vector.matrix.android.api.session.events.model.EventType +import im.vector.matrix.android.api.session.room.model.MessageContent +import im.vector.matrix.android.api.session.room.model.MessageType +import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.session.room.RoomAPI +import org.koin.standalone.KoinComponent +import org.koin.standalone.inject + +internal class SendContentWorker(context: Context, params: WorkerParameters) + : Worker(context, params), KoinComponent { + + private val roomAPI by inject() + + override fun doWork(): Result { + + val roomId = inputData.getString("roomId") + val text = inputData.getString("text") + + val fakeId = roomId + "-" + System.currentTimeMillis() + + if (roomId == null || text == null) { + return Result.FAILURE + } + + val result = executeRequest { + apiCall = roomAPI.send(fakeId, roomId, EventType.MESSAGE, MessageContent(MessageType.MSGTYPE_TEXT, text)) + } + return result.fold({ Result.RETRY }, { Result.SUCCESS }) + } + + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendResponse.kt new file mode 100644 index 00000000..1f285797 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/SendResponse.kt @@ -0,0 +1,9 @@ +package im.vector.matrix.android.internal.session.room.send + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class SendResponse( + @Json(name = "event_id") val eventId: String +) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CancelableWork.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CancelableWork.kt new file mode 100644 index 00000000..d78f2045 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/CancelableWork.kt @@ -0,0 +1,13 @@ +package im.vector.matrix.android.internal.util + +import com.google.common.util.concurrent.ListenableFuture +import im.vector.matrix.android.api.util.Cancelable +import kotlinx.coroutines.Job + +internal class CancelableWork(private val work: ListenableFuture) : Cancelable { + + override fun cancel() { + work.cancel(true) + } + +} \ No newline at end of file