mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-08 12:42:44 -05:00
WIP - swipe actions
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user