diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt index c97b38847..8b0029a17 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -28,6 +28,7 @@ import com.geeksville.mesh.database.entity.QuickChatAction import com.geeksville.mesh.repository.datastore.RadioConfigRepository import com.geeksville.mesh.repository.radio.RadioInterfaceService import com.geeksville.mesh.service.MeshService +import com.geeksville.mesh.service.ServiceAction import com.geeksville.mesh.ui.map.MAP_STYLE_ID import com.geeksville.mesh.util.positionToMeter import dagger.hilt.android.lifecycle.HiltViewModel @@ -383,6 +384,12 @@ class UIViewModel @Inject constructor( } } + fun sendTapback(emoji: String, replyId: Int, contactKey: String) { + viewModelScope.launch { + radioConfigRepository.onServiceAction(ServiceAction.Tapback(emoji, replyId, contactKey)) + } + } + fun requestTraceroute(destNum: Int) { info("Requesting traceroute for '$destNum'") try { diff --git a/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt index 36d6dbb65..7e0af44ce 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt @@ -16,6 +16,7 @@ import com.geeksville.mesh.deviceProfile import com.geeksville.mesh.model.NodeDB import com.geeksville.mesh.model.getChannelUrl import com.geeksville.mesh.service.MeshService.ConnectionState +import com.geeksville.mesh.service.ServiceAction import com.geeksville.mesh.service.ServiceRepository import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow @@ -177,6 +178,12 @@ class RadioConfigRepository @Inject constructor( serviceRepository.emitMeshPacket(packet) } + val serviceAction: SharedFlow get() = serviceRepository.serviceAction + + suspend fun onServiceAction(action: ServiceAction) = coroutineScope { + serviceRepository.onServiceAction(action) + } + val tracerouteResponse: StateFlow get() = serviceRepository.tracerouteResponse fun setTracerouteResponse(value: String?) { diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index a191f1258..9279c9614 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -58,6 +58,10 @@ import java.util.concurrent.TimeoutException import javax.inject.Inject import kotlin.math.absoluteValue +sealed class ServiceAction { + data class Tapback(val emoji: String, val replyId: Int, val contactKey: String) : ServiceAction() +} + /** * Handles all the communication with android apps. Also keeps an internal model * of the network state. @@ -279,6 +283,11 @@ class MeshService : Service(), Logging { .launchIn(serviceScope) radioConfigRepository.channelSetFlow.onEach { channelSet = it } .launchIn(serviceScope) + radioConfigRepository.serviceAction.onEach { action -> + when (action) { + is ServiceAction.Tapback -> sendTapback(action) + } + }.launchIn(serviceScope) loadSettings() // Load our last known node DB @@ -1724,6 +1733,21 @@ class MeshService : Service(), Logging { } } + private fun sendTapback(tapback: ServiceAction.Tapback) = toRemoteExceptions { + // contactKey: unique contact key filter (channel)+(nodeId) + val channel = tapback.contactKey[0].digitToInt() + val destNum = tapback.contactKey.substring(1) + + sendToRadio(newMeshPacketTo(destNum).buildMeshPacket( + channel = channel, + priority = MeshPacket.Priority.BACKGROUND, + ) { + replyId = tapback.replyId + portnumValue = Portnums.PortNum.TEXT_MESSAGE_APP_VALUE + payload = ByteString.copyFrom(tapback.emoji.encodeToByteArray()) + }) + } + private val binder = object : IMeshService.Stub() { override fun setDeviceAddress(deviceAddr: String?) = toRemoteExceptions { diff --git a/app/src/main/java/com/geeksville/mesh/service/ServiceRepository.kt b/app/src/main/java/com/geeksville/mesh/service/ServiceRepository.kt index c1fea6773..9ebe8b649 100644 --- a/app/src/main/java/com/geeksville/mesh/service/ServiceRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/service/ServiceRepository.kt @@ -68,4 +68,11 @@ class ServiceRepository @Inject constructor() : Logging { fun clearTracerouteResponse() { setTracerouteResponse(null) } + + private val _serviceAction = MutableSharedFlow() + val serviceAction: SharedFlow get() = _serviceAction + + suspend fun onServiceAction(action: ServiceAction) { + _serviceAction.emit(action) + } }