mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-12-30 11:21:20 -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}")
|
builder.header("Authorization", "Bearer ${BuildConfig.TMDB_Api_v4Key}")
|
||||||
} else {
|
} else {
|
||||||
builder.header("Authorization", "Bearer ${SessionManager.currentSession!!.accessToken}")
|
builder.header("Authorization", "Bearer ${SessionManager.currentSession!!.accessToken}")
|
||||||
|
}
|
||||||
|
if (shouldIncludeLanguageParam(url.encodedPathSegments)) {
|
||||||
val locale = Locale.current
|
val locale = Locale.current
|
||||||
val languageCode = "${locale.language}-${locale.region}"
|
val languageCode = "${locale.language}-${locale.region}"
|
||||||
val languageParam = QueryParam("language", languageCode)
|
val languageParam = QueryParam("language", languageCode)
|
||||||
@@ -155,10 +157,23 @@ class TmdbClient: KoinComponent {
|
|||||||
val newUrl = url.newBuilder().addQueryParams(languageParam).build()
|
val newUrl = url.newBuilder().addQueryParams(languageParam).build()
|
||||||
builder.url(newUrl)
|
builder.url(newUrl)
|
||||||
}
|
}
|
||||||
|
if (url.encodedPathSegments.contains("list")) {
|
||||||
|
builder.header("Content-Type", "application/json;charset=utf8")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return chain.proceed(builder.build())
|
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>
|
): Response<MediaList>
|
||||||
|
|
||||||
@POST("list")
|
@POST("list")
|
||||||
suspend fun createList(body: CreateListBody): Response<CreateListResponse>
|
suspend fun createList(@Body body: CreateListBody): Response<CreateListResponse>
|
||||||
|
|
||||||
@PUT("list/{id}")
|
@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")
|
@GET("list/{id}/clear")
|
||||||
suspend fun clearList(@Path("id") listId: Int): Response<ClearListResponse>
|
suspend fun clearList(@Path("id") listId: Int): Response<ClearListResponse>
|
||||||
@@ -26,13 +26,13 @@ interface ListV4Api {
|
|||||||
suspend fun deleteList(@Path("id") listId: Int): Response<StatusResponse>
|
suspend fun deleteList(@Path("id") listId: Int): Response<StatusResponse>
|
||||||
|
|
||||||
@POST("list/{id}/items")
|
@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")
|
@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")
|
@HTTP(method = "DELETE", path = "/list/{id}/items", hasBody = true)
|
||||||
suspend fun deleteListItems(@Path("id") listId: Int, body: DeleteListItemsBody): Response<AddToListResponse>
|
suspend fun deleteListItems(@Path("id") listId: Int, @Body body: DeleteListItemsBody): Response<AddToListResponse>
|
||||||
|
|
||||||
@GET("list/{id}/item_status")
|
@GET("list/{id}/item_status")
|
||||||
suspend fun getListItemStatus(@Path("id") listId: Int, @Query("media_id") mediaId: Int, @Query("media_type") mediaType: String): Response<ListItemStatusResponse>
|
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
|
import com.owenlejeune.tvtime.ui.screens.main.MediaViewType
|
||||||
|
|
||||||
class DeleteListItemsBody(
|
class DeleteListItemsBody(
|
||||||
|
@SerializedName("items") val items: List<DeleteListItemsItem>
|
||||||
|
)
|
||||||
|
|
||||||
|
class DeleteListItemsItem(
|
||||||
@SerializedName("media_id") val id: Int,
|
@SerializedName("media_id") val id: Int,
|
||||||
@SerializedName("media_type") val mediaType: MediaViewType
|
@SerializedName("media_type") val mediaType: MediaViewType
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.owenlejeune.tvtime.ui.screens.main
|
package com.owenlejeune.tvtime.ui.screens.main
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.animation.rememberSplineBasedDecay
|
import androidx.compose.animation.rememberSplineBasedDecay
|
||||||
import androidx.compose.foundation.*
|
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.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.ListV4Service
|
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.*
|
||||||
import com.owenlejeune.tvtime.api.tmdb.api.v4.model.MediaList
|
|
||||||
import com.owenlejeune.tvtime.extensions.WindowSizeClass
|
import com.owenlejeune.tvtime.extensions.WindowSizeClass
|
||||||
import com.owenlejeune.tvtime.extensions.unlessEmpty
|
import com.owenlejeune.tvtime.extensions.unlessEmpty
|
||||||
import com.owenlejeune.tvtime.preferences.AppPreferences
|
import com.owenlejeune.tvtime.preferences.AppPreferences
|
||||||
@@ -63,10 +63,10 @@ fun ListDetailView(
|
|||||||
) {
|
) {
|
||||||
val service = ListV4Service()
|
val service = ListV4Service()
|
||||||
|
|
||||||
val listItem = remember { mutableStateOf<MediaList?>(null) }
|
val parentList = remember { mutableStateOf<MediaList?>(null) }
|
||||||
itemId?.let {
|
itemId?.let {
|
||||||
if (listItem.value == null) {
|
if (parentList.value == null) {
|
||||||
fetchList(itemId, service, listItem)
|
fetchList(itemId, service, parentList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ fun ListDetailView(
|
|||||||
scrolledContainerColor = MaterialTheme.colorScheme.background,
|
scrolledContainerColor = MaterialTheme.colorScheme.background,
|
||||||
titleContentColor = MaterialTheme.colorScheme.primary
|
titleContentColor = MaterialTheme.colorScheme.primary
|
||||||
),
|
),
|
||||||
title = { Text(text = listItem.value?.name ?: "") },
|
title = { Text(text = parentList.value?.name ?: "") },
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { appNavController.popBackStack() }
|
onClick = { appNavController.popBackStack() }
|
||||||
@@ -102,7 +102,7 @@ fun ListDetailView(
|
|||||||
}
|
}
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
Box(modifier = Modifier.padding(innerPadding)) {
|
Box(modifier = Modifier.padding(innerPadding)) {
|
||||||
listItem.value?.let { mediaList ->
|
parentList.value?.let { mediaList ->
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(all = 12.dp)
|
.padding(all = 12.dp)
|
||||||
@@ -114,7 +114,8 @@ fun ListDetailView(
|
|||||||
mediaList.results.forEach { listItem ->
|
mediaList.results.forEach { listItem ->
|
||||||
ListItemView(
|
ListItemView(
|
||||||
appNavController = appNavController,
|
appNavController = appNavController,
|
||||||
listItem = listItem
|
listItem = listItem,
|
||||||
|
list = parentList
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -252,16 +253,22 @@ private fun RowScope.OverviewStatCard(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun ListItemView(
|
private fun ListItemView(
|
||||||
appNavController: NavController,
|
appNavController: NavController,
|
||||||
listItem: ListItem
|
listItem: ListItem,
|
||||||
|
list: MutableState<MediaList?>
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
RevealSwipe (
|
RevealSwipe (
|
||||||
directions = setOf(RevealDirection.EndToStart),
|
directions = setOf(RevealDirection.EndToStart),
|
||||||
hiddenContentEnd = {
|
hiddenContentEnd = {
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier.padding(horizontal = 15.dp),
|
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(
|
Icon(
|
||||||
imageVector = Icons.Filled.Delete,
|
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 Rated get() = arrayOf(RatedMovies, RatedTv, RatedEpisodes)
|
||||||
val Favorites get() = arrayOf(FavoriteMovies, FavoriteTv)
|
val Favorites get() = arrayOf(FavoriteMovies, FavoriteTv)
|
||||||
val Watchlist get() = arrayOf(WatchlistMovies, WatchlistTv)
|
val Watchlist get() = arrayOf(WatchlistMovies, WatchlistTv)
|
||||||
|
val List get() = arrayOf(Changed.Lists)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user