custom dropdown menu + setup account api service

This commit is contained in:
Owen LeJeune
2022-03-10 13:22:57 -05:00
parent 0ed5fa88f1
commit 45020832ff
24 changed files with 444 additions and 55 deletions

View File

@@ -0,0 +1,74 @@
package com.owenlejeune.tvtime.api.tmdb
import com.owenlejeune.tvtime.api.tmdb.model.*
import retrofit2.Response
import retrofit2.http.*
interface AccountApi {
@GET("account")
suspend fun getAccountDetails(): Response<AccountDetails>
@GET("account/{id}/lists")
suspend fun getLists(
@Path("id") id: Int,
@Query("page") page: Int
): Response<AccountListResponse>
@GET("account/{id}/favorite/movies")
suspend fun getFavoriteMovies(
@Path("id") id: Int,
@Query("page") page: Int
): Response<FavoriteMediaResponse<FavoriteMovie>>
@GET("account/{id}/favorite/tv")
suspend fun getFavoriteTvShows(
@Path("id") id: Int,
@Query("page") page: Int
): Response<FavoriteMediaResponse<FavoriteTvSeries>>
// @Headers("Content-Type: application/json;charset=utf-8")
@POST("account/{id}/favorite")
suspend fun markAsFavorite(
@Path("id") id: Int,
@Body body: MarkAsFavoriteBody
): Response<StatusResponse>
@GET("account/{id}/rated/movies")
suspend fun getRatedMovies(
@Path("id") id: Int,
@Query("page") page: Int
): Response<RatedMediaResponse<RatedMovie>>
@GET("account/{id}/rated/tv")
suspend fun getRatedTvShows(
@Path("id") id: Int,
@Query("page") page: Int
): Response<RatedMediaResponse<RatedTv>>
@GET("account/{id}/rated/tv/episodes")
suspend fun getRatedTvEpisodes(
@Path("id") id: Int,
@Query("page") page: Int
): Response<RatedMediaResponse<RatedEpisode>>
@GET("account/{id}/watchlist/movies")
suspend fun getMovieWatchlist(
@Path("id") id: Int,
@Query("page") page: Int
): Response<WatchlistResponse<WatchlistMovie>>
@GET("account/{id}/watchlist/tv")
suspend fun getTvWatchlist(
@Path("id") id: Int,
@Query("page") page: Int
): Response<WatchlistResponse<WatchlistTvSeries>>
// @Headers("Content-Type: application/json;charset=utf-8")
@POST("account/{id}/watchlist")
suspend fun addToWatchlist(
@Path("id") id: Int,
@Body body: WatchlistBody
): Response<StatusResponse>
}

View File

@@ -0,0 +1,50 @@
package com.owenlejeune.tvtime.api.tmdb
import com.owenlejeune.tvtime.api.tmdb.model.*
import retrofit2.Response
class AccountService {
private val accountService by lazy { TmdbClient().createAccountService() }
suspend fun getAccountDetails(): Response<AccountDetails> {
return accountService.getAccountDetails()
}
suspend fun getFavoriteMovies(accountId: Int, page: Int = 1): Response<FavoriteMediaResponse<FavoriteMovie>> {
return accountService.getFavoriteMovies(accountId, page)
}
suspend fun getFavoriteTvShows(accountId: Int, page: Int = 1): Response<FavoriteMediaResponse<FavoriteTvSeries>> {
return accountService.getFavoriteTvShows(accountId, page)
}
suspend fun markAsFavorite(accountId: Int, body: MarkAsFavoriteBody): Response<StatusResponse> {
return accountService.markAsFavorite(accountId, body)
}
suspend fun getRatedMovies(accountId: Int, page: Int = 1): Response<RatedMediaResponse<RatedMovie>> {
return accountService.getRatedMovies(accountId, page)
}
suspend fun getRatedTvShows(accountId: Int, page: Int = 1): Response<RatedMediaResponse<RatedTv>> {
return accountService.getRatedTvShows(accountId, page)
}
suspend fun getRatedTvEpisodes(accountId: Int, page: Int = 1): Response<RatedMediaResponse<RatedEpisode>> {
return accountService.getRatedTvEpisodes(accountId, page)
}
suspend fun getMovieWatchlist(accountId: Int, page: Int = 1): Response<WatchlistResponse<WatchlistMovie>> {
return accountService.getMovieWatchlist(accountId, page)
}
suspend fun getTvWatchlist(accountId: Int, page: Int = 1): Response<WatchlistResponse<WatchlistTvSeries>> {
return accountService.getTvWatchlist(accountId, page)
}
suspend fun addToWatchlist(accountId: Int, body: WatchlistBody): Response<StatusResponse> {
return accountService.addToWatchlist(accountId, body)
}
}

