Skip to content

Commit

Permalink
Merge pull request #28 from stslex/dev
Browse files Browse the repository at this point in the history
Favourites screen
  • Loading branch information
stslex authored Feb 4, 2024
2 parents 692c42e + b8e378b commit 341208f
Show file tree
Hide file tree
Showing 48 changed files with 990 additions and 220 deletions.
2 changes: 0 additions & 2 deletions composeApp/src/commonMain/kotlin/InitialApp.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -49,7 +48,6 @@ fun InitialApp(
) { paddingValues ->
Box(
modifier = Modifier.fillMaxSize()
.padding(paddingValues)
) {
Navigator(
screen = if (userStore.isAuth) MainScreen else AuthScreen
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.stslex.core.core

import java.util.UUID

actual fun randomUuid(): String = UUID.randomUUID().toString()
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ import kotlinx.coroutines.CoroutineExceptionHandler

val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
Logger.exception(throwable)
}
}

expect fun randomUuid(): String
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.stslex.core.core

import java.util.UUID

actual fun randomUuid(): String = UUID.randomUUID().toString()
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.stslex.core.core

import platform.Foundation.NSUUID

actual fun randomUuid(): String = NSUUID().UUIDString()
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package com.stslex.core.network.clients.film.client

import com.stslex.core.core.Logger
import com.stslex.core.core.randomUuid
import com.stslex.core.network.clients.film.model.FilmItemNetwork
import com.stslex.core.network.clients.film.model.FilmListNetwork
import com.stslex.core.network.clients.film.model.FilmTrailerNetwork
import com.stslex.core.network.clients.film.model.MovieNetwork
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlin.coroutines.coroutineContext
import kotlin.random.Random

class MockFilmClientImpl : FilmClient {

private val filmsFlow = MutableStateFlow(filmsList)

override suspend fun getFeedFilms(
page: Int,
pageSize: Int
Expand All @@ -21,20 +20,19 @@ class MockFilmClientImpl : FilmClient {
delay(1000)
return FilmListNetwork(
results = Array(pageSize) { index ->
val itemIndex = page.dec() * pageSize + index
getFilmById(itemIndex)
if (index >= filmsList.size) {
getFilmByIndex(index)
} else {
filmsList[index]
}
}.toList(),
hasNext = true
)
}

override suspend fun getFilm(id: String): MovieNetwork {
TODO()
}
override suspend fun getFilm(id: String): MovieNetwork = getMovieById(id)

override suspend fun getFilmTrailers(id: String): List<FilmTrailerNetwork> {
TODO("Not yet implemented")
}
override suspend fun getFilmTrailers(id: String): List<FilmTrailerNetwork> = emptyList()

override suspend fun likeFilm(id: String) {
TODO("Not yet implemented")
Expand All @@ -44,61 +42,77 @@ class MockFilmClientImpl : FilmClient {
TODO("Not yet implemented")
}

private fun getFilmById(id: Int) = filmsList[id % filmsList.size].copy(
id = id.toString()
private fun getFilmByIndex(index: Int) = filmsList[index % filmsList.size].copy(
id = randomUuid()
)
}

private fun getMovieById(id: String) = movieList.firstOrNull { it.id == id }
?: movieList[Random(0).nextInt(filmsList.size)]
}

private val lokiFilm = FilmItemNetwork(
id = "1",
private val lokiMovieFilm = MovieNetwork(
id = "b2cb4f71-1bf1-43fa-b047-4378f77d1286",
title = "Локи",
// description = "Сразу же после кражи Тессеракта в фильме «Мстители: Финал» (2019), альтернативная версия Локи попадает в «Управление временны́ми изменениями» (УВИ), бюрократическую организацию, которая существует вне пространства и времени. Богу обмана предстоит ответить за свои преступления против времени и перед ним встаёт выбор: подвергнуться стиранию из реальности или помочь УВИ в борьбе с большей угрозой.",
poster = "https://pico.kartinka.shop/poster/item/big/72418.jpg",
description = "Сразу же после кражи Тессеракта в фильме «Мстители: Финал» (2019), альтернативная версия Локи попадает в «Управление временны́ми изменениями» (УВИ), бюрократическую организацию, которая существует вне пространства и времени. Богу обмана предстоит ответить за свои преступления против времени и перед ним встаёт выбор: подвергнуться стиранию из реальности или помочь УВИ в борьбе с большей угрозой.",
poster = "https://avatars.mds.yandex.net/get-kinopoisk-image/9784475/8daa730d-5b99-4add-adc9-f623db620735/3840x",
rating = "8.2",
genres = listOf("Боевик", "Фантастика", "Фэнтези", "Приключения"),
// actors = listOf("Том Хиддлстон", "Софи Ди Мартин", "Оуэн Уилсон"),
// director = "Кейт Херон",
year = "2021",
// duration = "50 мин.",
duration = "50 мин.",
countries = listOf("США"),
// age = "16+",
age = "16+",
type = "Сериал",
// trailer = "https://www.youtube.com/watch?v=nW948Va-l10",
)

private val infiniteWar = FilmItemNetwork(
id = "2",
private val lokiFilm = lokiMovieFilm.toFilmItemNetwork()

private val infiniteWarMovie = MovieNetwork(
id = "33fa9d73-a722-4efd-b95c-0dd6af25e6af",
title = "Мстители: Война бесконечности",
// description = "Пока Мстители и их союзники продолжают защищать мир от различных опасностей, с которыми не смог бы справиться один супергерой, новая угроза возникает из космоса: Танос. Межгалактический тиран преследует цель собрать все шесть Камней Бесконечности - артефакты невероятной силы, с помощью которых можно менять реальность по своему желанию. Всё, с чем Мстители сталкивались ранее, вело к этому моменту - судьба Земли никогда ещё не была столь неопределённой.",
poster = "https://pico.kartinka.shop/poster/item/big/34114.jpg",
description = "Пока Мстители и их союзники продолжают защищать мир от различных опасностей, с которыми не смог бы справиться один супергерой, новая угроза возникает из космоса: Танос. Межгалактический тиран преследует цель собрать все шесть Камней Бесконечности - артефакты невероятной силы, с помощью которых можно менять реальность по своему желанию. Всё, с чем Мстители сталкивались ранее, вело к этому моменту - судьба Земли никогда ещё не была столь неопределённой.",
poster = "https://www.komar.de/media/catalog/product/cache/7/image/9df78eab33525d08d6e5fb8d27136e95/4/-/4-4126_avengers_infinity_war_movie_poster_web.jpg",
rating = "8.4",
genres = listOf("Боевик", "Фантастика", "Фэнтези", "Приключения"),
// actors = listOf("Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"),
// director = "Энтони Руссо",
year = "2018",
// duration = "149 мин.",
duration = "149 мин.",
countries = listOf("США"),
// age = "12+",
age = "12+",
type = "Фильм",
// trailer = "https://www.youtube.com/watch?v=6ZfuNTqbHE8",
)

private val rhinoFilm = FilmItemNetwork(
id = "3",
private val infiniteWar = infiniteWarMovie.toFilmItemNetwork()

private val rhinoFilmMovie = MovieNetwork(
id = "261fc394-e9cd-484e-bcd1-33152b7a0ba9",
title = "Вольт",
// description = "Вольт — собака-полицейский, звезда телесериала, в котором он сражается с преступниками и спасает мир. Но когда камеры отключаются, Вольт не понимает, что происходит, и думает, что всё, что его окружает, настоящее. Когда его хозяйка Пенни похищают, Вольт отправляется в реальное путешествие, чтобы спасти её. На помощь ему приходят два необычных спутника — кот Мистер и хомяк Ролли.",
poster = "https://pico.kartinka.shop/poster/item/big/2570.jpg",
description = "Вольт — собака-полицейский, звезда телесериала, в котором он сражается с преступниками и спасает мир. Но когда камеры отключаются, Вольт не понимает, что происходит, и думает, что всё, что его окружает, настоящее. Когда его хозяйка Пенни похищают, Вольт отправляется в реальное путешествие, чтобы спасти её. На помощь ему приходят два необычных спутника — кот Мистер и хомяк Ролли.",
poster = "https://avatars.dzeninfra.ru/get-zen_doc/3588827/pub_5ef9aeefa08a7d51ae37d007_5ef9af0b20ea6c1d487268cc/scale_1200",
rating = "6.8",
genres = listOf("Комедия", "Фантастика", "Семейный", "Приключения", "Мультфильм"),
// actors = listOf("Джон Траволта", "Майли Сайрус", "Сьюзи Эссман"),
// director = "Байрон Ховард",
year = "2008",
// duration = "96 мин.",
duration = "96 мин.",
countries = listOf("США"),
// age = "6+",
age = "6+",
type = "Фильм",
// trailer = "https://www.youtube.com/watch?v=6ZfuNTqbHE8",
)

private val filmsList = listOf(lokiFilm, infiniteWar, rhinoFilm)
private val rhinoFilm = rhinoFilmMovie.toFilmItemNetwork()

private val filmsList = listOf(lokiFilm, infiniteWar, rhinoFilm)
private val movieList = listOf(lokiMovieFilm, infiniteWarMovie, rhinoFilmMovie)

private fun MovieNetwork.toFilmItemNetwork() = FilmItemNetwork(
id = id,
title = title,
poster = poster,
rating = rating,
genres = genres,
year = year,
type = type,
countries = countries
)
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.stslex.core.network.clients.profile.client

import com.stslex.core.network.clients.profile.model.UserFavouriteResponse
import com.stslex.core.network.clients.profile.model.UserFavouriteResultResponse
import com.stslex.core.network.clients.profile.model.UserFollowerResponse
import com.stslex.core.network.clients.profile.model.UserFollowerResultResponse
import com.stslex.core.network.clients.profile.model.UserResponse
import com.stslex.core.network.clients.profile.model.UserSearchResponse
import com.stslex.core.core.Logger
import com.stslex.core.network.clients.profile.model.response.BooleanResponse
import com.stslex.core.network.clients.profile.model.response.UserFavouriteResponse
import com.stslex.core.network.clients.profile.model.response.UserFavouriteResultResponse
import com.stslex.core.network.clients.profile.model.response.UserFollowerResponse
import com.stslex.core.network.clients.profile.model.response.UserFollowerResultResponse
import com.stslex.core.network.clients.profile.model.response.UserResponse
import com.stslex.core.network.clients.profile.model.response.UserSearchResponse
import kotlinx.coroutines.delay

class MockProfileClientImpl : ProfileClient {
Expand Down Expand Up @@ -54,6 +56,7 @@ class MockProfileClientImpl : ProfileClient {

override suspend fun getFavourites(
uuid: String,
query: String,
page: Int,
pageSize: Int
): UserFavouriteResponse {
Expand Down Expand Up @@ -104,4 +107,16 @@ class MockProfileClientImpl : ProfileClient {
)
)
}

override suspend fun addFavourite(uuid: String, title: String) {
Logger.debug("Favourite added")
}

override suspend fun isFavourite(favouriteUuid: String): BooleanResponse {
return BooleanResponse(true)
}

override suspend fun removeFavourite(uuid: String) {
Logger.debug("Favourite removed")
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.stslex.core.network.clients.profile.client

import com.stslex.core.network.clients.profile.model.UserResponse
import com.stslex.core.network.clients.profile.model.UserFavouriteResponse
import com.stslex.core.network.clients.profile.model.UserFollowerResponse
import com.stslex.core.network.clients.profile.model.UserSearchResponse
import com.stslex.core.network.clients.profile.model.response.BooleanResponse
import com.stslex.core.network.clients.profile.model.response.UserFavouriteResponse
import com.stslex.core.network.clients.profile.model.response.UserFollowerResponse
import com.stslex.core.network.clients.profile.model.response.UserResponse
import com.stslex.core.network.clients.profile.model.response.UserSearchResponse

interface ProfileClient {

Expand All @@ -19,6 +20,7 @@ interface ProfileClient {

suspend fun getFavourites(
uuid: String,
query: String,
page: Int,
pageSize: Int
): UserFavouriteResponse
Expand All @@ -34,4 +36,13 @@ interface ProfileClient {
page: Int,
pageSize: Int
): UserFollowerResponse

suspend fun addFavourite(
uuid: String,
title: String,
)

suspend fun isFavourite(favouriteUuid: String): BooleanResponse

suspend fun removeFavourite(uuid: String)
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.stslex.core.network.clients.profile.client

import com.stslex.core.network.api.server.client.ServerApiClient
import com.stslex.core.network.clients.profile.model.UserResponse
import com.stslex.core.network.clients.profile.model.UserFavouriteResponse
import com.stslex.core.network.clients.profile.model.UserFollowerResponse
import com.stslex.core.network.clients.profile.model.UserSearchResponse
import com.stslex.core.network.clients.profile.model.request.AddLikeRequest
import com.stslex.core.network.clients.profile.model.response.BooleanResponse
import com.stslex.core.network.clients.profile.model.response.UserFavouriteResponse
import com.stslex.core.network.clients.profile.model.response.UserFollowerResponse
import com.stslex.core.network.clients.profile.model.response.UserResponse
import com.stslex.core.network.clients.profile.model.response.UserSearchResponse
import io.ktor.client.call.body
import io.ktor.client.request.delete
import io.ktor.client.request.get
import io.ktor.client.request.parameter
import io.ktor.client.request.post
import io.ktor.client.request.setBody

class ProfileClientImpl(
private val client: ServerApiClient
Expand Down Expand Up @@ -39,11 +44,13 @@ class ProfileClientImpl(

override suspend fun getFavourites(
uuid: String,
query: String,
page: Int,
pageSize: Int
): UserFavouriteResponse = client.request {
get("$HOST/favourites") {
parameter("uuid", uuid)
parameter("query", query)
parameter("page", page)
parameter("page_size", pageSize)
}.body()
Expand Down Expand Up @@ -73,7 +80,37 @@ class ProfileClientImpl(
}.body()
}

override suspend fun addFavourite(uuid: String, title: String) {
client.request {
post("$HOST/favourite") {
setBody(
AddLikeRequest(
filmUuid = uuid,
title = title
)
)
}
}
}

override suspend fun removeFavourite(uuid: String) {
client.request {
delete("$HOST/favourite") {
parameter("favourite_uuid", uuid)
}
}
}

override suspend fun isFavourite(
favouriteUuid: String
): BooleanResponse = client.request {
get("$HOST/is_favourite") {
parameter("uuid", favouriteUuid)
}.body()
}

companion object {
private const val HOST = "user"
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.stslex.core.network.clients.profile.model.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class AddLikeRequest(
@SerialName("favourite_uuid")
val filmUuid: String,
@SerialName("title")
val title: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.stslex.core.network.clients.profile.model.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class BooleanResponse(
@SerialName("result")
val result: Boolean
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.stslex.core.network.clients.profile.model
package com.stslex.core.network.clients.profile.model.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.stslex.core.network.clients.profile.model
package com.stslex.core.network.clients.profile.model.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand Down
Loading

0 comments on commit 341208f

Please sign in to comment.