Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f42aa0cd authored by Anton Potapov's avatar Anton Potapov Committed by Android (Google) Code Review
Browse files

Merge "Add loading state in the MediaOutputViewModel" into main

parents fd48e3a8 0a6fe047
Loading
Loading
Loading
Loading
+24 −10
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor
import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor
import com.android.systemui.volume.panel.component.mediaoutput.shared.model.SessionWithPlayback
import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
import com.android.systemui.volume.panel.shared.model.Result
import com.android.systemui.volume.panel.ui.VolumePanelUiEvent
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -34,6 +35,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
@@ -53,32 +55,40 @@ constructor(
    private val uiEventLogger: UiEventLogger,
) {

    private val sessionWithPlayback: StateFlow<SessionWithPlayback?> =
    private val sessionWithPlayback: StateFlow<Result<SessionWithPlayback?>> =
        interactor.defaultActiveMediaSession
            .flatMapLatest { session ->
                if (session == null) {
                    flowOf(null)
                    flowOf(Result.Data<SessionWithPlayback?>(null))
                } else {
                    mediaDeviceSessionInteractor.playbackState(session).map { playback ->
                        playback?.let { SessionWithPlayback(session, it) }
                    mediaDeviceSessionInteractor
                        .playbackState(session)
                        .map { playback ->
                            playback?.let {
                                Result.Data<SessionWithPlayback?>(SessionWithPlayback(session, it))
                            }
                        }
                        .filterNotNull()
                }
            }
            .stateIn(
                coroutineScope,
                SharingStarted.Eagerly,
                null,
                Result.Loading(),
            )

    val connectedDeviceViewModel: StateFlow<ConnectedDeviceViewModel?> =
        combine(sessionWithPlayback, interactor.currentConnectedDevice) {
                mediaDeviceSession,
                currentConnectedDevice ->
                if (mediaDeviceSession !is Result.Data) {
                    return@combine null
                }
                ConnectedDeviceViewModel(
                    if (mediaDeviceSession?.playback?.isActive == true) {
                    if (mediaDeviceSession.data?.playback?.isActive == true) {
                        context.getString(
                            R.string.media_output_label_title,
                            mediaDeviceSession.session.appLabel
                            mediaDeviceSession.data.session.appLabel
                        )
                    } else {
                        context.getString(R.string.media_output_title_without_playing)
@@ -96,7 +106,10 @@ constructor(
        combine(sessionWithPlayback, interactor.currentConnectedDevice) {
                mediaDeviceSession,
                currentConnectedDevice ->
                if (mediaDeviceSession?.playback?.isActive == true) {
                if (mediaDeviceSession !is Result.Data) {
                    return@combine null
                }
                if (mediaDeviceSession.data?.playback?.isActive == true) {
                    val icon =
                        currentConnectedDevice?.icon?.let { Icon.Loaded(it, null) }
                            ?: Icon.Resource(
@@ -130,6 +143,7 @@ constructor(

    fun onBarClick(expandable: Expandable) {
        uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_MEDIA_OUTPUT_CLICKED)
        actionsInteractor.onBarClick(sessionWithPlayback.value, expandable)
        val result = sessionWithPlayback.value
        actionsInteractor.onBarClick((result as? Result.Data)?.data, expandable)
    }
}
+27 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.volume.panel.shared.model

/** Models a loadable result */
sealed interface Result<T> {

    /** The data is still loading */
    class Loading<T> : Result<T>

    /** The data is loaded successfully */
    data class Data<T>(val data: T) : Result<T>
}