View File

@@ -17,9 +17,9 @@ interface DetailService {
suspend fun getReviews(id: Int): Response<ReviewResponse>
suspend fun postRating(id: Int, ratingBody: RatingBody): Response<RatingResponse>
suspend fun postRating(id: Int, ratingBody: RatingBody): Response<StatusResponse>
suspend fun deleteRating(id: Int): Response<RatingResponse>
suspend fun deleteRating(id: Int): Response<StatusResponse>
suspend fun getKeywords(id: Int): Response<KeywordsResponse>

View File

@@ -0,0 +1,9 @@
package com.owenlejeune.tvtime.api.tmdb
import com.google.gson.annotations.SerializedName
class MarkAsFavoriteBody(
@SerializedName("media_type") val mediaType: String, // media type
@SerializedName("media_id") val mediaId: Int,
@SerializedName("favorite") val isFavorite: Boolean
)

View File

@@ -47,25 +47,25 @@ interface MoviesApi {
@Path("id") id: Int,
@Query("guest_session_id") guestSessionId: String,
@Body ratingBody: RatingBody
): Response<RatingResponse>
): Response<StatusResponse>
@POST("movie/{id}/rating")
suspend fun postMovieRatingAsUser(
@Path("id") id: Int,
@Query("session_id") sessionId: String,
@Body ratingBody: RatingBody
): Response<RatingResponse>
): Response<StatusResponse>
@DELETE("movie/{id}/rating")
suspend fun deleteMovieReviewAsGuest(
@Path("id") id: Int,
@Query("guest_session_id") guestSessionId: String
): Response<RatingResponse>
): Response<StatusResponse>
@DELETE("movie/{id}/rating")
suspend fun deleteMovieReviewAsUser(
@Path("id") id: Int,
@Query("session_id") sessionId: String
): Response<RatingResponse>
): Response<StatusResponse>
}

View File

