Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open watch app's Now Playing screen when tapping on episode screen's Play icon #990

Merged
merged 2 commits into from
May 24, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import au.com.shiftyjelly.pocketcasts.wear.ui.downloads.DownloadsScreen
import au.com.shiftyjelly.pocketcasts.wear.ui.episode.EpisodeScreenFlow
import au.com.shiftyjelly.pocketcasts.wear.ui.episode.EpisodeScreenFlow.episodeGraph
import au.com.shiftyjelly.pocketcasts.wear.ui.player.EffectsScreen
import au.com.shiftyjelly.pocketcasts.wear.ui.player.NowPlayingScreen
import au.com.shiftyjelly.pocketcasts.wear.ui.player.PCVolumeScreen
import au.com.shiftyjelly.pocketcasts.wear.ui.player.StreamingConfirmationScreen
import au.com.shiftyjelly.pocketcasts.wear.ui.podcast.PodcastScreen
Expand Down Expand Up @@ -120,7 +121,7 @@ fun WearApp(
navigateToRoute = navController::navigate,
toNowPlaying = {
coroutineScope.launch {
pagerState.animateScrollToPage(1)
pagerState.animateScrollToPage(NowPlayingScreen.pagerIndex)
}
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,16 @@ fun EpisodeScreen(
navigateToConfirmDeleteDownload: () -> Unit,
navigateToRemoveFromUpNextNotification: () -> Unit,
navigateToStreamingConfirmation: () -> Unit,
navigateToNowPlaying: () -> Unit,
) {

val viewModel = hiltViewModel<EpisodeViewModel>()
val state = viewModel.stateFlow.collectAsState().value
if (state !is EpisodeViewModel.State.Loaded) return

val showNowPlaying = viewModel.showNowPlaying.collectAsState(false).value
if (showNowPlaying) navigateToNowPlaying()

val episode = state.episode
val podcast = state.podcast
val context = LocalContext.current
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package au.com.shiftyjelly.pocketcasts.wear.ui.episode

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
Expand All @@ -18,11 +20,13 @@ import androidx.wear.compose.material.SwipeToDismissBoxState
import au.com.shiftyjelly.pocketcasts.wear.ui.component.NotificationScreen
import au.com.shiftyjelly.pocketcasts.wear.ui.component.NowPlayingPager
import au.com.shiftyjelly.pocketcasts.wear.ui.component.ObtainConfirmationScreen
import au.com.shiftyjelly.pocketcasts.wear.ui.player.NowPlayingScreen
import au.com.shiftyjelly.pocketcasts.wear.ui.player.StreamingConfirmationScreen
import com.google.android.horologist.compose.layout.ScalingLazyColumnDefaults
import com.google.android.horologist.compose.navscaffold.NavScaffoldViewModel
import com.google.android.horologist.compose.navscaffold.composable
import com.google.android.horologist.compose.navscaffold.scrollable
import kotlinx.coroutines.launch
import au.com.shiftyjelly.pocketcasts.localization.R as LR

object EpisodeScreenFlow {
Expand All @@ -37,6 +41,7 @@ object EpisodeScreenFlow {
private const val deleteDownloadNotificationScreen = "deleteDownloadNotificationScreen"
private const val removeFromUpNextNotificationScreen = "removeFromUpNextNotificationScreen"

@OptIn(ExperimentalFoundationApi::class)
fun NavGraphBuilder.episodeGraph(
navigateToPodcast: (podcastUuid: String) -> Unit,
navController: NavController,
Expand Down Expand Up @@ -71,9 +76,13 @@ object EpisodeScreenFlow {
}
}

val pagerState = rememberPagerState()
val coroutineScope = rememberCoroutineScope()

@OptIn(ExperimentalFoundationApi::class)
NowPlayingPager(
navController = navController,
pagerState = pagerState,
swipeToDismissState = swipeToDismissState,
scrollableScaffoldContext = it,
) {
Expand All @@ -90,6 +99,11 @@ object EpisodeScreenFlow {
navigateToStreamingConfirmation = {
navController.navigate(StreamingConfirmationScreen.route)
},
navigateToNowPlaying = {
coroutineScope.launch {
pagerState.animateScrollToPage(NowPlayingScreen.pagerIndex)
}
},
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import coil.request.SuccessResult
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
Expand Down Expand Up @@ -103,6 +104,8 @@ class EpisodeViewModel @Inject constructor(
)

val stateFlow: StateFlow<State>
var showNowPlaying = MutableSharedFlow<Boolean>()
private set
Copy link
Contributor

@mchowning mchowning May 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it might be worth adding a comment here noting that we're using a shared flow here because we need the event to only be sent one time and then discarded? Just to make it clear why we're not using a state flow like we normally do.

Also, the private set var on the mutable flow reads a bit odd to me because I read it as implying that we might want to switch out this flow for an entirely different flow. Maybe something like this would work instead and make it clearer that it's a single flow and we just want it to be updated from inside the view model.

val _showNowPlaying = MutableSharedFlow<Boolean>()
val showNowPlaying = _showNowPlaying.asSharedFlow()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense 👍
Addressed in bd5a809


init {
val episodeUuid = savedStateHandle.get<String>(EpisodeScreenFlow.episodeUuidArgument)
Expand Down Expand Up @@ -259,6 +262,7 @@ class EpisodeViewModel @Inject constructor(
episode = episode,
playbackSource = analyticsSource,
)
showNowPlaying.emit(true)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import au.com.shiftyjelly.pocketcasts.localization.R as LR

object NowPlayingScreen {
const val route = "now_playing"
const val pagerIndex = 1
}

@OptIn(ExperimentalWearFoundationApi::class)
Expand Down