Skip to content

Commit

Permalink
init follower screen
Browse files Browse the repository at this point in the history
  • Loading branch information
stslex committed Jan 31, 2024
1 parent fa863a9 commit 10ae445
Show file tree
Hide file tree
Showing 21 changed files with 451 additions and 2 deletions.
1 change: 1 addition & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ kotlin {
implementation(project(":feature:profile"))
implementation(project(":feature:match_feed"))
implementation(project(":feature:auth"))
implementation(project(":feature:follower"))
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions composeApp/src/commonMain/kotlin/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.stslex.core.ui.theme.AppTheme
import com.stslex.feature.auth.di.featureAuthModule
import com.stslex.feature.film.di.featureFilmModule
import com.stslex.feature.film_feed.di.featureFeedModule
import com.stslex.feature.follower.di.featureFollowerModule
import com.stslex.feature.match_feed.di.featureMatchFeedModule
import com.stslex.feature.profile.di.featureProfileModule
import di.appModule
Expand Down Expand Up @@ -42,6 +43,7 @@ private fun KoinApplication.setupCommonModules() {
featureProfileModule,
featureMatchFeedModule,
featureAuthModule,
featureFollowerModule
)
)
}
19 changes: 17 additions & 2 deletions composeApp/src/commonMain/kotlin/navigator/AppNavigatorImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import com.stslex.core.ui.navigation.AppNavigator
import com.stslex.core.ui.navigation.AppScreen
import com.stslex.feature.auth.ui.AuthScreen
import com.stslex.feature.film.ui.FilmScreen
import com.stslex.feature.follower.ui.FollowerScreen
import com.stslex.feature.follower.ui.FollowerScreenArgs
import com.stslex.feature.match_feed.ui.MatchFeedScreen
import main_screen.MainScreen

Expand Down Expand Up @@ -37,8 +39,21 @@ class AppNavigatorImpl : AppNavigator {
is AppScreen.Film -> navigator.push(FilmScreen(screen.id))
AppScreen.MatchFeed -> navigator.push(MatchFeedScreen)
is AppScreen.Favourite -> TODO()
is AppScreen.Followers -> TODO()
is AppScreen.Following -> TODO()
is AppScreen.Followers -> navigator.push(
FollowerScreen(
args = FollowerScreenArgs.Follower(
uuid = screen.uuid
)
)
)

is AppScreen.Following -> navigator.push(
FollowerScreen(
args = FollowerScreenArgs.Following(
uuid = screen.uuid
)
)
)
}
}
}
66 changes: 66 additions & 0 deletions feature/follower/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidLibrary)
alias(libs.plugins.jetbrainsCompose)
alias(libs.plugins.kotlinCocoapods)
}

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

jvm("desktop")

iosX64()
iosArm64()
iosSimulatorArm64()
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
version = "1.0"
ios.deploymentTarget = "16.0"
podfile =
project.file(project.rootProject.projectDir.path + "/iosApp/FeatureFollowerPodfile")
framework {
baseName = "featureFollower"
}
}

sourceSets {
commonMain.dependencies {
implementation(project(":core:core"))
implementation(project(":core:ui"))
implementation(project(":core:network"))
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
}
}

