Skip to content

Commit

Permalink
Refactor: Explore 화면 MVI 변경
Browse files Browse the repository at this point in the history
  • Loading branch information
Guri999 committed Jan 9, 2025
1 parent 6ad37ef commit 4c82296
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 29 deletions.
14 changes: 14 additions & 0 deletions feature/explore/src/main/java/kr/co/di/ExploreModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package kr.co.di

import kr.co.explore.ExploreViewModel
import org.koin.core.module.dsl.viewModel
import org.koin.dsl.module

val exploreModule =
module {
viewModel {
ExploreViewModel(
get()
)
}
}
75 changes: 46 additions & 29 deletions feature/explore/src/main/java/kr/co/explore/ExploreScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,56 +13,59 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kr.co.model.ExploreSideEffect
import kr.co.model.ExploreUiIntent
import kr.co.model.ExploreUiState
import kr.co.model.FileInfo
import kr.co.seedocs.feature.explore.R
import kr.co.ui.theme.SeeDocsTheme
import kr.co.ui.theme.Theme
import kr.co.ui.util.LaunchIntentHandler
import kr.co.ui.util.LaunchSideEffect
import kr.co.ui.widget.FileBox
import kr.co.util.DEFAULT_STORAGE
import kr.co.util.readPDFOrDirectory
import kr.co.widget.FolderBox
import org.koin.androidx.compose.koinViewModel