@@ -53,7 +53,7 @@ class MoviesService: KoinComponent, DetailService, HomePageService {
return movieService.getReviews(id)
}
override suspend fun postRating(id: Int, rating: RatingBody): Response<RatingResponse> {
override suspend fun postRating(id: Int, rating: RatingBody): Response<StatusResponse> {
val session = SessionManager.currentSession ?: throw Exception("Session must not be null")
return if (!session.isAuthorized) {
movieService.postMovieRatingAsGuest(id, session.sessionId, rating)
@@ -62,7 +62,7 @@ class MoviesService: KoinComponent, DetailService, HomePageService {
}
}
override suspend fun deleteRating(id: Int): Response<RatingResponse> {
override suspend fun deleteRating(id: Int): Response<StatusResponse> {
val session = SessionManager.currentSession ?: throw Exception("Session must not be null")
return if (!session.isAuthorized) {
movieService.deleteMovieReviewAsGuest(id, session.sessionId)

View File

@@ -5,6 +5,7 @@ import com.owenlejeune.tvtime.BuildConfig
import com.owenlejeune.tvtime.api.Client
import com.owenlejeune.tvtime.api.QueryParam
import com.owenlejeune.tvtime.extensions.addQueryParams
import com.owenlejeune.tvtime.utils.SessionManager
import okhttp3.Interceptor
import okhttp3.Response
import org.koin.core.component.KoinComponent
@@ -43,6 +44,10 @@ class TmdbClient: KoinComponent {
return client.create(GuestSessionApi::class.java)
}
fun createAccountService(): AccountApi {
return client.create(AccountApi::class.java)
}
private inner class TmdbInterceptor: Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val apiParam = QueryParam("api_key", BuildConfig.TMDB_ApiKey)
@@ -51,7 +56,13 @@ class TmdbClient: KoinComponent {
val languageCode = "${locale.language}-${locale.region}"
val languageParam = QueryParam("language", languageCode)
val request = chain.addQueryParams(apiParam, languageParam)
var sessionIdParam: QueryParam? = null
val segments = chain.request().url().encodedPathSegments()
if (segments.size > 1 && segments[1].equals("account") && SessionManager.currentSession?.isAuthorized == true) {
sessionIdParam = QueryParam("session_id", SessionManager.currentSession!!.sessionId)
}
val request = chain.addQueryParams(apiParam, languageParam, sessionIdParam)
return chain.proceed(request)
}

View File

@@ -47,25 +47,25 @@ interface TvApi {
@Path("id") id: Int,
@Query("guest_session_id") guestSessionId: String,
@Body ratingBody: RatingBody
): Response<RatingResponse>
): Response<StatusResponse>
@POST("tv/{id}/rating")
suspend fun postTvRatingAsUser(
@Path("id") id: Int,
@Query("session_id") sessionId: String,
@Body ratingBody: RatingBody
): Response<RatingResponse>
): Response<StatusResponse>
@DELETE("tv/{id}/rating")
suspend fun deleteTvReviewAsGuest(
@Path("id") id: Int,
@Query("guest_session_id") guestSessionId: String
): Response<RatingResponse>
): Response<StatusResponse>
@DELETE("tv/{id}/rating")
suspend fun deleteTvReviewAsUser(
@Path("id") id: Int,
@Query("session_id") sessionId: String
): Response<RatingResponse>
): Response<StatusResponse>
}

View File

