Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev #15

Merged
merged 2 commits into from
Nov 29, 2023
Merged

dev #15

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ kotlin {
commonMain.dependencies {
implementation(project(":core:core"))
implementation(project(":core:network"))
implementation(project(":core:database"))
implementation(project(":core:ui"))
implementation(project(":feature:feed"))
implementation(project(":feature:film"))
Expand Down
2 changes: 2 additions & 0 deletions composeApp/src/commonMain/kotlin/App.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import androidx.compose.runtime.Composable
import com.stslex.core.core.coreModule
import com.stslex.core.database.di.databaseModule
import com.stslex.core.network.di.networkModule
import com.stslex.core.ui.theme.AppTheme
import com.stslex.feature.feed.di.feedModule
Expand Down Expand Up @@ -34,6 +35,7 @@ private fun setupModules(): KoinAppDeclaration = {
appModule,
coreModule,
networkModule,
databaseModule,
feedModule,
filmModule,
profileModule,
Expand Down
47 changes: 47 additions & 0 deletions core/database/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidLibrary)
alias(libs.plugins.jetbrainsCompose)
kotlin("plugin.serialization") version "1.9.20"
}

kotlin {
androidTarget {
compilations.all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}

jvm("desktop")

listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "database"
isStatic = true
}
}

sourceSets {
commonMain.dependencies {
implementation(project(":core:core"))
implementation(libs.kotlinx.serialization.json)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
}
}