android {
namespace = "com.stslex.feature.follower"
compileSdk = libs.versions.android.compileSdk.get().toInt()
defaultConfig {
minSdk = libs.versions.android.minSdk.get().toInt()
}
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
compilerOptions.freeCompilerArgs.addAll(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=$projectDir/build/compose/metrics",
)
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
compilerOptions.freeCompilerArgs.addAll(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=$projectDir/build/compose/reports",
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.stslex.feature.follower.data.model

import com.stslex.core.network.clients.profile.model.UserFollowerResponse

fun UserFollowerResponse.toData(): List<FollowerDataModel> = this
.result
.map { response ->
FollowerDataModel(
uuid = response.uuid,
username = response.username,
avatarUrl = response.avatarUrl,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.stslex.feature.follower.data.model

data class FollowerDataModel(
val uuid: String,
val username: String,
val avatarUrl: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.stslex.feature.follower.data.repository

import com.stslex.feature.follower.data.model.FollowerDataModel
import kotlinx.coroutines.flow.Flow

interface FollowerRepository {

fun getFollowers(
uuid: String,
page: Int,
pageSize: Int
): Flow<List<FollowerDataModel>>

fun getFollowing(
uuid: String,
page: Int,
pageSize: Int
): Flow<List<FollowerDataModel>>
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.stslex.feature.follower.data.repository

import com.stslex.core.network.clients.profile.client.ProfileClient
import com.stslex.feature.follower.data.model.FollowerDataModel
import com.stslex.feature.follower.data.model.toData
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow

class FollowerRepositoryImpl(
private val client: ProfileClient
) : FollowerRepository {

override fun getFollowers(
uuid: String,
page: Int,
pageSize: Int
): Flow<List<FollowerDataModel>> = flow {
val result = client.getFollowers(
uuid = uuid,
page = page,
pageSize = pageSize
).toData()
emit(result)
}

override fun getFollowing(
uuid: String,
page: Int,
pageSize: Int
): Flow<List<FollowerDataModel>> = flow {
val result = client.getFollowing(
uuid = uuid,
page = page,
pageSize = pageSize
).toData()
emit(result)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.stslex.feature.follower.di

import com.stslex.feature.follower.data.repository.FollowerRepository
import com.stslex.feature.follower.data.repository.FollowerRepositoryImpl
import com.stslex.feature.follower.domain.interactor.FollowerInteractor
import com.stslex.feature.follower.domain.interactor.FollowerInteractorImpl
import com.stslex.feature.follower.navigation.FollowerRouter
import com.stslex.feature.follower.navigation.FollowerRouterImpl
import com.stslex.feature.follower.ui.store.FollowerStore
import org.koin.dsl.module

val featureFollowerModule = module {

factory<FollowerRepository> {
FollowerRepositoryImpl(
api = get()
)
}

factory<FollowerInteractor> {
FollowerInteractorImpl(
repository = get()
)
}

factory<FollowerRouter> { FollowerRouterImpl(navigator = get()) }

factory {
FollowerStore(
interactor = get(),
appDispatcher = get(),
router = get(),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.stslex.feature.follower.domain.interactor

import com.stslex.feature.follower.ui.model.FollowerModel
import kotlinx.coroutines.flow.Flow

interface FollowerInteractor {

fun getFollowers(
uuid: String,
page: Int,
pageSize: Int
): Flow<List<FollowerModel>>

fun getFollowing(
uuid: String,
page: Int,
pageSize: Int
): Flow<List<FollowerModel>>
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.stslex.feature.follower.domain.interactor

import com.stslex.feature.follower.data.repository.FollowerRepository
import com.stslex.feature.follower.domain.model.toUI
import com.stslex.feature.follower.ui.model.FollowerModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

class FollowerInteractorImpl(
private val repository: FollowerRepository
) : FollowerInteractor {

override fun getFollowers(
uuid: String,
page: Int, pageSize: Int
): Flow<List<FollowerModel>> = repository
.getFollowers(
uuid = uuid,
page = page,
pageSize = pageSize
)
.map { it.toUI() }

override fun getFollowing(
uuid: String,
page: Int,
pageSize: Int
): Flow<List<FollowerModel>> = repository
.getFollowing(
uuid = uuid,
page = page,
pageSize = pageSize
)
.map { it.toUI() }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.stslex.feature.follower.domain.model

import com.stslex.feature.follower.data.model.FollowerDataModel
import com.stslex.feature.follower.ui.model.FollowerModel

fun List<FollowerDataModel>.toUI(): List<FollowerModel> = map { it.toUI() }

fun FollowerDataModel.toUI(): FollowerModel = FollowerModel(
uuid = uuid,
username = username,
avatarUrl = avatarUrl,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.stslex.feature.follower.navigation

import com.stslex.core.ui.navigation.Router
import com.stslex.feature.follower.ui.store.FollowerStoreComponent.Navigation

interface FollowerRouter : Router<Navigation>

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.stslex.feature.follower.navigation

import com.stslex.core.ui.navigation.AppNavigator
import com.stslex.feature.follower.ui.store.FollowerStoreComponent

class FollowerRouterImpl(
private val navigator: AppNavigator
) : FollowerRouter {

override fun invoke(event: FollowerStoreComponent.Navigation) {
TODO("Not yet implemented")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.stslex.feature.follower.ui

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel
import com.stslex.feature.follower.ui.store.FollowerStore
import com.stslex.feature.follower.ui.store.FollowerStoreComponent.Action
import com.stslex.feature.follower.ui.store.FollowerStoreComponent.State

data class FollowerScreen(
val args: FollowerScreenArgs
) : Screen {

@Composable
override fun Content() {
val store = getScreenModel<FollowerStore>()
val state by remember { store.state }.collectAsState()

LaunchedEffect(key1 = Unit) {
store.sendAction(Action.Init(args = args))
}

FollowerScreen(
state = state,
onAction = store::sendAction
)
}
}


@Composable
internal fun FollowerScreen(
state: State,
onAction: (Action) -> Unit
) {
Text("test")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.stslex.feature.follower.ui

sealed interface FollowerScreenArgs {

data class Follower(
val uuid: String
) : FollowerScreenArgs

data class Following(
val uuid: String
) : FollowerScreenArgs
}
Loading

0 comments on commit 10ae445

Please sign in to comment.