Skip to content

Commit c599b2b

Browse files
authored
[Jetcaster] Wear - adds navigation to player, cleanup (#1316)
- Adds navigation to Player from latest episodes and setting the URI via EpisodePlayer - Cleanup - Restructured the Dialog for when the content is empty
2 parents 4f1815c + 71d7dce commit c599b2b

File tree

10 files changed

+349
-316
lines changed

10 files changed

+349
-316
lines changed

Jetcaster/core/src/main/java/com/example/jetcaster/core/data/model/PlayerEpisode.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ data class PlayerEpisode(
3030
val author: String = "",
3131
val summary: String = "",
3232
val podcastImageUrl: String = "",
33+
val uri: String = ""
3334
) {
3435
constructor(podcastInfo: PodcastInfo, episodeInfo: EpisodeInfo) : this(
3536
title = episodeInfo.title,
@@ -39,6 +40,7 @@ data class PlayerEpisode(
3940
author = episodeInfo.author,
4041
summary = episodeInfo.summary,
4142
podcastImageUrl = podcastInfo.imageUrl,
43+
uri = episodeInfo.uri
4244
)
4345
}
4446

@@ -49,4 +51,5 @@ fun EpisodeToPodcast.toPlayerEpisode(): PlayerEpisode =
4951
podcastName = podcast.title,
5052
summary = episode.summary ?: "",
5153
podcastImageUrl = podcast.imageUrl ?: "",
54+
uri = episode.uri
5255
)

Jetcaster/wear/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ android {
5555
}
5656
kotlinOptions {
5757
jvmTarget = JavaVersion.VERSION_17.majorVersion
58+
freeCompilerArgs = freeCompilerArgs + "-opt-in=kotlin.RequiresOptIn"
59+
freeCompilerArgs = freeCompilerArgs + "-opt-in=com.google.android.horologist.annotations.ExperimentalHorologistApi"
5860
}
5961
buildFeatures {
6062
compose true

Jetcaster/wear/src/main/java/com/example/jetcaster/MainActivity.kt

Lines changed: 1 addition & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -14,113 +14,22 @@
1414
* limitations under the License.
1515
*/
1616

17-
@file:OptIn(ExperimentalHorologistApi::class, ExperimentalWearFoundationApi::class)
18-
1917
package com.example.jetcaster
2018

2119
import android.os.Bundle
2220
import androidx.activity.ComponentActivity
2321
import androidx.activity.compose.setContent
24-
import androidx.compose.foundation.layout.fillMaxSize
25-
import androidx.compose.runtime.Composable
26-
import androidx.compose.ui.Modifier
27-
import androidx.compose.ui.res.stringResource
2822
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
29-
import androidx.lifecycle.viewmodel.compose.viewModel
30-
import androidx.wear.compose.foundation.ExperimentalWearFoundationApi
31-
import androidx.wear.compose.material.TimeText
32-
import androidx.wear.compose.navigation.composable
33-
import androidx.wear.compose.navigation.rememberSwipeDismissableNavController
34-
import androidx.wear.compose.navigation.rememberSwipeDismissableNavHostState
35-
import com.example.jetcaster.theme.WearAppTheme
36-
import com.example.jetcaster.ui.JetcasterNavController.navigateToLatestEpisode
37-
import com.example.jetcaster.ui.JetcasterNavController.navigateToUpNext
38-
import com.example.jetcaster.ui.JetcasterNavController.navigateToYourPodcast
39-
import com.example.jetcaster.ui.LatestEpisodes
40-
import com.example.jetcaster.ui.home.HomeScreen
41-
import com.example.jetcaster.ui.library.LatestEpisodesScreen
42-
import com.example.jetcaster.ui.player.PlayerScreen
43-
import com.google.android.horologist.annotations.ExperimentalHorologistApi
44-
import com.google.android.horologist.audio.ui.VolumeViewModel
45-
import com.google.android.horologist.compose.layout.ScreenScaffold
46-
import com.google.android.horologist.compose.layout.rememberColumnState
47-
import com.google.android.horologist.media.ui.navigation.MediaNavController.navigateToVolume
48-
import com.google.android.horologist.media.ui.navigation.MediaPlayerScaffold
49-
import com.google.android.horologist.media.ui.snackbar.SnackbarManager
50-
import com.google.android.horologist.media.ui.snackbar.SnackbarViewModel
5123
import dagger.hilt.android.AndroidEntryPoint
5224

5325
@AndroidEntryPoint
5426
class MainActivity : ComponentActivity() {
5527
override fun onCreate(savedInstanceState: Bundle?) {
28+
installSplashScreen()
5629
super.onCreate(savedInstanceState)
5730

5831
setContent {
59-
installSplashScreen()
6032
WearApp()
6133
}
6234
}
6335
}
64-
65-
@OptIn(ExperimentalHorologistApi::class)
66-
@Composable
67-
fun WearApp() {
68-
69-
val navController = rememberSwipeDismissableNavController()
70-
val navHostState = rememberSwipeDismissableNavHostState()
71-
val volumeViewModel: VolumeViewModel = viewModel(factory = VolumeViewModel.Factory)
72-
val snackBarManager: SnackbarManager = SnackbarManager()
73-
val snackbarViewModel: SnackbarViewModel = SnackbarViewModel(snackBarManager)
74-
75-
WearAppTheme {
76-
MediaPlayerScaffold(
77-
playerScreen = {
78-
PlayerScreen(
79-
modifier = Modifier.fillMaxSize(),
80-
volumeViewModel = volumeViewModel,
81-
onVolumeClick = {
82-
navController.navigateToVolume()
83-
},
84-
)
85-
},
86-
libraryScreen = {
87-
HomeScreen(
88-
onLatestEpisodeClick = { navController.navigateToLatestEpisode() },
89-
onYourPodcastClick = { navController.navigateToYourPodcast() },
90-
onUpNextClick = { navController.navigateToUpNext() },
91-
onErrorDialogCancelClick = { navController.popBackStack() }
92-
)
93-
},
94-
categoryEntityScreen = { _, _ -> },
95-
mediaEntityScreen = {},
96-
playlistsScreen = {},
97-
settingsScreen = {},
98-
99-
navHostState = navHostState,
100-
snackbarViewModel = snackbarViewModel,
101-
volumeViewModel = volumeViewModel,
102-
timeText = {
103-
TimeText()
104-
},
105-
deepLinkPrefix = "",
106-
navController = navController,
107-
additionalNavRoutes = {
108-
composable(
109-
route = LatestEpisodes.navRoute,
110-
) {
111-
val columnState = rememberColumnState()
112-
113-
ScreenScaffold(scrollState = columnState) {
114-
LatestEpisodesScreen(
115-
columnState = columnState,
116-
playlistName = stringResource(id = R.string.latest_episodes),
117-
onShuffleButtonClick = {},
118-
onPlayButtonClick = {}
119-
)
120-
}
121-
}
122-
},
123-
124-
)
125-
}
126-
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright 2024 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.jetcaster
18+
19+
/*
20+
* Copyright 2022 The Android Open Source Project
21+
*
22+
* Licensed under the Apache License, Version 2.0 (the "License");
23+
* you may not use this file except in compliance with the License.
24+
* You may obtain a copy of the License at
25+
*
26+
* https://www.apache.org/licenses/LICENSE-2.0
27+
*
28+
* Unless required by applicable law or agreed to in writing, software
29+
* distributed under the License is distributed on an "AS IS" BASIS,
30+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31+
* See the License for the specific language governing permissions and
32+
* limitations under the License.
33+
*/
34+
35+
import androidx.compose.foundation.layout.fillMaxSize
36+
import androidx.compose.runtime.Composable
37+
import androidx.compose.ui.Modifier
38+
import androidx.compose.ui.res.stringResource
39+
import androidx.lifecycle.viewmodel.compose.viewModel
40+
import androidx.wear.compose.navigation.composable
41+
import androidx.wear.compose.navigation.rememberSwipeDismissableNavController
42+
import androidx.wear.compose.navigation.rememberSwipeDismissableNavHostState
43+
import com.example.jetcaster.theme.WearAppTheme
44+
import com.example.jetcaster.ui.JetcasterNavController.navigateToLatestEpisode
45+
import com.example.jetcaster.ui.JetcasterNavController.navigateToUpNext
46+
import com.example.jetcaster.ui.JetcasterNavController.navigateToYourPodcast
47+
import com.example.jetcaster.ui.LatestEpisodes
48+
import com.example.jetcaster.ui.home.HomeScreen
49+
import com.example.jetcaster.ui.library.LatestEpisodesScreen
50+
import com.example.jetcaster.ui.player.PlayerScreen
51+
import com.google.android.horologist.audio.ui.VolumeViewModel
52+
import com.google.android.horologist.media.ui.navigation.MediaNavController.navigateToPlayer
53+
import com.google.android.horologist.media.ui.navigation.MediaNavController.navigateToVolume
54+
import com.google.android.horologist.media.ui.navigation.MediaPlayerScaffold
55+
import com.google.android.horologist.media.ui.snackbar.SnackbarManager
56+
import com.google.android.horologist.media.ui.snackbar.SnackbarViewModel
57+
58+
@Composable
59+
fun WearApp() {
60+
61+
val navController = rememberSwipeDismissableNavController()
62+
val navHostState = rememberSwipeDismissableNavHostState()
63+
val volumeViewModel: VolumeViewModel = viewModel(factory = VolumeViewModel.Factory)
64+
65+
// TODO remove from MediaPlayerScaffold
66+
val snackBarManager: SnackbarManager = SnackbarManager()
67+
val snackbarViewModel: SnackbarViewModel = SnackbarViewModel(snackBarManager)
68+
69+
WearAppTheme {
70+
MediaPlayerScaffold(
71+
playerScreen = {
72+
PlayerScreen(
73+
modifier = Modifier.fillMaxSize(),
74+
volumeViewModel = volumeViewModel,
75+
onVolumeClick = {
76+
navController.navigateToVolume()
77+
},
78+
)
79+
},
80+
libraryScreen = {
81+
HomeScreen(
82+
onLatestEpisodeClick = { navController.navigateToLatestEpisode() },
83+
onYourPodcastClick = { navController.navigateToYourPodcast() },
84+
onUpNextClick = { navController.navigateToUpNext() }
85+
)
86+
},
87+
categoryEntityScreen = { _, _ -> },
88+
mediaEntityScreen = {},
89+
playlistsScreen = {},
90+
settingsScreen = {},
91+
92+
navHostState = navHostState,
93+
snackbarViewModel = snackbarViewModel,
94+
volumeViewModel = volumeViewModel,
95+
deepLinkPrefix = "",
96+
navController = navController,
97+
additionalNavRoutes = {
98+
composable(
99+
route = LatestEpisodes.navRoute,
100+
) {
101+
LatestEpisodesScreen(
102+
playlistName = stringResource(id = R.string.latest_episodes),
103+
onShuffleButtonClick = {
104+
// navController.navigateToPlayer(it[0].episode.uri)
105+
},
106+
onPlayButtonClick = {
107+
navController.navigateToPlayer()
108+
}
109+
)
110+
}
111+
},
112+
113+
)
114+
}
115+
}

0 commit comments

Comments
 (0)