diff --git a/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt b/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt index 7fb1356..0758c2c 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/MainActivity.kt @@ -1,6 +1,7 @@ package com.owenlejeune.tvtime import android.os.Bundle +import android.widget.Toast import androidx.activity.compose.setContent import androidx.compose.animation.rememberSplineBasedDecay import androidx.compose.foundation.layout.* @@ -70,9 +71,14 @@ class MainActivity : MonetCompatActivity() { setContent { AppKeyboardFocusManager() TVTimeTheme(monetCompat = monet) { + val windowSize = rememberWindowSizeClass() val appNavController = rememberNavController() Box { - MainNavigationRoutes(appNavController = appNavController, mainNavStartRoute = mainNavStartRoute) + MainNavigationRoutes( + appNavController = appNavController, + mainNavStartRoute = mainNavStartRoute, + windowSize = windowSize + ) } } } @@ -83,10 +89,9 @@ class MainActivity : MonetCompatActivity() { private fun AppScaffold( appNavController: NavHostController, mainNavStartRoute: String = BottomNavItem.SortedItems[0].route, + windowSize: WindowSizeClass, preferences: AppPreferences = get(AppPreferences::class.java) ) { - val windowSize = rememberWindowSizeClass() - val navController = rememberNavController() val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route @@ -363,11 +368,16 @@ class MainActivity : MonetCompatActivity() { startDestination: String = MainNavItem.MainView.route, mainNavStartRoute: String = MainNavItem.Items[0].route, appNavController: NavHostController, + windowSize: WindowSizeClass, preferences: AppPreferences = get(AppPreferences::class.java) ) { NavHost(navController = appNavController, startDestination = startDestination) { composable(MainNavItem.MainView.route) { - AppScaffold(appNavController = appNavController, mainNavStartRoute = mainNavStartRoute) + AppScaffold( + appNavController = appNavController, + mainNavStartRoute = mainNavStartRoute, + windowSize = windowSize + ) } composable( MainNavItem.DetailView.route.plus("/{${NavConstants.TYPE_KEY}}/{${NavConstants.ID_KEY}}"), @@ -378,17 +388,27 @@ class MainActivity : MonetCompatActivity() { ) { navBackStackEntry -> val args = navBackStackEntry.arguments val mediaType = args?.getSerializable(NavConstants.TYPE_KEY) as MediaViewType - if (mediaType != MediaViewType.PERSON) { - MediaDetailView( - appNavController = appNavController, - itemId = args.getInt(NavConstants.ID_KEY), - type = mediaType - ) - } else { - PersonDetailView( - appNavController = appNavController, - personId = args.getInt(NavConstants.ID_KEY) - ) + + when (mediaType) { + MediaViewType.PERSON -> { + PersonDetailView( + appNavController = appNavController, + personId = args.getInt(NavConstants.ID_KEY) + ) + } + MediaViewType.LIST -> { + LocalContext.current.let { + Toast.makeText(it, "It's a list!", Toast.LENGTH_SHORT).show() + } + } + else -> { + MediaDetailView( + appNavController = appNavController, + itemId = args.getInt(NavConstants.ID_KEY), + type = mediaType, + windowSize = windowSize + ) + } } } composable( diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/AccountV4Api.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/AccountV4Api.kt index 99ab459..367fdc3 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/AccountV4Api.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/AccountV4Api.kt @@ -9,34 +9,35 @@ import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4RatedTv import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Path +import retrofit2.http.Query interface AccountV4Api { @GET("account/{account_id}/lists") - suspend fun getLists(@Path("account_id") accountId: String, page: Int = 1): Response> + suspend fun getLists(@Path("account_id") accountId: String, @Query("page") page: Int = 1): Response> @GET("account/{account_id}/movie/favorites") - suspend fun getFavoriteMovies(@Path("account_id") accountId: String, page: Int = 1): Response> + suspend fun getFavoriteMovies(@Path("account_id") accountId: String, @Query("page") page: Int = 1): Response> @GET("account/{account_id}/tv/favorites") - suspend fun getFavoriteTvShows(@Path("account_id") accountId: String, page: Int = 1): Response> + suspend fun getFavoriteTvShows(@Path("account_id") accountId: String, @Query("page") page: Int = 1): Response> @GET("account/{account_id}/movie/recommendations") - suspend fun getMovieRecommendations(@Path("account_id") accountId: String, page: Int = 1): Response> + suspend fun getMovieRecommendations(@Path("account_id") accountId: String, @Query("page") page: Int = 1): Response> @GET("account/{account_id}/tv/recommendations") - suspend fun getTvShowRecommendations(@Path("account_id") accountId: String, page: Int = 1): Response> + suspend fun getTvShowRecommendations(@Path("account_id") accountId: String, @Query("page") page: Int = 1): Response> @GET("account/{account_id}/movie/watchlist") - suspend fun getMovieWatchlist(@Path("account_id") accountId: String, page: Int = 1): Response> + suspend fun getMovieWatchlist(@Path("account_id") accountId: String, @Query("page") page: Int = 1): Response> @GET("account/{account_id}/tv/watchlist") - suspend fun getTvShowWatchlist(@Path("account_id") accountId: String, page: Int = 1): Response> + suspend fun getTvShowWatchlist(@Path("account_id") accountId: String, @Query("page") page: Int = 1): Response> @GET("account/{account_id}/movie/rated") - suspend fun getRatedMovies(@Path("account_id") accountId: String, page: Int = 1): Response> + suspend fun getRatedMovies(@Path("account_id") accountId: String, @Query("page") page: Int = 1): Response> @GET("account/{account_id}/tv/rated") - suspend fun getRatedTvShows(@Path("account_id") accountId: String, page: Int = 1): Response> + suspend fun getRatedTvShows(@Path("account_id") accountId: String, @Query("page") page: Int = 1): Response> } \ No newline at end of file diff --git a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Service.kt b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Service.kt index 55f7356..c05a5fd 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Service.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/api/tmdb/api/v4/ListV4Service.kt @@ -8,7 +8,7 @@ class ListV4Service { private val service by lazy { TmdbClient().createV4ListService() } - suspend fun getLists(listId: Int, apiKey: String, page: Int = 1): Response { + suspend fun getList(listId: Int, apiKey: String, page: Int = 1): Response { return service.getList(listId, apiKey, page) } diff --git a/app/src/main/java/com/owenlejeune/tvtime/di/modules/modules.kt b/app/src/main/java/com/owenlejeune/tvtime/di/modules/modules.kt index 78d91bb..b53cf13 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/di/modules/modules.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/di/modules/modules.kt @@ -6,10 +6,12 @@ import com.google.gson.JsonDeserializer import com.owenlejeune.tvtime.BuildConfig import com.owenlejeune.tvtime.api.* import com.owenlejeune.tvtime.api.tmdb.TmdbClient +import com.owenlejeune.tvtime.api.tmdb.api.v3.AccountService import com.owenlejeune.tvtime.api.tmdb.api.v3.deserializer.KnownForDeserializer import com.owenlejeune.tvtime.api.tmdb.api.v3.deserializer.SortableSearchResultDeserializer import com.owenlejeune.tvtime.api.tmdb.api.v3.model.KnownFor import com.owenlejeune.tvtime.api.tmdb.api.v3.model.SortableSearchResult +import com.owenlejeune.tvtime.api.tmdb.api.v4.AccountV4Service import com.owenlejeune.tvtime.api.tmdb.api.v4.deserializer.ListItemDeserializer import com.owenlejeune.tvtime.api.tmdb.api.v4.model.ListItem import com.owenlejeune.tvtime.preferences.AppPreferences @@ -33,6 +35,9 @@ val networkModule = module { single { get().createSearchService() } single { get().createTvService() } + single { AccountService() } + single { AccountV4Service() } + single, JsonDeserializer<*>>> { mapOf( ListItem::class.java to ListItemDeserializer(), diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AccountTabNavItem.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AccountTabNavItem.kt index acc2972..af7e7a4 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AccountTabNavItem.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/navigation/AccountTabNavItem.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable import androidx.navigation.NavHostController import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.api.tmdb.api.v3.model.* +import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4AccountList import com.owenlejeune.tvtime.ui.screens.main.MediaViewType import com.owenlejeune.tvtime.ui.screens.main.AccountTabContent import com.owenlejeune.tvtime.utils.ResourceUtils @@ -31,7 +32,10 @@ sealed class AccountTabNavItem( get() = listOf(RatedMovies, RatedTvShows, RatedTvEpisodes) val AuthorizedItems - get() = listOf(RatedMovies, RatedTvShows, RatedTvEpisodes, FavoriteMovies, FavoriteTvShows, MovieWatchlist, TvWatchlist).filter { it.ordinal > -1 }.sortedBy { it.ordinal } + get() = listOf( + RatedMovies, RatedTvShows, RatedTvEpisodes, FavoriteMovies, FavoriteTvShows, + MovieWatchlist, TvWatchlist, UserLists + ).filter { it.ordinal > -1 }.sortedBy { it.ordinal } } object RatedMovies: AccountTabNavItem( @@ -39,7 +43,8 @@ sealed class AccountTabNavItem( "rated_movies_route", R.string.no_rated_movies, MediaViewType.MOVIE, - screenContent, { SessionManager.currentSession?.ratedMovies ?: emptyList() }, + screenContent, + { SessionManager.currentSession?.ratedMovies ?: emptyList() }, RatedMovie::class, 0 ) @@ -48,7 +53,8 @@ sealed class AccountTabNavItem( "rated_shows_route", R.string.no_rated_tv, MediaViewType.TV, - screenContent, { SessionManager.currentSession?.ratedTvShows ?: emptyList() }, + screenContent, + { SessionManager.currentSession?.ratedTvShows ?: emptyList() }, RatedTv::class, 1 ) @@ -57,16 +63,18 @@ sealed class AccountTabNavItem( "rated_episodes_route", R.string.no_rated_episodes, MediaViewType.EPISODE, - screenContent, { SessionManager.currentSession?.ratedTvEpisodes ?: emptyList() }, + screenContent, + { SessionManager.currentSession?.ratedTvEpisodes ?: emptyList() }, RatedEpisode::class, - 2 + -1 //2 ) object FavoriteMovies: AccountTabNavItem( R.string.nav_favorite_movies_title, "favorite_movies_route", R.string.no_favorite_movies, MediaViewType.MOVIE, - screenContent, { SessionManager.currentSession?.favoriteMovies ?: emptyList() }, + screenContent, + { SessionManager.currentSession?.favoriteMovies ?: emptyList() }, FavoriteMovie::class, 3 ) @@ -75,7 +83,8 @@ sealed class AccountTabNavItem( "favorite_shows_route", R.string.no_favorite_tv, MediaViewType.TV, - screenContent, { SessionManager.currentSession?.favoriteTvShows ?: emptyList() }, + screenContent, + { SessionManager.currentSession?.favoriteTvShows ?: emptyList() }, FavoriteTvSeries::class, 4 ) @@ -84,7 +93,8 @@ sealed class AccountTabNavItem( "movie_watchlist_route", R.string.no_watchlist_movies, MediaViewType.MOVIE, - screenContent, { SessionManager.currentSession?.movieWatchlist ?: emptyList() }, + screenContent, + { SessionManager.currentSession?.movieWatchlist ?: emptyList() }, WatchlistMovie::class, 5 ) @@ -93,10 +103,22 @@ sealed class AccountTabNavItem( "tv_watchlist_route", R.string.no_watchlist_tv, MediaViewType.TV, - screenContent, { SessionManager.currentSession?.tvWatchlist ?: emptyList() }, + screenContent, + { SessionManager.currentSession?.tvWatchlist ?: emptyList() }, WatchlistTvSeries::class, 6 ) + + object UserLists: AccountTabNavItem( + R.string.nav_user_lists_title, + "user_lists_route", + R.string.no_lists, + MediaViewType.LIST, + screenContent, + { SessionManager.currentSession?.accountLists ?: emptyList() }, + V4AccountList::class, + 0//7 + ) } private val screenContent: AccountNavComposableFun = { noContentText, appNavController, mediaViewType, listFetchFun, clazz -> diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt index 0a569c9..3a4d7b0 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/AccountTab.kt @@ -37,6 +37,8 @@ import com.google.accompanist.pager.PagerState import com.google.accompanist.pager.rememberPagerState import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.api.tmdb.api.v3.model.* +import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4AccountList +import com.owenlejeune.tvtime.extensions.unlessEmpty import com.owenlejeune.tvtime.preferences.AppPreferences import com.owenlejeune.tvtime.ui.components.RoundedLetterImage import com.owenlejeune.tvtime.ui.components.SignInDialog @@ -238,6 +240,19 @@ fun AccountTabContent( description = item.overview ) } + V4AccountList::class -> { + val item = contentItems[i] as V4AccountList + MediaItemRow( + appNavController = appNavController, + mediaViewType = mediaViewType, + id = item.id, + name = item.name, + date = item.createdAt, + description = item.description.unlessEmpty(stringResource(R.string.no_description_provided)), + posterPath = TmdbUtils.getFullPosterPath(item.posterPath), + backdropPath = TmdbUtils.getFullBackdropPath(item.backdropPath) + ) + } } } } diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaDetailView.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaDetailView.kt index f151461..15ad4e4 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaDetailView.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaDetailView.kt @@ -36,6 +36,7 @@ import com.owenlejeune.tvtime.api.tmdb.api.v3.DetailService import com.owenlejeune.tvtime.api.tmdb.api.v3.MoviesService import com.owenlejeune.tvtime.api.tmdb.api.v3.TvService import com.owenlejeune.tvtime.api.tmdb.api.v3.model.* +import com.owenlejeune.tvtime.extensions.WindowSizeClass import com.owenlejeune.tvtime.extensions.listItems import com.owenlejeune.tvtime.preferences.AppPreferences import com.owenlejeune.tvtime.ui.components.* @@ -57,6 +58,7 @@ fun MediaDetailView( appNavController: NavController, itemId: Int?, type: MediaViewType, + windowSize: WindowSizeClass, preferences: AppPreferences = KoinJavaComponent.get(AppPreferences::class.java) ) { val service = when (type) { @@ -104,51 +106,76 @@ fun MediaDetailView( } ) { innerPadding -> Box(modifier = Modifier.padding(innerPadding)) { - Column( + Row( modifier = Modifier .background(color = MaterialTheme.colorScheme.background) - .verticalScroll(state = rememberScrollState()) .padding(bottom = 16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp) + horizontalArrangement = Arrangement.spacedBy(16.dp) ) { - val images = remember { mutableStateOf(null) } - itemId?.let { - if (preferences.showBackdropGallery && images.value == null) { - fetchImages(itemId, service, images) - } - } - - DetailHeader( - posterUrl = TmdbUtils.getFullPosterPath(mediaItem.value?.posterPath), - posterContentDescription = mediaItem.value?.title, - backdropUrl = TmdbUtils.getFullBackdropPath(mediaItem.value?.backdropPath), - rating = mediaItem.value?.voteAverage?.let { it / 10 }, - imageCollection = images.value - ) - Column( - modifier = Modifier.padding(horizontal = 16.dp), + modifier = Modifier + .background(color = MaterialTheme.colorScheme.background) + .weight(1f) + .verticalScroll(state = rememberScrollState()), verticalArrangement = Arrangement.spacedBy(16.dp) ) { - if (type == MediaViewType.MOVIE) { - MiscMovieDetails(mediaItem = mediaItem, service as MoviesService) - } else { - MiscTvDetails(mediaItem = mediaItem, service as TvService) + val images = remember { mutableStateOf(null) } + itemId?.let { + if (preferences.showBackdropGallery && images.value == null) { + fetchImages(itemId, service, images) + } } - ActionsView(itemId = itemId, type = type, service = service) + DetailHeader( + posterUrl = TmdbUtils.getFullPosterPath(mediaItem.value?.posterPath), + posterContentDescription = mediaItem.value?.title, + backdropUrl = TmdbUtils.getFullBackdropPath(mediaItem.value?.backdropPath), + rating = mediaItem.value?.voteAverage?.let { it / 10 }, + imageCollection = images.value + ) - OverviewCard(itemId = itemId, mediaItem = mediaItem, service = service) + Column( + modifier = Modifier.padding(horizontal = 16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + if (type == MediaViewType.MOVIE) { + MiscMovieDetails(mediaItem = mediaItem, service as MoviesService) + } else { + MiscTvDetails(mediaItem = mediaItem, service as TvService) + } - CastCard(itemId = itemId, service = service, appNavController = appNavController) + ActionsView(itemId = itemId, type = type, service = service) - SimilarContentCard(itemId = itemId, service = service, mediaType = type, appNavController = appNavController) + OverviewCard(itemId = itemId, mediaItem = mediaItem, service = service) - VideosCard(itemId = itemId, service = service) + CastCard(itemId = itemId, service = service, appNavController = appNavController) - AdditionalDetailsCard(itemId = itemId, mediaItem = mediaItem, service = service, type = type) + SimilarContentCard(itemId = itemId, service = service, mediaType = type, appNavController = appNavController) - ReviewsCard(itemId = itemId, service = service) + VideosCard(itemId = itemId, service = service) + + AdditionalDetailsCard(itemId = itemId, mediaItem = mediaItem, service = service, type = type) + + if (windowSize != WindowSizeClass.Expanded) { + ReviewsCard(itemId = itemId, service = service) + } + } + + Spacer(modifier = Modifier.height(16.dp)) + } + + if (windowSize == WindowSizeClass.Expanded) { + Column( + modifier = Modifier + .background(color = MaterialTheme.colorScheme.background) + .weight(1f) + .padding(bottom = 16.dp) + .verticalScroll(state = rememberScrollState()) + ) { + ReviewsCard(itemId = itemId, service = service) + + Spacer(modifier = Modifier.height(16.dp)) + } } } } @@ -1025,7 +1052,7 @@ private fun ReviewsCard( ) { val reviews = reviewsResponse.value?.results ?: emptyList() if (reviews.isNotEmpty()) { - reviews.reversed().forEach { review -> + reviews.reversed().forEachIndexed { index, review -> Row( modifier = Modifier .fillMaxWidth() @@ -1088,10 +1115,12 @@ private fun ReviewsCard( ) } } - Divider( - color = MaterialTheme.colorScheme.secondary, - modifier = Modifier.padding(vertical = 12.dp) - ) + if (index != reviews.size - 1) { + Divider( + color = MaterialTheme.colorScheme.secondary, + modifier = Modifier.padding(vertical = 12.dp) + ) + } } } else { Text( diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViewType.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViewType.kt index 87bedaf..72fa6e6 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViewType.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViewType.kt @@ -10,7 +10,8 @@ enum class MediaViewType { @SerializedName("person") PERSON, EPISODE, - MIXED; + MIXED, + LIST; companion object { const val JSON_KEY = "media_type" diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViews.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViews.kt index 9219ee5..e178887 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViews.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/main/MediaViews.kt @@ -2,6 +2,7 @@ package com.owenlejeune.tvtime.ui.screens.main import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.* @@ -11,6 +12,7 @@ import androidx.compose.ui.draw.blur import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @@ -19,6 +21,7 @@ import androidx.constraintlayout.compose.ConstraintLayout import androidx.constraintlayout.compose.Dimension import androidx.navigation.NavController import coil.compose.AsyncImage +import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.ui.navigation.MainNavItem @OptIn(ExperimentalMaterial3Api::class) @@ -63,7 +66,7 @@ fun MediaResultCard( Box(modifier = Modifier .fillMaxSize() - .background(Color.Black.copy(alpha = 0.7f)) + .background(Color.Black.copy(alpha = 0.4f)) .blur(radius = 10.dp) ) } @@ -83,8 +86,9 @@ fun MediaResultCard( bottom.linkTo(parent.bottom) height = Dimension.fillToConstraints } + .aspectRatio(0.7f) .clip(RoundedCornerShape(10.dp)), - model = posterPath, + model = posterPath ?: R.drawable.placeholder, contentDescription = title ) @@ -101,9 +105,10 @@ fun MediaResultCard( height = Dimension.matchParent } ) { + val textColor = backdropPath?.let { Color.White } ?: if (isSystemInDarkTheme()) Color.White else Color.Black Text( text = title, - color = MaterialTheme.colorScheme.onBackground, + color = textColor, fontSize = 18.sp, fontWeight = FontWeight.Bold ) @@ -111,7 +116,7 @@ fun MediaResultCard( additionalDetails.forEach { Text( text = it, - color = MaterialTheme.colorScheme.onBackground, + color = textColor, fontSize = 14.sp, overflow = TextOverflow.Ellipsis ) diff --git a/app/src/main/java/com/owenlejeune/tvtime/utils/SessionManager.kt b/app/src/main/java/com/owenlejeune/tvtime/utils/SessionManager.kt index 4403128..5219b5c 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/utils/SessionManager.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/utils/SessionManager.kt @@ -1,5 +1,6 @@ package com.owenlejeune.tvtime.utils +import android.accounts.Account import android.content.Context import android.content.Intent import android.net.Uri @@ -10,11 +11,15 @@ import com.owenlejeune.tvtime.api.tmdb.api.v3.AccountService import com.owenlejeune.tvtime.api.tmdb.api.v3.AuthenticationService import com.owenlejeune.tvtime.api.tmdb.api.v3.GuestSessionService import com.owenlejeune.tvtime.api.tmdb.TmdbClient +import com.owenlejeune.tvtime.api.tmdb.api.v3.AccountApi import com.owenlejeune.tvtime.api.tmdb.api.v3.model.* +import com.owenlejeune.tvtime.api.tmdb.api.v4.AccountV4Api +import com.owenlejeune.tvtime.api.tmdb.api.v4.AccountV4Service import com.owenlejeune.tvtime.api.tmdb.api.v4.AuthenticationV4Service import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AuthAccessBody import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AuthDeleteBody import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AuthRequestBody +import com.owenlejeune.tvtime.api.tmdb.api.v4.model.V4AccountList import com.owenlejeune.tvtime.preferences.AppPreferences import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -90,8 +95,8 @@ object SessionManager: KoinComponent { accessToken = values.accessToken, accountId = values.accountId ) - session.initialize() _currentSession = session + session.initialize() } } } @@ -207,8 +212,8 @@ object SessionManager: KoinComponent { val accountDetails: AccountDetails? get() = _accountDetails - protected open var _accountLists: List = emptyList() - val accountLists: List + protected open var _accountLists: List = emptyList() + val accountLists: List get() = _accountLists protected open var _favoriteMovies: List = emptyList() @@ -302,7 +307,8 @@ object SessionManager: KoinComponent { accessToken: String = "", accountId: String = "" ): Session(sessionId, true, accessToken, accountId) { - private val service by lazy { AccountService() } + private val service: AccountService by inject() + private val serviceV4: AccountV4Service by inject() override suspend fun initialize() { refresh() @@ -325,7 +331,7 @@ object SessionManager: KoinComponent { private suspend fun refreshWithAccountId(accountId: Int, changed: Array = Changed.All) { if (changed.contains(Changed.Lists)) { - service.getLists(accountId).apply { + serviceV4.getLists(preferences.authorizedSessionValues?.accountId ?: "").apply { if (isSuccessful) { withContext(Dispatchers.Main) { _accountLists = body()?.results ?: _accountLists diff --git a/app/src/main/java/com/owenlejeune/tvtime/utils/TmdbUtils.kt b/app/src/main/java/com/owenlejeune/tvtime/utils/TmdbUtils.kt index 79f3f21..f9dbf6f 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/utils/TmdbUtils.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/utils/TmdbUtils.kt @@ -15,7 +15,9 @@ object TmdbUtils { private const val DEF_REGION = "US" fun getFullPosterPath(posterPath: String?): String? { - return posterPath?.let { "${POSTER_BASE}${posterPath}" } + return posterPath?.let { + if (posterPath.isEmpty()) null else "${POSTER_BASE}${posterPath}" + } } fun getFullPosterPath(tmdbItem: TmdbItem?): String? { @@ -27,7 +29,9 @@ object TmdbUtils { } fun getFullBackdropPath(backdropPath: String?): String? { - return backdropPath?.let { "${BACKDROP_BASE}${backdropPath}" } + return backdropPath?.let { + if (backdropPath.isEmpty()) null else "${BACKDROP_BASE}${backdropPath}" + } } fun getFullBackdropPath(detailItem: DetailedItem?): String? { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a5c193d..aa04f0c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,6 +22,7 @@ Favorite TV Shows Movie Watchlist TV Watchlist + Lists Cast @@ -180,4 +181,6 @@ No Favorite TV No Watchlisted Movies No Watchlisted TV + No Lists + No description provided \ No newline at end of file