fix list button on details

This commit is contained in:
Owen LeJeune
2023-07-08 20:31:24 -04:00
parent 859ab14d95
commit 2712561a31
10 changed files with 237 additions and 162 deletions

View File

@@ -104,15 +104,13 @@ dependencies {
// retrofit // retrofit
def retrofit = "2.9.0" def retrofit = "2.9.0"
def stetho = "1.6.0"
def gson = "2.10.1" def gson = "2.10.1"
def profiler = "1.0.8" def logging = "4.6.0"
implementation "com.squareup.retrofit2:retrofit:$retrofit" implementation "com.squareup.retrofit2:retrofit:$retrofit"
implementation "com.squareup.retrofit2:converter-gson:$retrofit" implementation "com.squareup.retrofit2:converter-gson:$retrofit"
implementation "com.google.code.gson:gson:$gson" implementation "com.google.code.gson:gson:$gson"
implementation "com.facebook.stetho:stetho:$stetho" implementation "com.squareup.okhttp3:logging-interceptor:$logging"
implementation "com.facebook.stetho:stetho-okhttp3:$stetho"
implementation "com.localebro:okhttpprofiler:$profiler"
// koin // koin
def koin = "3.3.0" def koin = "3.3.0"

View File

@@ -1,7 +1,6 @@
package com.owenlejeune.tvtime package com.owenlejeune.tvtime
import android.app.Application import android.app.Application
import com.facebook.stetho.Stetho
import com.kieronquinn.monetcompat.core.MonetCompat import com.kieronquinn.monetcompat.core.MonetCompat
import com.owenlejeune.tvtime.di.modules.appModule import com.owenlejeune.tvtime.di.modules.appModule
import com.owenlejeune.tvtime.di.modules.networkModule import com.owenlejeune.tvtime.di.modules.networkModule
@@ -41,10 +40,6 @@ class TvTimeApplication: Application() {
val userPickedColor = preferences.selectedColor val userPickedColor = preferences.selectedColor
it?.firstOrNull { color -> color == userPickedColor } ?: it?.firstOrNull() it?.firstOrNull { color -> color == userPickedColor } ?: it?.firstOrNull()
} }
if (BuildConfig.DEBUG) {
Stetho.initializeWithDefaults(this)
}
} }
} }

View File

@@ -1,12 +1,14 @@
package com.owenlejeune.tvtime.api package com.owenlejeune.tvtime.api
import com.facebook.stetho.okhttp3.StethoInterceptor
import com.localebro.okhttpprofiler.OkHttpProfilerInterceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
class DebugHttpClient: HttpClient { class DebugHttpClient: HttpClient {
override val httpClient: OkHttpClient = OkHttpClient.Builder() override val httpClient: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(OkHttpProfilerInterceptor()) .addInterceptor(getLoggingInterceptor())
.addNetworkInterceptor(StethoInterceptor())
.build() .build()
private fun getLoggingInterceptor() = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
} }

View File