@Composable
internal fun ExploreRoute(
path: String,
padding: PaddingValues,
navigateToFolder: (String) -> Unit = {},
navigateToPdf: (String) -> Unit = {},
viewModel: ExploreViewModel = koinViewModel(),
) {
var files by remember { mutableStateOf<List<FileInfo>>(emptyList()) }
val state by viewModel.uiState.collectAsStateWithLifecycle()

LaunchedEffect(Unit) {
files = readPDFOrDirectory(path)
LaunchIntentHandler(ExploreUiIntent.Init(path), viewModel)

LaunchSideEffect(viewModel) {
when (it) {
is ExploreSideEffect.NavigateToPdf -> navigateToPdf(it.path)
is ExploreSideEffect.NavigateToFolder -> navigateToFolder(it.path)
}
}

ExploreScreen(
path = path.replace(DEFAULT_STORAGE,
stringResource(R.string.feature_explore_local_storage)),
files = files,
state = state,
padding = padding,
onFolderClick = { folderPath -> navigateToFolder(folderPath) },
onFileClick = navigateToPdf
handleIntent = viewModel::handleIntent,
)
}

@Composable
private fun ExploreScreen(
path: String,
files: List<FileInfo> = emptyList(),
state: ExploreUiState = ExploreUiState.INIT,
padding: PaddingValues,
onFolderClick: (String) -> Unit = {},
onFileClick: (String) -> Unit = {}
handleIntent: (ExploreUiIntent) -> Unit = {},
) {
Box(
modifier = Modifier
Expand Down Expand Up @@ -93,13 +96,28 @@ private fun ExploreScreen(
)
Text(
text = buildAnnotatedString {
append(">${path.split("/").dropLast(1).joinToString(separator = "/")}")
append("/")
withStyle(
Theme.typography.caption1r.copy(color = Theme.colors.highlight)
.toSpanStyle()
) {
append(path.split("/").last())
val relativePath = state.path.replace(
DEFAULT_STORAGE,
stringResource(R.string.feature_explore_local_storage)
)
val pathSegments = relativePath.split("/")

if (pathSegments.size <= 1) {
withStyle(
Theme.typography.caption1r.copy(color = Theme.colors.highlight).toSpanStyle()
) {
append("> ${pathSegments.first()}")
}
} else {
append("> ")
pathSegments.dropLast(1).forEach { segment ->
append("$segment/")
}
withStyle(
Theme.typography.caption1r.copy(color = Theme.colors.highlight).toSpanStyle()
) {
append(pathSegments.last())
}
}
},
style = Theme.typography.caption1r,
Expand All @@ -108,21 +126,21 @@ private fun ExploreScreen(
}
}

items(files.filter { it.isDirectory }) { folder ->
items(state.files.filter { it.isDirectory }) { folder ->
FolderBox(
name = folder.name,
onClick = { onFolderClick(folder.path) }
onClick = { handleIntent(ExploreUiIntent.ClickFolder(folder)) }
)
}

items(
items = files.filter { !it.isDirectory },
items = state.files.filter { !it.isDirectory },
span = { GridItemSpan(maxLineSpan) }
) { file ->
FileBox(
name = file.name,
dateTime = file.createdAt,
onFileClick = { onFileClick(file.path) }
onFileClick = { handleIntent(ExploreUiIntent.ClickFile(file)) }
)
}
}
Expand All @@ -134,7 +152,6 @@ private fun ExploreScreen(
private fun Preview() {
SeeDocsTheme {
ExploreScreen(
path = DEFAULT_STORAGE,
padding = PaddingValues(),
)
}
Expand Down
45 changes: 45 additions & 0 deletions feature/explore/src/main/java/kr/co/explore/ExploreViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package kr.co.explore

import kr.co.data.repository.RecentRepository
import kr.co.model.ExploreSideEffect
import kr.co.model.ExploreUiIntent
import kr.co.model.ExploreUiState
import kr.co.model.FileInfo
import kr.co.ui.base.BaseMviViewModel
import kr.co.util.readPDFOrDirectory

internal class ExploreViewModel(
private val recentRepository: RecentRepository,
) :
BaseMviViewModel<ExploreUiState, ExploreUiIntent, ExploreSideEffect>(ExploreUiState.INIT) {

override fun handleIntent(intent: ExploreUiIntent) {
when (intent) {
is ExploreUiIntent.Init -> init(intent.path)
is ExploreUiIntent.ClickFile -> onClickFile(intent.file)
is ExploreUiIntent.ClickFolder -> onClickFolder(intent.folder)
}
}

private fun init(path: String) = launch {
path.debugLog("path")
readPDFOrDirectory(path).let {
reduce {
copy(
path = path,
files = it
)
}
}
}

private fun onClickFile(file: FileInfo) = launch {
recentRepository.insert(file)
}.invokeOnCompletion {
postSideEffect(ExploreSideEffect.NavigateToPdf(file.path))
}

private fun onClickFolder(folder: FileInfo) =
postSideEffect(ExploreSideEffect.NavigateToFolder(folder.path))

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package kr.co.model

import kr.co.ui.base.UiSideEffect

internal sealed interface ExploreSideEffect: UiSideEffect {
data class NavigateToFolder(val path: String) : ExploreSideEffect
data class NavigateToPdf(val path: String) : ExploreSideEffect
}
9 changes: 9 additions & 0 deletions feature/explore/src/main/java/kr/co/model/ExploreUiIntent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package kr.co.model

import kr.co.ui.base.UiIntent

internal sealed interface ExploreUiIntent: UiIntent {
data class Init(val path: String): ExploreUiIntent
data class ClickFile(val file: FileInfo): ExploreUiIntent
data class ClickFolder(val folder: FileInfo): ExploreUiIntent
}
15 changes: 15 additions & 0 deletions feature/explore/src/main/java/kr/co/model/ExploreUiState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package kr.co.model

import kr.co.ui.base.UiState

internal data class ExploreUiState(
val path: String,
val files: List<FileInfo>,
): UiState {
companion object {
val INIT = ExploreUiState(
path = "",
files = emptyList(),
)
}
}
2 changes: 2 additions & 0 deletions feature/main/src/main/java/kr/co/main/di/MainModule.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package kr.co.main.di

import kr.co.di.bookmarkModule
import kr.co.di.exploreModule
import kr.co.di.recentModule
import kr.co.di.pdfModule
import org.koin.dsl.module

val mainModule =
module {
includes(
exploreModule,
recentModule,
bookmarkModule,
pdfModule,
Expand Down

0 comments on commit 4c82296

Please sign in to comment.