Merge pull request #6539 from vector-im/bugfix/mna/lls-status-bar-disappearing
[Location Share] - Wrong room live location status bar visibility in timeline (PSG-625)
This commit is contained in:
commit
448b6e1c74
|
@ -0,0 +1 @@
|
||||||
|
[Location Share] - Wrong room live location status bar visibility in timeline
|
|
@ -84,6 +84,4 @@ sealed class RoomDetailViewEvents : VectorViewEvents {
|
||||||
data class StartChatEffect(val type: ChatEffect) : RoomDetailViewEvents()
|
data class StartChatEffect(val type: ChatEffect) : RoomDetailViewEvents()
|
||||||
object StopChatEffects : RoomDetailViewEvents()
|
object StopChatEffects : RoomDetailViewEvents()
|
||||||
object RoomReplacementStarted : RoomDetailViewEvents()
|
object RoomReplacementStarted : RoomDetailViewEvents()
|
||||||
|
|
||||||
data class ChangeLocationIndicator(val isVisible: Boolean) : RoomDetailViewEvents()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,8 @@ data class RoomDetailViewState(
|
||||||
val switchToParentSpace: Boolean = false,
|
val switchToParentSpace: Boolean = false,
|
||||||
val rootThreadEventId: String? = null,
|
val rootThreadEventId: String? = null,
|
||||||
val threadNotificationBadgeState: ThreadNotificationBadgeState = ThreadNotificationBadgeState(),
|
val threadNotificationBadgeState: ThreadNotificationBadgeState = ThreadNotificationBadgeState(),
|
||||||
val typingUsers: List<SenderInfo>? = null
|
val typingUsers: List<SenderInfo>? = null,
|
||||||
|
val isSharingLiveLocation: Boolean = false,
|
||||||
) : MavericksState {
|
) : MavericksState {
|
||||||
|
|
||||||
constructor(args: TimelineArgs) : this(
|
constructor(args: TimelineArgs) : this(
|
||||||
|
|
|
@ -498,7 +498,6 @@ class TimelineFragment @Inject constructor(
|
||||||
RoomDetailViewEvents.StopChatEffects -> handleStopChatEffects()
|
RoomDetailViewEvents.StopChatEffects -> handleStopChatEffects()
|
||||||
is RoomDetailViewEvents.DisplayAndAcceptCall -> acceptIncomingCall(it)
|
is RoomDetailViewEvents.DisplayAndAcceptCall -> acceptIncomingCall(it)
|
||||||
RoomDetailViewEvents.RoomReplacementStarted -> handleRoomReplacement()
|
RoomDetailViewEvents.RoomReplacementStarted -> handleRoomReplacement()
|
||||||
is RoomDetailViewEvents.ChangeLocationIndicator -> handleChangeLocationIndicator(it)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,10 +662,6 @@ class TimelineFragment @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleChangeLocationIndicator(event: RoomDetailViewEvents.ChangeLocationIndicator) {
|
|
||||||
views.locationLiveStatusIndicator.isVisible = event.isVisible
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun displayErrorMessage(error: RoomDetailViewEvents.Failure) {
|
private fun displayErrorMessage(error: RoomDetailViewEvents.Failure) {
|
||||||
if (error.showInDialog) displayErrorDialog(error.throwable) else showErrorInSnackbar(error.throwable)
|
if (error.showInDialog) displayErrorDialog(error.throwable) else showErrorInSnackbar(error.throwable)
|
||||||
}
|
}
|
||||||
|
@ -1686,6 +1681,11 @@ class TimelineFragment @Inject constructor(
|
||||||
} else if (mainState.asyncInviter.complete) {
|
} else if (mainState.asyncInviter.complete) {
|
||||||
vectorBaseActivity.finish()
|
vectorBaseActivity.finish()
|
||||||
}
|
}
|
||||||
|
updateLiveLocationIndicator(mainState.isSharingLiveLocation)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateLiveLocationIndicator(isSharingLiveLocation: Boolean) {
|
||||||
|
views.locationLiveStatusIndicator.isVisible = isSharingLiveLocation
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FragmentTimelineBinding.hideComposerViews() {
|
private fun FragmentTimelineBinding.hideComposerViews() {
|
||||||
|
@ -1706,7 +1706,7 @@ class TimelineFragment @Inject constructor(
|
||||||
|
|
||||||
private fun renderToolbar(roomSummary: RoomSummary?) {
|
private fun renderToolbar(roomSummary: RoomSummary?) {
|
||||||
when {
|
when {
|
||||||
isLocalRoom() -> {
|
isLocalRoom() -> {
|
||||||
views.includeRoomToolbar.roomToolbarContentView.isVisible = false
|
views.includeRoomToolbar.roomToolbarContentView.isVisible = false
|
||||||
views.includeThreadToolbar.roomToolbarThreadConstraintLayout.isVisible = false
|
views.includeThreadToolbar.roomToolbarThreadConstraintLayout.isVisible = false
|
||||||
setupToolbar(views.roomToolbar)
|
setupToolbar(views.roomToolbar)
|
||||||
|
@ -1724,7 +1724,7 @@ class TimelineFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
views.includeThreadToolbar.roomToolbarThreadTitleTextView.text = resources.getText(R.string.thread_timeline_title)
|
views.includeThreadToolbar.roomToolbarThreadTitleTextView.text = resources.getText(R.string.thread_timeline_title)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
views.includeRoomToolbar.roomToolbarContentView.isVisible = true
|
views.includeRoomToolbar.roomToolbarContentView.isVisible = true
|
||||||
views.includeThreadToolbar.roomToolbarThreadConstraintLayout.isVisible = false
|
views.includeThreadToolbar.roomToolbarThreadConstraintLayout.isVisible = false
|
||||||
if (roomSummary == null) {
|
if (roomSummary == null) {
|
||||||
|
|
|
@ -1303,12 +1303,12 @@ class TimelineViewModel @AssistedInject constructor(
|
||||||
_viewEvents.post(RoomDetailViewEvents.OnNewTimelineEvents(eventIds))
|
_viewEvents.post(RoomDetailViewEvents.OnNewTimelineEvents(eventIds))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLocationServiceRunning() {
|
override fun onLocationServiceRunning(roomIds: Set<String>) {
|
||||||
_viewEvents.post(RoomDetailViewEvents.ChangeLocationIndicator(isVisible = true))
|
setState { copy(isSharingLiveLocation = roomId in roomIds) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLocationServiceStopped() {
|
override fun onLocationServiceStopped() {
|
||||||
_viewEvents.post(RoomDetailViewEvents.ChangeLocationIndicator(isVisible = false))
|
setState { copy(isSharingLiveLocation = false) }
|
||||||
// Bind again in case user decides to share live location without leaving the room
|
// Bind again in case user decides to share live location without leaving the room
|
||||||
locationSharingServiceConnection.bind(this)
|
locationSharingServiceConnection.bind(this)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ import im.vector.app.features.redaction.CheckIfEventIsRedactedUseCase
|
||||||
import im.vector.app.features.session.coroutineScope
|
import im.vector.app.features.session.coroutineScope
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
import kotlinx.coroutines.flow.distinctUntilChangedBy
|
import kotlinx.coroutines.flow.distinctUntilChangedBy
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
@ -68,6 +70,9 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca
|
||||||
private val jobs = mutableListOf<Job>()
|
private val jobs = mutableListOf<Job>()
|
||||||
private var startInProgress = false
|
private var startInProgress = false
|
||||||
|
|
||||||
|
private val _roomIdsOfActiveLives = MutableSharedFlow<Set<String>>(replay = 1)
|
||||||
|
val roomIdsOfActiveLives = _roomIdsOfActiveLives.asSharedFlow()
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
Timber.i("onCreate")
|
Timber.i("onCreate")
|
||||||
|
@ -195,11 +200,13 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca
|
||||||
private fun addRoomArgs(beaconEventId: String, roomArgs: RoomArgs) {
|
private fun addRoomArgs(beaconEventId: String, roomArgs: RoomArgs) {
|
||||||
Timber.i("adding roomArgs for beaconEventId: $beaconEventId")
|
Timber.i("adding roomArgs for beaconEventId: $beaconEventId")
|
||||||
roomArgsMap[beaconEventId] = roomArgs
|
roomArgsMap[beaconEventId] = roomArgs
|
||||||
|
launchWithActiveSession { _roomIdsOfActiveLives.emit(getRoomIdsOfActiveLives()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeRoomArgs(beaconEventId: String) {
|
private fun removeRoomArgs(beaconEventId: String) {
|
||||||
Timber.i("removing roomArgs for beaconEventId: $beaconEventId")
|
Timber.i("removing roomArgs for beaconEventId: $beaconEventId")
|
||||||
roomArgsMap.remove(beaconEventId)
|
roomArgsMap.remove(beaconEventId)
|
||||||
|
launchWithActiveSession { _roomIdsOfActiveLives.emit(getRoomIdsOfActiveLives()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun listenForLiveSummaryChanges(roomId: String, beaconEventId: String) {
|
private fun listenForLiveSummaryChanges(roomId: String, beaconEventId: String) {
|
||||||
|
@ -226,6 +233,10 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getRoomIdsOfActiveLives(): Set<String> {
|
||||||
|
return roomArgsMap.map { it.value.roomId }.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent?): IBinder {
|
override fun onBind(intent: Intent?): IBinder {
|
||||||
return binder
|
return binder
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,17 +21,22 @@ import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import im.vector.app.features.session.coroutineScope
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class LocationSharingServiceConnection @Inject constructor(
|
class LocationSharingServiceConnection @Inject constructor(
|
||||||
private val context: Context
|
private val context: Context,
|
||||||
) : ServiceConnection,
|
private val activeSessionHolder: ActiveSessionHolder
|
||||||
LocationSharingAndroidService.Callback {
|
) : ServiceConnection, LocationSharingAndroidService.Callback {
|
||||||
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
fun onLocationServiceRunning()
|
fun onLocationServiceRunning(roomIds: Set<String>)
|
||||||
fun onLocationServiceStopped()
|
fun onLocationServiceStopped()
|
||||||
fun onLocationServiceError(error: Throwable)
|
fun onLocationServiceError(error: Throwable)
|
||||||
}
|
}
|
||||||
|
@ -44,7 +49,7 @@ class LocationSharingServiceConnection @Inject constructor(
|
||||||
addCallback(callback)
|
addCallback(callback)
|
||||||
|
|
||||||
if (isBound) {
|
if (isBound) {
|
||||||
callback.onLocationServiceRunning()
|
callback.onLocationServiceRunning(getRoomIdsOfActiveLives())
|
||||||
} else {
|
} else {
|
||||||
Intent(context, LocationSharingAndroidService::class.java).also { intent ->
|
Intent(context, LocationSharingAndroidService::class.java).also { intent ->
|
||||||
context.bindService(intent, this, 0)
|
context.bindService(intent, this, 0)
|
||||||
|
@ -56,12 +61,24 @@ class LocationSharingServiceConnection @Inject constructor(
|
||||||
removeCallback(callback)
|
removeCallback(callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getRoomIdsOfActiveLives(): Set<String> {
|
||||||
|
return locationSharingAndroidService?.getRoomIdsOfActiveLives() ?: emptySet()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onServiceConnected(className: ComponentName, binder: IBinder) {
|
override fun onServiceConnected(className: ComponentName, binder: IBinder) {
|
||||||
locationSharingAndroidService = (binder as LocationSharingAndroidService.LocalBinder).getService().also {
|
locationSharingAndroidService = (binder as LocationSharingAndroidService.LocalBinder).getService().also { service ->
|
||||||
it.callback = this
|
service.callback = this
|
||||||
|
getActiveSessionCoroutineScope()?.let { scope ->
|
||||||
|
service.roomIdsOfActiveLives
|
||||||
|
.onEach(::onRoomIdsUpdate)
|
||||||
|
.launchIn(scope)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isBound = true
|
isBound = true
|
||||||
onCallbackActionNoArg(Callback::onLocationServiceRunning)
|
}
|
||||||
|
|
||||||
|
private fun getActiveSessionCoroutineScope(): CoroutineScope? {
|
||||||
|
return activeSessionHolder.getSafeActiveSession()?.coroutineScope
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceDisconnected(className: ComponentName) {
|
override fun onServiceDisconnected(className: ComponentName) {
|
||||||
|
@ -71,6 +88,10 @@ class LocationSharingServiceConnection @Inject constructor(
|
||||||
onCallbackActionNoArg(Callback::onLocationServiceStopped)
|
onCallbackActionNoArg(Callback::onLocationServiceStopped)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onRoomIdsUpdate(roomIds: Set<String>) {
|
||||||
|
forwardRoomIdsToCallbacks(roomIds)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onServiceError(error: Throwable) {
|
override fun onServiceError(error: Throwable) {
|
||||||
forwardErrorToCallbacks(error)
|
forwardErrorToCallbacks(error)
|
||||||
}
|
}
|
||||||
|
@ -87,6 +108,10 @@ class LocationSharingServiceConnection @Inject constructor(
|
||||||
callbacks.toList().forEach(action)
|
callbacks.toList().forEach(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun forwardRoomIdsToCallbacks(roomIds: Set<String>) {
|
||||||
|
callbacks.toList().forEach { it.onLocationServiceRunning(roomIds) }
|
||||||
|
}
|
||||||
|
|
||||||
private fun forwardErrorToCallbacks(error: Throwable) {
|
private fun forwardErrorToCallbacks(error: Throwable) {
|
||||||
callbacks.toList().forEach { it.onLocationServiceError(error) }
|
callbacks.toList().forEach { it.onLocationServiceError(error) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ class LocationLiveMapViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLocationServiceRunning() {
|
override fun onLocationServiceRunning(roomIds: Set<String>) {
|
||||||
// NOOP
|
// NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue