WIP - swipe actions

This commit is contained in:
Owen LeJeune
2023-05-27 11:25:33 -04:00
parent 077e51f3cd
commit f24e0d2dfb
5 changed files with 68 additions and 18 deletions

View File

@@ -148,6 +148,8 @@ class TmdbClient: KoinComponent {
builder.header("Authorization", "Bearer ${BuildConfig.TMDB_Api_v4Key}")
} else {
builder.header("Authorization", "Bearer ${SessionManager.currentSession!!.accessToken}")
}
if (shouldIncludeLanguageParam(url.encodedPathSegments)) {
val locale = Locale.current
val languageCode = "${locale.language}-${locale.region}"
val languageParam = QueryParam("language", languageCode)
@@ -155,10 +157,23 @@ class TmdbClient: KoinComponent {
val newUrl = url.newBuilder().addQueryParams(languageParam).build()
builder.url(newUrl)
}
if (url.encodedPathSegments.contains("list")) {
builder.header("Content-Type", "application/json;charset=utf8")
}
}
return chain.proceed(builder.build())
}
private fun shouldIncludeLanguageParam(urlSegments: List<String>): Boolean {
val ignoredRoutes = listOf("list", "auth")
for (route in ignoredRoutes) {
if (urlSegments.contains(route)) {
return false
}
}
return true
}
}
}

View File

@@ -14,10 +14,10 @@ interface ListV4Api {
): Response<MediaList>
@POST("list")
suspend fun createList(body: CreateListBody): Response<CreateListResponse>
suspend fun createList(@Body body: CreateListBody): Response<CreateListResponse>
@PUT("list/{id}")
suspend fun updateList(@Path("id") listId: Int, body: ListUpdateBody): Response<StatusResponse>
suspend fun updateList(@Path("id") listId: Int, @Body body: ListUpdateBody): Response<StatusResponse>
@GET("list/{id}/clear")
suspend fun clearList(@Path("id") listId: Int): Response<ClearListResponse>
@@ -26,13 +26,13 @@ interface ListV4Api {
suspend fun deleteList(@Path("id") listId: Int): Response<StatusResponse>
@POST("list/{id}/items")
suspend fun addItemsToList(@Path("id") listId: Int, body: AddToListBody): Response<AddToListResponse>
suspend fun addItemsToList(@Path("id") listId: Int, @Body body: AddToListBody): Response<AddToListResponse>
@PUT("list/{id}/items")
suspend fun updateListItems(@Path("id") listId: Int, body: UpdateListItemBody): Response<AddToListResponse>
suspend fun updateListItems(@Path("id") listId: Int, @Body body: UpdateListItemBody): Response<AddToListResponse>
@DELETE("list/{id}/items")
suspend fun deleteListItems(@Path("id") listId: Int, body: DeleteListItemsBody): Response<AddToListResponse>
@HTTP(method = "DELETE", path = "/list/{id}/items", hasBody = true)
suspend fun deleteListItems(@Path("id") listId: Int, @Body body: DeleteListItemsBody): Response<AddToListResponse>
@GET("list/{id}/item_status")
suspend fun getListItemStatus(@Path("id") listId: Int, @Query("media_id") mediaId: Int, @Query("media_type") mediaType: String): Response<ListItemStatusResponse>

View File

@@ -4,6 +4,10 @@ import com.google.gson.annotations.SerializedName
import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
class DeleteListItemsBody(
@SerializedName("items") val items: List<DeleteListItemsItem>
)
class DeleteListItemsItem(
@SerializedName("media_id") val id: Int,
@SerializedName("media_type") val mediaType: MediaViewType
)

View File

@@ -1,6 +1,7 @@
package com.owenlejeune.tvtime.ui.screens.main
import android.content.Context
import android.content.Intent
import android.util.Log
import android.widget.Toast
import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.foundation.*
@@ -35,8 +36,7 @@ import com.owenlejeune.tvtime.api.tmdb.api.v3.AccountService
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.v4.ListV4Service
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.ListItem
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.MediaList
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.*
import com.owenlejeune.tvtime.extensions.WindowSizeClass
import com.owenlejeune.tvtime.extensions.unlessEmpty
import com.owenlejeune.tvtime.preferences.AppPreferences
@@ -63,10 +63,10 @@ fun ListDetailView(
) {
val service = ListV4Service()
val listItem = remember { mutableStateOf<MediaList?>(null) }
val parentList = remember { mutableStateOf<MediaList?>(null) }
itemId?.let {
if (listItem.value == null) {
fetchList(itemId, service, listItem)
if (parentList.value == null) {
fetchList(itemId, service, parentList)
}
}
@@ -86,7 +86,7 @@ fun ListDetailView(
scrolledContainerColor = MaterialTheme.colorScheme.background,
titleContentColor = MaterialTheme.colorScheme.primary
),
title = { Text(text = listItem.value?.name ?: "") },
title = { Text(text = parentList.value?.name ?: "") },
navigationIcon = {
IconButton(
onClick = { appNavController.popBackStack() }
@@ -102,7 +102,7 @@ fun ListDetailView(
}
) { innerPadding ->
Box(modifier = Modifier.padding(innerPadding)) {
listItem.value?.let { mediaList ->
parentList.value?.let { mediaList ->
Column(
modifier = Modifier
.padding(all = 12.dp)
@@ -114,7 +114,8 @@ fun ListDetailView(
mediaList.results.forEach { listItem ->
ListItemView(
appNavController = appNavController,
listItem = listItem
listItem = listItem,
list = parentList
)
}
}
@@ -252,16 +253,22 @@ private fun RowScope.OverviewStatCard(
@Composable
private fun ListItemView(
appNavController: NavController,
listItem: ListItem
listItem: ListItem,
list: MutableState<MediaList?>
) {
val context = LocalContext.current
RevealSwipe (
directions = setOf(RevealDirection.EndToStart),
hiddenContentEnd = {
IconButton(
modifier = Modifier.padding(horizontal = 15.dp),
onClick = { Toast.makeText(context, "Remove from list", Toast.LENGTH_SHORT).show() }
onClick = {
removeItemFromList(
itemId = listItem.id,
itemType = listItem.mediaType,
service = ListV4Service(),
list = list
)
}
) {
Icon(
imageVector = Icons.Filled.Delete,
@@ -496,4 +503,27 @@ private fun fetchList(
}
}
}
}
private fun removeItemFromList(
itemId: Int,
itemType: MediaViewType,
service: ListV4Service,
list: MutableState<MediaList?>
) {
CoroutineScope(Dispatchers.IO).launch {
val listId = list.value?.id ?: 0
val removeItem = DeleteListItemsItem(itemId, itemType)
val result = service.deleteListItems(listId, DeleteListItemsBody(listOf(removeItem)))
if (result.isSuccessful) {
SessionManager.currentSession?.refresh(SessionManager.Session.Changed.List)
service.getList(listId).body()?.let {
withContext(Dispatchers.Main) {
list.value = it
}
}
} else {
Log.w("RemoveListItemError", result.toString())
}
}
}

View File

@@ -290,6 +290,7 @@ object SessionManager: KoinComponent {
val Rated get() = arrayOf(RatedMovies, RatedTv, RatedEpisodes)
val Favorites get() = arrayOf(FavoriteMovies, FavoriteTv)
val Watchlist get() = arrayOf(WatchlistMovies, WatchlistTv)
val List get() = arrayOf(Changed.Lists)
}
}
}