@@ -1,7 +1,10 @@
package com.owenlejeune.tvtime.api.tmdb.api.v4 package com.owenlejeune.tvtime.api.tmdb.api.v4
import android.content.Context
import android.util.Log import android.util.Log
import android.widget.Toast
import androidx.compose.runtime.mutableStateMapOf import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AddToListBody import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AddToListBody
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.CreateListBody import com.owenlejeune.tvtime.api.tmdb.api.v4.model.CreateListBody
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.DeleteListItemsBody import com.owenlejeune.tvtime.api.tmdb.api.v4.model.DeleteListItemsBody
@@ -18,6 +21,7 @@ class ListV4Service: KoinComponent {
} }
private val service: ListV4Api by inject() private val service: ListV4Api by inject()
private val context: Context by inject()
val listMap = mutableStateMapOf<Int, MediaList>() val listMap = mutableStateMapOf<Int, MediaList>()
@@ -59,8 +63,21 @@ class ListV4Service: KoinComponent {
service.deleteList(listId) service.deleteList(listId)
} }
suspend fun addItemsToList(listId: Int, body: AddToListBody) {//}: Response<AddToListResponse> { suspend fun addItemsToList(listId: Int, body: AddToListBody) {
service.addItemsToList(listId, body) val response = service.addItemsToList(listId, body)
if (response.isSuccessful) {
response.body()?.let {
if (it.isSuccess) {
Toast.makeText(context, "Successfully added to list", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, "Error: This item already exists in list", Toast.LENGTH_SHORT).show()
}
} ?: run {
Toast.makeText(context, "An error occurred", Toast.LENGTH_SHORT).show()
}
} else {
Toast.makeText(context, "An error occurred", Toast.LENGTH_SHORT).show()
}
} }
suspend fun updateListItems(listId: Int, body: UpdateListItemBody) {//}: Response<AddToListResponse> { suspend fun updateListItems(listId: Int, body: UpdateListItemBody) {//}: Response<AddToListResponse> {

View File

@@ -8,49 +8,34 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredWidthIn import androidx.compose.foundation.layout.requiredWidthIn
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Bookmark import androidx.compose.material.icons.filled.Bookmark
import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.List import androidx.compose.material.icons.filled.List
import androidx.compose.material.icons.filled.Star import androidx.compose.material.icons.filled.Star
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.ui.theme.FavoriteSelected import com.owenlejeune.tvtime.ui.theme.FavoriteSelected
import com.owenlejeune.tvtime.ui.theme.RatingSelected import com.owenlejeune.tvtime.ui.theme.RatingSelected
import com.owenlejeune.tvtime.ui.theme.WatchlistSelected import com.owenlejeune.tvtime.ui.theme.WatchlistSelected
import com.owenlejeune.tvtime.ui.theme.actionButtonColor
import com.owenlejeune.tvtime.ui.viewmodel.AccountViewModel import com.owenlejeune.tvtime.ui.viewmodel.AccountViewModel
import com.owenlejeune.tvtime.ui.viewmodel.MainViewModel import com.owenlejeune.tvtime.ui.viewmodel.MainViewModel
import com.owenlejeune.tvtime.utils.SessionManager
import com.owenlejeune.tvtime.utils.types.MediaViewType import com.owenlejeune.tvtime.utils.types.MediaViewType
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.text.DecimalFormat
enum class Actions { enum class Actions {
RATE, RATE,
@@ -63,8 +48,8 @@ enum class Actions {
fun ActionsView( fun ActionsView(
itemId: Int, itemId: Int,
type: MediaViewType, type: MediaViewType,
actions: List<Actions> = listOf(Actions.RATE, Actions.WATCHLIST, Actions.LIST, Actions.FAVORITE), modifier: Modifier = Modifier,
modifier: Modifier = Modifier actions: List<Actions> = listOf(Actions.RATE, Actions.WATCHLIST, Actions.LIST, Actions.FAVORITE)
) { ) {
val accountViewModel = viewModel<AccountViewModel>() val accountViewModel = viewModel<AccountViewModel>()
val mainViewModel = viewModel<MainViewModel>() val mainViewModel = viewModel<MainViewModel>()
@@ -77,6 +62,12 @@ fun ActionsView(
modifier = modifier, modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(8.dp) horizontalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
if (actions.contains(Actions.LIST)) {
ListButton(
itemId = itemId,
type = type
)
}
if (actions.contains(Actions.RATE)) { if (actions.contains(Actions.RATE)) {
RateButton( RateButton(
itemId = itemId, itemId = itemId,
@@ -100,12 +91,6 @@ fun ActionsView(
mainViewModel = mainViewModel mainViewModel = mainViewModel
) )
} }
if (actions.contains(Actions.LIST)) {
ListButton(
itemId = itemId,
type = type
)
}
} }
} }
@@ -215,15 +200,21 @@ fun ListButton(
type: MediaViewType, type: MediaViewType,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
CircleBackgroundColorImage( val showListDialog = remember { mutableStateOf(false) }
modifier = modifier.clickable(
onClick = {} ActionButton(
), imageVector = Icons.Filled.List,
size = 40.dp, contentDescription = "",
backgroundColor = MaterialTheme.colorScheme.actionButtonColor, isSelected = false,
image = Icons.Filled.List, filledIconColor = MaterialTheme.colorScheme.background,
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.background), onClick = { showListDialog.value = true },
contentDescription = "" modifier = modifier
)
AddToListDialog(
showDialog = showListDialog,
itemId = itemId,
itemType = type
) )
} }

View File

@@ -6,14 +6,12 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.painter.Painter
@@ -24,8 +22,6 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import coil.compose.AsyncImage import coil.compose.AsyncImage
import coil.compose.rememberAsyncImagePainter import coil.compose.rememberAsyncImagePainter
import coil.request.CachePolicy import coil.request.CachePolicy
@@ -37,11 +33,9 @@ import com.google.accompanist.pager.rememberPagerState
import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ExternalIds import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ExternalIds
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ImageCollection import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ImageCollection
import com.owenlejeune.tvtime.ui.viewmodel.ConfigurationViewModel
import com.owenlejeune.tvtime.utils.TmdbUtils import com.owenlejeune.tvtime.utils.TmdbUtils
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.androidx.compose.koinViewModel
@OptIn(ExperimentalPagerApi::class) @OptIn(ExperimentalPagerApi::class)
@Composable @Composable
@@ -55,76 +49,7 @@ fun DetailHeader(
posterContentDescription: String? = null, posterContentDescription: String? = null,
rating: Float? = null, rating: Float? = null,
pagerState: PagerState? = null, pagerState: PagerState? = null,
elevation: Dp = 20.dp elevation: Dp = 50.dp
) {
ConstraintLayout(modifier = modifier
.fillMaxWidth()
.wrapContentHeight()
) {
val (
backdropImage, posterImage, ratingsView
) = createRefs()
if (imageCollection != null) {
BackdropGallery(
modifier = Modifier
.constrainAs(backdropImage) {
top.linkTo(parent.top)
start.linkTo(parent.start)
end.linkTo(parent.end)
}
.clickable {
showGalleryOverlay?.value = true
},
imageCollection = imageCollection,
state = pagerState
)
} else {
Backdrop(
imageUrl = backdropUrl,
contentDescription = backdropContentDescription
)
}
PosterItem(
modifier = Modifier
.constrainAs(posterImage) {
bottom.linkTo(backdropImage.bottom)
start.linkTo(parent.start, margin = 16.dp)
},
url = posterUrl,
title = posterContentDescription,
elevation = elevation,
overrideShowTitle = false,
enabled = false
)
rating?.let {
RatingView(
modifier = Modifier
.constrainAs(ratingsView) {
bottom.linkTo(parent.bottom)
start.linkTo(posterImage.end, margin = 20.dp)
},
progress = rating
)
}
}
}
@OptIn(ExperimentalPagerApi::class)
@Composable
fun DetailHeader2(
modifier: Modifier = Modifier,
showGalleryOverlay: MutableState<Boolean>? = null,
imageCollection: ImageCollection? = null,
backdropUrl: String? = null,
posterUrl: String? = null,
backdropContentDescription: String? = null,
posterContentDescription: String? = null,
rating: Float? = null,
pagerState: PagerState? = null,
elevation: Dp = 20.dp
) { ) {
Box( Box(
modifier = modifier.then( modifier = modifier.then(

View File

@@ -1,22 +1,54 @@
package com.owenlejeune.tvtime.ui.components package com.owenlejeune.tvtime.ui.components
import android.util.Log
import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.paging.compose.collectAsLazyPagingItems
import com.owenlejeune.tvtime.R import com.owenlejeune.tvtime.R
import com.owenlejeune.tvtime.api.tmdb.api.v4.ListV4Service
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AccountList
import com.owenlejeune.tvtime.extensions.lazyPagingItems
import com.owenlejeune.tvtime.ui.viewmodel.AccountViewModel
import com.owenlejeune.tvtime.utils.types.MediaViewType
import kotlinx.coroutines.launch
import java.text.DecimalFormat import java.text.DecimalFormat
private const val TAG = "Dialogs"
@Composable @Composable
fun RatingDialog( fun RatingDialog(
showDialog: MutableState<Boolean>, showDialog: MutableState<Boolean>,
@@ -28,7 +60,7 @@ fun RatingDialog(
} }
if (showDialog.value) { if (showDialog.value) {
var sliderPosition by remember { mutableStateOf(rating) } var sliderPosition by remember { mutableFloatStateOf(rating) }
val formatted = formatPosition(sliderPosition).toFloat() val formatted = formatPosition(sliderPosition).toFloat()
AlertDialog( AlertDialog(
modifier = Modifier.wrapContentHeight(), modifier = Modifier.wrapContentHeight(),
@@ -79,4 +111,96 @@ fun RatingDialog(
} }
) )
} }
}
@Composable
fun AddToListDialog(
itemId: Int,
itemType: MediaViewType,
showDialog: MutableState<Boolean>
) {
if (showDialog.value) {
val scope = rememberCoroutineScope()
val accountViewModel = viewModel<AccountViewModel>()
val lists = accountViewModel.userLists.collectAsLazyPagingItems()
AlertDialog(
onDismissRequest = { showDialog.value = false },
title = {
Text(text = stringResource(id = R.string.add_to_list_action_label))
},
text = {
Column(
modifier = Modifier.height(300.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
val filter = remember { mutableStateOf("") }
RoundedTextField(
modifier = Modifier
.height(55.dp)
.padding(bottom = 12.dp),
value = filter.value,
onValueChange = { filter.value = it },
placeHolder = stringResource(id = R.string.search_placeholder, stringResource(id = R.string.lists)),
leadingIcon = {
Image(
imageVector = Icons.Filled.Search,
contentDescription = stringResource(R.string.search_icon_content_descriptor),
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.primary)
)
}
)
LazyColumn(
verticalArrangement = Arrangement.spacedBy(18.dp)
) {
if (lists.itemCount == 0) {
item {
Spacer(modifier = Modifier.weight(1f))
Text(stringResource(id = R.string.no_lists_message))
Spacer(modifier = Modifier.weight(1f))
}
}
lazyPagingItems(lists) { list ->
(list as AccountList).apply {
if (list.name.contains(filter.value)) {
Box(
modifier = Modifier
.clip(RoundedCornerShape(10.dp))
.clickable {
scope.launch {
accountViewModel.addToList(
listId = list.id,
itemId = itemId,
itemType = itemType
)
}
}
) {
Text(
text = stringResource(id = R.string.list_count_label, list.name, list.numberOfItems),
fontSize = 16.sp,
modifier = Modifier
.padding(horizontal = 12.dp, vertical = 4.dp)
.fillMaxWidth()
)
}
}
}
}
}
}
},
confirmButton = {
Button(
modifier = Modifier.height(40.dp),
onClick = {
showDialog.value = false
}
) {
Text(stringResource(id = R.string.action_dismiss))
}
}
)
}
} }

View File

@@ -167,7 +167,7 @@ private fun MediaViewContent(
.verticalScroll(state = rememberScrollState()), .verticalScroll(state = rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(16.dp) verticalArrangement = Arrangement.spacedBy(16.dp)
) { ) {
DetailHeader2( DetailHeader(
posterUrl = TmdbUtils.getFullPosterPath(mediaItem?.posterPath), posterUrl = TmdbUtils.getFullPosterPath(mediaItem?.posterPath),
posterContentDescription = mediaItem?.title, posterContentDescription = mediaItem?.title,
backdropUrl = TmdbUtils.getFullBackdropPath(mediaItem?.backdropPath), backdropUrl = TmdbUtils.getFullBackdropPath(mediaItem?.backdropPath),

View File

@@ -8,6 +8,8 @@ import com.owenlejeune.tvtime.api.tmdb.api.v3.model.MarkAsFavoriteBody
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.WatchlistBody import com.owenlejeune.tvtime.api.tmdb.api.v3.model.WatchlistBody
import com.owenlejeune.tvtime.api.tmdb.api.v4.AccountV4Service import com.owenlejeune.tvtime.api.tmdb.api.v4.AccountV4Service
import com.owenlejeune.tvtime.api.tmdb.api.v4.ListV4Service import com.owenlejeune.tvtime.api.tmdb.api.v4.ListV4Service
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AddToListBody
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.AddToListBodyItem
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.DeleteListItemsBody import com.owenlejeune.tvtime.api.tmdb.api.v4.model.DeleteListItemsBody
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.DeleteListItemsItem import com.owenlejeune.tvtime.api.tmdb.api.v4.model.DeleteListItemsItem
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.ListUpdateBody import com.owenlejeune.tvtime.api.tmdb.api.v4.model.ListUpdateBody
@@ -30,44 +32,53 @@ class AccountViewModel: ViewModel(), KoinComponent {
val listMap = listService.listMap val listMap = listService.listMap
val ratedTv: Flow<PagingData<Any>> = createPagingFlow( val ratedTv: Flow<PagingData<Any>>
fetcher = { p -> accountV4Service.getRatedTvShows(accountId, p) }, get() = createPagingFlow(
processor = { it.results } fetcher = { p -> accountV4Service.getRatedTvShows(accountId, p) },
) processor = { it.results }
val favoriteTv: Flow<PagingData<Any>> = createPagingFlow( )
fetcher = { p -> accountV4Service.getFavoriteTvShows(accountId, p) }, val favoriteTv: Flow<PagingData<Any>>
processor = { it.results } get() = createPagingFlow(
) fetcher = { p -> accountV4Service.getFavoriteTvShows(accountId, p) },
val watchlistTv: Flow<PagingData<Any>> = createPagingFlow( processor = { it.results }
fetcher = { p -> accountV4Service.getTvShowWatchlist(accountId, p) }, )
processor = { it.results } val watchlistTv: Flow<PagingData<Any>>
) get() = createPagingFlow(
val recommendedTv: Flow<PagingData<Any>> = createPagingFlow( fetcher = { p -> accountV4Service.getTvShowWatchlist(accountId, p) },
fetcher = { p -> accountV4Service.getRecommendedTvSeries(accountId, p) }, processor = { it.results }
processor = { it.results } )
) val recommendedTv: Flow<PagingData<Any>>
get() = createPagingFlow(
fetcher = { p -> accountV4Service.getRecommendedTvSeries(accountId, p) },
processor = { it.results }
)
val ratedMovies: Flow<PagingData<Any>> = createPagingFlow( val ratedMovies: Flow<PagingData<Any>>
fetcher = { p -> accountV4Service.getRatedMovies(accountId, p) }, get() = createPagingFlow(
processor = { it.results } fetcher = { p -> accountV4Service.getRatedMovies(accountId, p) },
) processor = { it.results }
val favoriteMovies: Flow<PagingData<Any>> = createPagingFlow( )
fetcher = { p -> accountV4Service.getFavoriteMovies(accountId, p) }, val favoriteMovies: Flow<PagingData<Any>>
processor = { it.results } get() = createPagingFlow(
) fetcher = { p -> accountV4Service.getFavoriteMovies(accountId, p) },
val watchlistMovies: Flow<PagingData<Any>> = createPagingFlow( processor = { it.results }
fetcher = { p -> accountV4Service.getMovieWatchlist(accountId, p) }, )
processor = { it.results } val watchlistMovies: Flow<PagingData<Any>>
) get() = createPagingFlow(
val recommendedMovies: Flow<PagingData<Any>> = createPagingFlow( fetcher = { p -> accountV4Service.getMovieWatchlist(accountId, p) },
fetcher = { p -> accountV4Service.getRecommendedMovies(accountId, p) }, processor = { it.results }
processor = { it.results } )
) val recommendedMovies: Flow<PagingData<Any>>
get() = createPagingFlow(
fetcher = { p -> accountV4Service.getRecommendedMovies(accountId, p) },
processor = { it.results }
)
val userLists: Flow<PagingData<Any>> = createPagingFlow( val userLists: Flow<PagingData<Any>>
fetcher = { p -> accountV4Service.getLists(accountId, p) }, get() = createPagingFlow(
processor = { it.results } fetcher = { p -> accountV4Service.getLists(accountId, p) },
) processor = { it.results }
)
fun getPagingFlowFor(type: MediaViewType, accountTabType: AccountTabNavItem.AccountTabType): Flow<PagingData<Any>> { fun getPagingFlowFor(type: MediaViewType, accountTabType: AccountTabNavItem.AccountTabType): Flow<PagingData<Any>> {
return when (accountTabType) { return when (accountTabType) {
@@ -124,6 +135,15 @@ class AccountViewModel: ViewModel(), KoinComponent {
listService.updateList(listId, body) listService.updateList(listId, body)
} }
suspend fun addToList(listId: Int, itemId: Int, itemType: MediaViewType) {
val body = AddToListBody(listOf(AddToListBodyItem(itemType, itemId)))
addToList(listId, body)
}
suspend fun addToList(listId: Int, body: AddToListBody) {
listService.addItemsToList(listId, body)
}
suspend fun addToFavourites(type: MediaViewType, itemId: Int, favourited: Boolean) { suspend fun addToFavourites(type: MediaViewType, itemId: Int, favourited: Boolean) {
val accountId = SessionManager.currentSession.value?.accountDetails?.value?.id ?: throw Exception("Session must not be null") val accountId = SessionManager.currentSession.value?.accountDetails?.value?.id ?: throw Exception("Session must not be null")
accountService.markAsFavorite(accountId, MarkAsFavoriteBody(type, itemId, favourited)) accountService.markAsFavorite(accountId, MarkAsFavoriteBody(type, itemId, favourited))

View File

@@ -244,4 +244,7 @@
<string name="network_disconnected_message">Network Disconnected</string> <string name="network_disconnected_message">Network Disconnected</string>
<string name="network_api_rate_limit_reached">API Rate limit reached</string> <string name="network_api_rate_limit_reached">API Rate limit reached</string>
<string name="network_error_occurred">%1$d: An error occurred</string> <string name="network_error_occurred">%1$d: An error occurred</string>
<string name="lists">lists</string>
<string name="no_lists_message">You don\'t have any lists yet</string>
<string name="list_count_label">%1$s (%2$d items)</string>
</resources> </resources>