android {
namespace = "com.stslex.core.database"
compileSdk = libs.versions.android.compileSdk.get().toInt()
defaultConfig {
minSdk = libs.versions.android.minSdk.get().toInt()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.stslex.core.database.di

import com.stslex.core.database.sources.source.FavouriteFilmDataSource
import com.stslex.core.database.sources.source.FavouriteFilmDataSourceImpl
import org.koin.dsl.module

val databaseModule = module {
single<FavouriteFilmDataSource> { FavouriteFilmDataSourceImpl() }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.stslex.core.database.sources.model

data class FilmEntity(
val id: String,
val title: String,
val description: String,
val poster: String,
val rating: String,
val duration: String,
val genres: List<String>,
val actors: List<String>,
val director: String,
val country: String,
val year: String,
val age: String,
val type: String,
val trailer: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.stslex.core.database.sources.source

import com.stslex.core.database.sources.model.FilmEntity

interface FavouriteFilmDataSource {

suspend fun getFilm(id: String): FilmEntity?

suspend fun likeFilm(filmEntity: FilmEntity)

suspend fun dislikeFilm(id: String)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.stslex.core.database.sources.source

import com.stslex.core.database.sources.model.FilmEntity

class FavouriteFilmDataSourceImpl : FavouriteFilmDataSource {

override suspend fun getFilm(id: String): FilmEntity? {
return null
TODO("Not yet implemented")
}

override suspend fun likeFilm(filmEntity: FilmEntity) {
// TODO("Not yet implemented")
}

override suspend fun dislikeFilm(id: String) {
// TODO("Not yet implemented")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ package com.stslex.core.network.clients.film.client

import com.stslex.core.network.clients.film.model.FilmFeedResponse
import com.stslex.core.network.clients.film.model.FilmResponse
import kotlinx.coroutines.flow.Flow

interface FilmClient {

suspend fun getFeedFilms(page: Int, pageSize: Int): FilmFeedResponse

suspend fun getFilm(id: String): FilmResponse
fun getFilm(id: String): Flow<FilmResponse>

suspend fun likeFilm(id: String)

suspend fun dislikeFilm(id: String)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import com.stslex.core.network.clients.film.model.FilmResponse
import io.ktor.client.call.body
import io.ktor.client.request.get
import io.ktor.client.request.parameter
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow

class FilmClientImpl(
private val client: NetworkClient
Expand All @@ -20,9 +22,20 @@ class FilmClientImpl(
}.body()
}

override suspend fun getFilm(id: String): FilmResponse = client.request {
get("feed") {
parameter("id", id)
}.body()
override fun getFilm(id: String): Flow<FilmResponse> = flow {
val result: FilmResponse = client.request {
get("feed") {
parameter("id", id)
}.body()
}
emit(result)
}

override suspend fun likeFilm(id: String) {
TODO("Not yet implemented")
}

override suspend fun dislikeFilm(id: String) {
TODO("Not yet implemented")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ import com.stslex.core.core.Logger
import com.stslex.core.network.clients.film.model.FilmFeedResponse
import com.stslex.core.network.clients.film.model.FilmResponse
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.map

class MockFilmClientImpl : FilmClient {

private val filmsFlow = MutableStateFlow(filmsList)

override suspend fun getFeedFilms(
page: Int,
pageSize: Int
Expand All @@ -22,65 +28,78 @@ class MockFilmClientImpl : FilmClient {
)
}

override suspend fun getFilm(id: String): FilmResponse = getFilmById(id.toInt())
override fun getFilm(id: String): Flow<FilmResponse> = filmsFlow
.map { filmsList ->
filmsList[id.toInt() % filmsList.size].copy(id = id)
}
.filterNotNull()

override suspend fun likeFilm(id: String) {
TODO("Not yet implemented")
}

override suspend fun dislikeFilm(id: String) {
TODO("Not yet implemented")
}

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

private val lokiFilm = FilmResponse(
id = "1",
title = "Локи",
description = "Сразу же после кражи Тессеракта в фильме «Мстители: Финал» (2019), альтернативная версия Локи попадает в «Управление временны́ми изменениями» (УВИ), бюрократическую организацию, которая существует вне пространства и времени. Богу обмана предстоит ответить за свои преступления против времени и перед ним встаёт выбор: подвергнуться стиранию из реальности или помочь УВИ в борьбе с большей угрозой.",
poster = "http://pico.kartinka.shop/poster/item/big/72418.jpg",
rating = "8.2",
genres = listOf("Боевик", "Фантастика", "Фэнтези", "Приключения"),
actors = listOf("Том Хиддлстон", "Софи Ди Мартин", "Оуэн Уилсон"),
director = "Кейт Херон",
year = "2021",
duration = "50 мин.",
country = "США",
age = "16+",
type = "Сериал",
trailer = "https://www.youtube.com/watch?v=nW948Va-l10",
isFavorite = false,
)

private val infiniteWar = FilmResponse(
id = "2",
title = "Мстители: Война бесконечности",
description = "Пока Мстители и их союзники продолжают защищать мир от различных опасностей, с которыми не смог бы справиться один супергерой, новая угроза возникает из космоса: Танос. Межгалактический тиран преследует цель собрать все шесть Камней Бесконечности - артефакты невероятной силы, с помощью которых можно менять реальность по своему желанию. Всё, с чем Мстители сталкивались ранее, вело к этому моменту - судьба Земли никогда ещё не была столь неопределённой.",
poster = "http://pico.kartinka.shop/poster/item/big/34114.jpg",
rating = "8.4",
genres = listOf("Боевик", "Фантастика", "Фэнтези", "Приключения"),
actors = listOf("Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"),
director = "Энтони Руссо",
year = "2018",
duration = "149 мин.",
country = "США",
age = "12+",
type = "Фильм",
trailer = "https://www.youtube.com/watch?v=6ZfuNTqbHE8",
isFavorite = true,
)
private val lokiFilm = FilmResponse(
id = "1",
title = "Локи",
description = "Сразу же после кражи Тессеракта в фильме «Мстители: Финал» (2019), альтернативная версия Локи попадает в «Управление временны́ми изменениями» (УВИ), бюрократическую организацию, которая существует вне пространства и времени. Богу обмана предстоит ответить за свои преступления против времени и перед ним встаёт выбор: подвергнуться стиранию из реальности или помочь УВИ в борьбе с большей угрозой.",
poster = "http://pico.kartinka.shop/poster/item/big/72418.jpg",
rating = "8.2",
genres = listOf("Боевик", "Фантастика", "Фэнтези", "Приключения"),
actors = listOf("Том Хиддлстон", "Софи Ди Мартин", "Оуэн Уилсон"),
director = "Кейт Херон",
year = "2021",
duration = "50 мин.",
country = "США",
age = "16+",
type = "Сериал",
trailer = "https://www.youtube.com/watch?v=nW948Va-l10",
isFavorite = false,
)

private val rhinoFilm = FilmResponse(
id = "3",
title = "Вольт",
description = "Вольт — собака-полицейский, звезда телесериала, в котором он сражается с преступниками и спасает мир. Но когда камеры отключаются, Вольт не понимает, что происходит, и думает, что всё, что его окружает, настоящее. Когда его хозяйка Пенни похищают, Вольт отправляется в реальное путешествие, чтобы спасти её. На помощь ему приходят два необычных спутника — кот Мистер и хомяк Ролли.",
poster = "http://pico.kartinka.shop/poster/item/big/2570.jpg",
rating = "6.8",
genres = listOf("Комедия", "Фантастика", "Семейный", "Приключения", "Мультфильм"),
actors = listOf("Джон Траволта", "Майли Сайрус", "Сьюзи Эссман"),
director = "Байрон Ховард",
year = "2008",
duration = "96 мин.",
country = "США",
age = "6+",
type = "Фильм",
trailer = "https://www.youtube.com/watch?v=6ZfuNTqbHE8",
isFavorite = false,
)
private val infiniteWar = FilmResponse(
id = "2",
title = "Мстители: Война бесконечности",
description = "Пока Мстители и их союзники продолжают защищать мир от различных опасностей, с которыми не смог бы справиться один супергерой, новая угроза возникает из космоса: Танос. Межгалактический тиран преследует цель собрать все шесть Камней Бесконечности - артефакты невероятной силы, с помощью которых можно менять реальность по своему желанию. Всё, с чем Мстители сталкивались ранее, вело к этому моменту - судьба Земли никогда ещё не была столь неопределённой.",
poster = "http://pico.kartinka.shop/poster/item/big/34114.jpg",
rating = "8.4",
genres = listOf("Боевик", "Фантастика", "Фэнтези", "Приключения"),
actors = listOf("Роберт Дауни мл.", "Крис Хемсворт", "Марк Руффало"),
director = "Энтони Руссо",
year = "2018",
duration = "149 мин.",
country = "США",
age = "12+",
type = "Фильм",
trailer = "https://www.youtube.com/watch?v=6ZfuNTqbHE8",
isFavorite = true,
)

private val rhinoFilm = FilmResponse(
id = "3",
title = "Вольт",
description = "Вольт — собака-полицейский, звезда телесериала, в котором он сражается с преступниками и спасает мир. Но когда камеры отключаются, Вольт не понимает, что происходит, и думает, что всё, что его окружает, настоящее. Когда его хозяйка Пенни похищают, Вольт отправляется в реальное путешествие, чтобы спасти её. На помощь ему приходят два необычных спутника — кот Мистер и хомяк Ролли.",
poster = "http://pico.kartinka.shop/poster/item/big/2570.jpg",
rating = "6.8",
genres = listOf("Комедия", "Фантастика", "Семейный", "Приключения", "Мультфильм"),
actors = listOf("Джон Траволта", "Майли Сайрус", "Сьюзи Эссман"),
director = "Байрон Ховард",
year = "2008",
duration = "96 мин.",
country = "США",
age = "6+",
type = "Фильм",
trailer = "https://www.youtube.com/watch?v=6ZfuNTqbHE8",
isFavorite = false,
)

private val filmsList = listOf(lokiFilm, infiniteWar, rhinoFilm)
}
private val filmsList = listOf(lokiFilm, infiniteWar, rhinoFilm)
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,16 @@ abstract class BaseStore<S : State, E : Event, A : Action, N : Navigation>(

fun launch(
onError: suspend (Throwable) -> Unit = {},
onSuccess: suspend () -> Unit = {},
block: suspend CoroutineScope.() -> Unit,
): Job = screenModelScope.launch(
context = exceptionHandler(onError) + appDispatcher.default,
block = block
)
): Job = screenModelScope.launch(appDispatcher.default) {
runCatching { block() }
.onSuccess { onSuccess() }
.onFailure {
Logger.exception(it)
onError(it)
}
}

fun <T> launch(
action: suspend CoroutineScope.() -> T,
Expand Down
1 change: 1 addition & 0 deletions feature/film/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ kotlin {
implementation(project(":core:core"))
implementation(project(":core:ui"))
implementation(project(":core:network"))
implementation(project(":core:database"))
}
commonTest.dependencies {
implementation(libs.kotlin.test)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.stslex.feature.film.data.model

import com.stslex.core.database.sources.model.FilmEntity
import com.stslex.core.network.clients.film.model.FilmResponse

fun FilmResponse.toData() = FilmData(
Expand All @@ -18,4 +19,21 @@ fun FilmResponse.toData() = FilmData(
type = type,
trailer = trailer,
isFavorite = isFavorite
)

fun FilmData.toEntity(): FilmEntity = FilmEntity(
id = id,
title = title,
description = description,
poster = poster,
rating = rating,
duration = duration,
genres = genres,
actors = actors,
director = director,
country = country,
year = year,
age = age,
type = type,
trailer = trailer,
)
Loading
Loading