@@ -53,7 +53,7 @@ class TvService: KoinComponent, DetailService, HomePageService {
return service.getReviews(id)
}
override suspend fun postRating(id: Int, rating: RatingBody): Response<RatingResponse> {
override suspend fun postRating(id: Int, rating: RatingBody): Response<StatusResponse> {
val session = SessionManager.currentSession ?: throw Exception("Session must not be null")
return if (!session.isAuthorized) {
service.postTvRatingAsGuest(id, session.sessionId, rating)
@@ -62,7 +62,7 @@ class TvService: KoinComponent, DetailService, HomePageService {
}
}
override suspend fun deleteRating(id: Int): Response<RatingResponse> {
override suspend fun deleteRating(id: Int): Response<StatusResponse> {
val session = SessionManager.currentSession ?: throw Exception("Session must not be null")
return if (!session.isAuthorized) {
service.deleteTvReviewAsGuest(id, session.sessionId)

View File

@@ -0,0 +1,21 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class AccountDetails(
@SerializedName("avatar") val avatar: Avatar,
@SerializedName("id") val id: Int,
@SerializedName("iso_639_1") val languageCode: String,
@SerializedName("iso_3166_1") val countryCode: String,
@SerializedName("name") val name: String,
@SerializedName("include_adult") val includeAdult: Boolean,
@SerializedName("username") val username: String
)
class Avatar(
@SerializedName("gravatar") val gravatar: Gravatar
)
class Gravatar(
@SerializedName("hash") val hash: String
)

View File

@@ -0,0 +1,13 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class AccountList(
@SerializedName("description") val description: String,
@SerializedName("favorite_count") val favoriteCount: Int,
@SerializedName("id") val id: Int,
@SerializedName("item_count") val itemCount: Int,
@SerializedName("iso_639_1") val languageCode: String,
@SerializedName("list_type") val listType: String, // media type
@SerializedName("name") val name: String
)

View File

@@ -0,0 +1,10 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class AccountListResponse(
@SerializedName("page") val page: Int,
@SerializedName("total_pages") val totalPages: Int,
@SerializedName("total_results") val totalResults: Int,
@SerializedName("results") val results: List<AccountList>
)

View File

@@ -0,0 +1,18 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
abstract class FavoriteMedia(
@SerializedName("poster_path") val posterPath: String?,
@SerializedName("popularity") val popularity: Float,
@SerializedName("id") val id: Int,
@SerializedName("backdrop_path") val backdropPath: String?,
@SerializedName("vote_average") val voteAverage: Float,
@SerializedName("overview") val overview: String,
@SerializedName("release_date", alternate = ["first_air_date"]) val releaseDate: String,
@SerializedName("genre_ids") val genreIds: List<Int>,
@SerializedName("original_language") val originalLanguage: String,
@SerializedName("vote_count") val voteCount: Int,
@SerializedName("title", alternate = ["name"]) val title: String,
@SerializedName("original_title", alternate = ["original_name"]) val originalTitle: String
)

View File

@@ -0,0 +1,10 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class FavoriteMediaResponse<T: FavoriteMedia>(
@SerializedName("page") val page: Int,
@SerializedName("results") val results: List<T>,
@SerializedName("total_pages") val totalPages: Int,
@SerializedName("total_results") val totalResults: Int
)

View File

@@ -0,0 +1,23 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class FavoriteMovie(
posterPath: String?,
popularity: Float,
id: Int,
backdropPath: String?,
voteAverage: Float,
overview: String,
releaseDate: String,
genreIds: List<Int>,
originalLanguage: String,
voteCount: Int,
title: String,
originalTitle: String,
@SerializedName("adult") val isAdult: Boolean,
@SerializedName("video") val isVideo: Boolean,
): FavoriteMedia(
posterPath, popularity, id, backdropPath, voteAverage, overview, releaseDate,
genreIds, originalLanguage, voteCount, title, originalTitle
)

View File

@@ -0,0 +1,22 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class FavoriteTvSeries(
posterPath: String?,
popularity: Float,
id: Int,
backdropPath: String?,
voteAverage: Float,
overview: String,
releaseDate: String,
genreIds: List<Int>,
originalLanguage: String,
voteCount: Int,
title: String,
originalTitle: String,
@SerializedName("origin_country") val originCountry: List<String>
): FavoriteMedia(
posterPath, popularity, id, backdropPath, voteAverage, overview, releaseDate,
genreIds, originalLanguage, voteCount, title, originalTitle
)

View File

@@ -2,7 +2,7 @@ package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class RatingResponse(
class StatusResponse(
@SerializedName("status_code") val statusCode: Int,
@SerializedName("status_message") val statusMessage: String
)

View File

@@ -0,0 +1,9 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class WatchlistBody(
@SerializedName("media_type") val mediaType: String, // media type
@SerializedName("media_id") val mediaId: Int,
@SerializedName("watchlist") val onWatchlist: Boolean
)

View File

@@ -0,0 +1,18 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
abstract class WatchlistMedia(
@SerializedName("poster_path") val posterPath: String?,
@SerializedName("popularity") val popularity: Float,
@SerializedName("id") val id: Int,
@SerializedName("backdrop_path") val backdropPath: String?,
@SerializedName("vote_average") val voteAverage: Float,
@SerializedName("overview") val overview: String,
@SerializedName("release_date", alternate = ["first_air_date"]) val releaseDate: String,
@SerializedName("genre_ids") val genreIds: List<Int>,
@SerializedName("original_language") val originalLanguage: String,
@SerializedName("vote_count") val voteCount: Int,
@SerializedName("title", alternate = ["name"]) val title: String,
@SerializedName("original_title", alternate = ["original_name"]) val originalTitle: String
)

View File

@@ -0,0 +1,23 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class WatchlistMovie(
posterPath: String?,
popularity: Float,
id: Int,
backdropPath: String?,
voteAverage: Float,
overview: String,
releaseDate: String,
genreIds: List<Int>,
originalLanguage: String,
voteCount: Int,
title: String,
originalTitle: String,
@SerializedName("adult") val isAdult: Boolean,
@SerializedName("video") val isVideo: Boolean,
): WatchlistMedia(
posterPath, popularity, id, backdropPath, voteAverage, overview, releaseDate,
genreIds, originalLanguage, voteCount, title, originalTitle
)

View File

@@ -0,0 +1,10 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class WatchlistResponse<T: WatchlistMedia>(
@SerializedName("page") val page: Int,
@SerializedName("results") val results: List<T>,
@SerializedName("total_pages") val totalPages: Int,
@SerializedName("total_results") val totalResults: Int
)

View File

@@ -0,0 +1,22 @@
package com.owenlejeune.tvtime.api.tmdb.model
import com.google.gson.annotations.SerializedName
class WatchlistTvSeries(
posterPath: String?,
popularity: Float,
id: Int,
backdropPath: String?,
voteAverage: Float,
overview: String,
releaseDate: String,
genreIds: List<Int>,
originalLanguage: String,
voteCount: Int,
title: String,
originalTitle: String,
@SerializedName("origin_country") val originCountry: List<String>
): WatchlistMedia(
posterPath, popularity, id, backdropPath, voteAverage, overview, releaseDate,
genreIds, originalLanguage, voteCount, title, originalTitle
)

View File

@@ -1,19 +1,26 @@
package com.owenlejeune.tvtime.ui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.AlertDialog
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.DropdownMenu
import androidx.compose.material3.Divider
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.window.Dialog
@Composable
@@ -36,7 +43,7 @@ fun TopAppBarDropdownMenu(
}
DropdownMenu(
modifier = Modifier.background(color = MaterialTheme.colorScheme.surfaceVariant),
modifier = Modifier.background(color = MaterialTheme.colorScheme.background),
expanded = expanded.value,
onDismissRequest = { expanded.value = false }
) {
@@ -44,6 +51,59 @@ fun TopAppBarDropdownMenu(
}
}
@Composable
fun CustomTopAppBarDropdownMenu(
icon: @Composable () -> Unit = {},
content: @Composable ColumnScope.(expanded: MutableState<Boolean>) -> Unit = {}
) {
val expanded = remember { mutableStateOf(false) }
Box(modifier = Modifier.wrapContentSize(Alignment.TopEnd)) {
IconButton(onClick = { expanded.value = true }) {
icon()
}
}
DropdownMenu(
expanded = expanded.value,
onDismissRequest = { expanded.value = false},
modifier = Modifier
.background(color = MaterialTheme.colorScheme.background)
.shadow(elevation = 0.dp),
offset = DpOffset(16.dp, 0.dp)
) {
content(this, expanded)
}
}
@Composable
fun CustomMenuItem(
text: String,
onClick: () -> Unit
) {
Box(
modifier = Modifier
.clip(RoundedCornerShape(30.dp))
.fillMaxWidth()
.background(color = MaterialTheme.colorScheme.primary)
) {
Text(
text = text,
color = MaterialTheme.colorScheme.background,
modifier = Modifier
.padding(horizontal = 15.dp, vertical = 10.dp)
.clickable(onClick = onClick)
.fillMaxWidth(),
textAlign = TextAlign.Center
)
}
}
@Composable
fun CustomMenuDivider() {
Divider(color = Color.Transparent, modifier = Modifier.padding(vertical = 2.dp))
}
@Composable
fun TopAppBarDialogMenu(
icon: @Composable () -> Unit = {},

View File

@@ -1,14 +1,11 @@
package com.owenlejeune.tvtime.ui.screens.tabs.bottom
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material3.Divider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@@ -31,9 +28,7 @@ import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.model.RatedMovie
import com.owenlejeune.tvtime.api.tmdb.model.RatedTopLevelMedia
import com.owenlejeune.tvtime.api.tmdb.model.RatedTv
import com.owenlejeune.tvtime.ui.components.RoundedLetterImage
import com.owenlejeune.tvtime.ui.components.SignInDialog
import com.owenlejeune.tvtime.ui.components.TopAppBarDropdownMenu
import com.owenlejeune.tvtime.ui.components.*
import com.owenlejeune.tvtime.ui.navigation.AccountTabNavItem
import com.owenlejeune.tvtime.ui.navigation.ListFetchFun
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
@@ -175,7 +170,7 @@ private fun AccountDropdownMenu(
session: SessionManager.Session?,
lastSelectedOption: MutableState<String>
) {
TopAppBarDropdownMenu(
CustomTopAppBarDropdownMenu(
icon = {
when(session?.isAuthorized) {
true -> { }
@@ -198,14 +193,14 @@ private fun NoSessionMenuItems(
lastSelectedOption: MutableState<String>
) {
val showSignInDialog = remember { mutableStateOf(false) }
DropdownMenuItem(
CustomMenuItem(
text = stringResource(id = R.string.action_sign_in),
onClick = {
showSignInDialog.value = true
},
modifier = Modifier.background(color = MaterialTheme.colorScheme.surfaceVariant)
) {
Text(text = stringResource(R.string.action_sign_in), color = MaterialTheme.colorScheme.onSurfaceVariant)
}
}
)
CustomMenuDivider()
if (showSignInDialog.value) {
SignInDialog(showDialog = showSignInDialog) { success ->
@@ -216,16 +211,13 @@ private fun NoSessionMenuItems(
}
}
Divider(color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(horizontal = 12.dp))
DropdownMenuItem(
CustomMenuItem(
text = stringResource(R.string.action_sign_in_as_guest),
onClick = {
createGuestSession(lastSelectedOption)
expanded.value = false
}
) {
Text(text = stringResource(R.string.action_sign_in_as_guest), color = MaterialTheme.colorScheme.onSurfaceVariant)
}
)
}
@Composable
@@ -246,14 +238,10 @@ private fun GuestSessionMenuItems(
lastSelectedOption: MutableState<String>
) {
val showSignInDialog = remember { mutableStateOf(false) }
DropdownMenuItem(
onClick = {
showSignInDialog.value = true
},
modifier = Modifier.background(color = MaterialTheme.colorScheme.surfaceVariant)
) {
Text(text = stringResource(id = R.string.action_sign_in), color = MaterialTheme.colorScheme.onSurfaceVariant)
}
CustomMenuItem(
text = stringResource(id = R.string.action_sign_in),
onClick = { showSignInDialog.value = true }
)
if (showSignInDialog.value) {
SignInDialog(showDialog = showSignInDialog) { success ->
@@ -264,16 +252,15 @@ private fun GuestSessionMenuItems(
}
}
Divider(color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(horizontal = 12.dp))
CustomMenuDivider()
DropdownMenuItem(
CustomMenuItem(
text = stringResource(id = R.string.action_sign_out),
onClick = {
signOut(lastSelectedOption)
expanded.value = false
}
) {
Text(text = stringResource(id = R.string.action_sign_out), color = MaterialTheme.colorScheme.onSurfaceVariant)
}
)
}
@Composable
@@ -287,14 +274,13 @@ private fun AuthorizedSessionMenuItems(
expanded: MutableState<Boolean>,
lastSelectedOption: MutableState<String>
) {
DropdownMenuItem(
CustomMenuItem(
text = stringResource(id = R.string.action_sign_out),
onClick = {
lastSelectedOption.value = ACCOUNT_SIGN_OUT
expanded.value = false
}
) {
Text(text = stringResource(id = R.string.action_sign_out), color = MaterialTheme.colorScheme.onSurfaceVariant)
}
)
}
private fun createGuestSession(lastSelectedOption: MutableState<String>) {