Skip to content

Commit

Permalink
detekt fixes for transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
makeevrserg committed Dec 2, 2024
1 parent 2e05301 commit 50ef64b
Show file tree
Hide file tree
Showing 14 changed files with 582 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class FileManagerDecomposeComponentImpl @AssistedInject constructor(
childFactory = ::child,
)

@Suppress("LongMethod")
private fun child(
config: FileManagerNavigationConfig,
componentContext: ComponentContext
Expand Down
1 change: 1 addition & 0 deletions components/filemngr/transfer/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ commonDependencies {
implementation(projects.components.filemngr.uiComponents)
implementation(projects.components.filemngr.transfer.api)
implementation(projects.components.filemngr.listing.api)
implementation(projects.components.filemngr.create.api)

implementation(projects.components.deeplink.api)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="fmt_otp_create_folder">Create Folder</string>
<string name="fmt_otp_display_list">List</string>
<string name="fmt_otp_display_grid">Grid</string>
<string name="fmt_otp_sort_default">Sort by Default</string>
<string name="fmt_otp_sort_size">Sort by Size</string>
<string name="fmt_otp_show_hidden">Show Hidden Files</string>

<string name="fmt_items_in_folder">%1$s items</string>

<string name="fmt_appbar_title_moving">Moving</string>
<string name="fmt_move_button">Move Here</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,54 +1,30 @@
package com.flipperdevices.filemanager.transfer.impl.api

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.childContext
import com.arkivanov.essenty.backhandler.BackCallback
import com.arkivanov.essenty.instancekeeper.getOrCreate
import com.flipperdevices.bridge.connection.feature.storage.api.model.FileType
import com.flipperdevices.core.di.AppGraph
import com.flipperdevices.core.ktx.jre.toFormattedSize
import com.flipperdevices.core.ui.ktx.OrangeAppBar
import com.flipperdevices.core.ui.ktx.elements.ComposableFlipperButton
import com.flipperdevices.filemanager.listing.api.model.ExtendedListingItem
import com.flipperdevices.filemanager.create.api.CreateFileDecomposeComponent
import com.flipperdevices.filemanager.transfer.api.TransferDecomposeComponent
import com.flipperdevices.filemanager.transfer.api.model.TransferType
import com.flipperdevices.filemanager.transfer.impl.composable.ComposableTransferScreen
import com.flipperdevices.filemanager.transfer.impl.viewmodel.FilesViewModel
import com.flipperdevices.filemanager.transfer.impl.viewmodel.OptionsViewModel
import com.flipperdevices.filemanager.transfer.impl.viewmodel.TransferViewModel
import com.flipperdevices.filemanager.ui.components.itemcard.FolderCardListComposable
import com.flipperdevices.filemanager.ui.components.itemcard.components.asPainter
import com.flipperdevices.filemanager.ui.components.itemcard.components.asTint
import com.flipperdevices.filemanager.ui.components.itemcard.model.ItemUiSelectionState
import com.flipperdevices.filemanager.ui.components.path.PathComposable
import com.flipperdevices.ui.decompose.DecomposeOnBackParameter
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import me.gulya.anvil.assisted.ContributesAssistedFactory
import okio.Path
import javax.inject.Provider

@Suppress("LongParameterList")
@ContributesAssistedFactory(AppGraph::class, TransferDecomposeComponent.Factory::class)
class TransferDecomposeComponentImpl @AssistedInject constructor(
@Assisted componentContext: ComponentContext,
Expand All @@ -57,14 +33,29 @@ class TransferDecomposeComponentImpl @AssistedInject constructor(
@Assisted private val onMoved: MovedCallback,
@Assisted private val onPathChange: PathChangedCallback,
filesViewModelFactory: FilesViewModel.Factory,
transferViewModelProvider: Provider<TransferViewModel>
transferViewModelProvider: Provider<TransferViewModel>,
optionsViewModelProvider: Provider<OptionsViewModel>,
createFileDecomposeComponentFactory: CreateFileDecomposeComponent.Factory,
) : TransferDecomposeComponent(componentContext) {
private val filesViewModel = instanceKeeper.getOrCreate("files_${param.path}") {
filesViewModelFactory.invoke(path = param.path)
}
private val transferViewModel = instanceKeeper.getOrCreate("transfer_${param.path}") {
transferViewModelProvider.get()
}
private val optionsViewModel = instanceKeeper.getOrCreate("options_${param.path}") {
optionsViewModelProvider.get()
}
private val createFileDecomposeComponent = createFileDecomposeComponentFactory.invoke(
componentContext = childContext("createfolder_${param.path}"),
createCallback = filesViewModel::onFolderCreated
)

// Folder should not be a subfolder of movable folder
// Folder should be the same as movable folder's parent
private val canMoveHere = param.fullPathToMove
.all { path -> !param.path.toString().startsWith(path.toString()) }
.and(param.fullPathToMove.all { path -> param.path != path.parent })

private val backCallback = BackCallback {
val parent = param.path.parent
Expand All @@ -85,123 +76,31 @@ class TransferDecomposeComponentImpl @AssistedInject constructor(
LaunchedEffect(transferViewModel) {
transferViewModel.state
.filterIsInstance<TransferViewModel.State.Moved>()
.onEach { state ->
onMoved.invoke(state.targetDir)
}
.onEach { state -> onMoved.invoke(state.targetDir) }
.launchIn(this)
}

val optionsState by optionsViewModel.state.collectAsState()
val state by filesViewModel.state.collectAsState()
val transferState by transferViewModel.state.collectAsState()
val isMoving = transferState is TransferViewModel.State.Moving
Scaffold(
modifier = Modifier.fillMaxSize(),
topBar = {
OrangeAppBar(
title = when (param.transferType) {
TransferType.MOVE -> "Moving"
},
onBack = onBack::invoke
ComposableTransferScreen(
optionsState = optionsState,
state = state,
isMoving = isMoving,
canMoveHere = canMoveHere,
param = param,
onBack = onBack::invoke,
onOptionsAction = optionsViewModel::onAction,
onCreateFolder = { createFileDecomposeComponent.startCreateFolder(param.path) },
onPathChange = onPathChange::invoke,
onMoveStart = {
transferViewModel.move(
oldPaths = param.fullPathToMove,
targetDir = param.path
)
}
) { contentPaddings ->
LazyVerticalGrid(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalArrangement = Arrangement.spacedBy(4.dp),
contentPadding = PaddingValues(14.dp),
columns = GridCells.Fixed(1)
) {
item(span = { GridItemSpan(maxLineSpan) }) {
PathComposable(
path = param.path,
onRootPathClick = onRootPathClick@{
if (isMoving) return@onRootPathClick
param.path.root?.run(onPathChange::invoke)
},
onPathClick = onPathClick@{ path ->
if (isMoving) return@onPathClick
onPathChange.invoke(path)
},
modifier = Modifier
.fillMaxWidth()
.padding(14.dp)
)
}

when (val localState = state) {
FilesViewModel.State.CouldNotListPath -> {
item(
span = { GridItemSpan(maxLineSpan) },
content = { Box(Modifier.fillMaxSize().background(Color.Red)) }
)
}

is FilesViewModel.State.Loaded -> {
items(localState.files) { file ->
FolderCardListComposable(
painter = file.asListingItem().asPainter(),
iconTint = file.asListingItem().asTint(),
title = file.itemName,
subtitle = when (file) {
is ExtendedListingItem.File -> file.size.toFormattedSize()
is ExtendedListingItem.Folder -> "items ${file.itemsCount ?: 0}"
},
isSubtitleLoading = when (file) {
is ExtendedListingItem.File -> false
is ExtendedListingItem.Folder -> file.itemsCount == null
},
selectionState = ItemUiSelectionState.NONE,
onClick = onClick@{
if (file.itemType != FileType.DIR) return@onClick
if (isMoving) return@onClick
onPathChange.invoke(param.path.resolve(file.itemName))
},
onCheckChange = null,
onMoreClick = null
)
}
item {
Box(Modifier.height(32.dp))
}
}

FilesViewModel.State.Loading -> {
item(
span = { GridItemSpan(maxLineSpan) },
content = { Box(Modifier.fillMaxSize().background(Color.Blue)) }
)
}

FilesViewModel.State.Unsupported -> {
item(
span = { GridItemSpan(maxLineSpan) },
content = { Box(Modifier.fillMaxSize().background(Color.Magenta)) }
)
}
}
}

Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.BottomCenter,
content = {
ComposableFlipperButton(
text = "Move Here",
modifier = Modifier.fillMaxWidth(),
isLoading = isMoving,
enabled = !isMoving &&
!param.fullPathToMove.contains(param.path) &&
!param.fullPathToMove.mapNotNull(Path::parent).contains(param.path),
onClick = {
transferViewModel.move(
oldPaths = param.fullPathToMove,
targetDir = param.path
)
}
)
}
)
}
},
)
createFileDecomposeComponent.Render()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package com.flipperdevices.filemanager.transfer.impl.composable

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.flipperdevices.core.preference.pb.FileManagerOrientation
import com.flipperdevices.filemanager.transfer.api.TransferDecomposeComponent.Param
import com.flipperdevices.filemanager.transfer.impl.viewmodel.FilesViewModel
import com.flipperdevices.filemanager.transfer.impl.viewmodel.OptionsViewModel
import com.flipperdevices.filemanager.ui.components.itemcard.FolderCardPlaceholderComposable
import okio.Path

@Suppress("LongMethod")
@Composable
fun ComposableTransferScreen(
optionsState: OptionsViewModel.State,
state: FilesViewModel.State,
isMoving: Boolean,
canMoveHere: Boolean,
param: Param,
onBack: () -> Unit,
onOptionsAction: (OptionsViewModel.Action) -> Unit,
onCreateFolder: () -> Unit,
onPathChange: (Path) -> Unit,
onMoveStart: () -> Unit,
modifier: Modifier = Modifier
) {
Scaffold(
modifier = modifier.fillMaxSize(),
topBar = {
TransferAppBar(
transferType = param.transferType,
onBack = onBack,
optionsState = optionsState,
onOptionsAction = onOptionsAction,
onCreateFolder = onCreateFolder
)
}
) { contentPaddings ->
LazyVerticalGrid(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalArrangement = Arrangement.spacedBy(4.dp),
contentPadding = PaddingValues(14.dp),
columns = when (optionsState.orientation) {
FileManagerOrientation.GRID -> GridCells.Fixed(2)
is FileManagerOrientation.Unrecognized,
FileManagerOrientation.LIST -> GridCells.Fixed(1)
}
) {
item(span = { GridItemSpan(maxLineSpan) }) {
TransferPathComposable(
isMoving = isMoving,
path = param.path,
onPathChange = onPathChange
)
}

when (val localState = state) {
FilesViewModel.State.CouldNotListPath -> {
item(
span = { GridItemSpan(maxLineSpan) },
content = { Box(Modifier.fillMaxSize().background(Color.Red)) }
)
}

is FilesViewModel.State.Loaded -> {
items(localState.files) { item ->
TransferFolderCardListComposable(
modifier = Modifier.animateItem(),
fullDirPath = param.path,
item = item,
onPathChange = onPathChange,
isMoving = isMoving
)
}
item(
span = { GridItemSpan(maxLineSpan) },
content = { Box(Modifier.height(32.dp)) }
)
}

FilesViewModel.State.Loading -> {
items(count = 6) {
FolderCardPlaceholderComposable(
modifier = Modifier
.fillMaxWidth()
.animateItem(),
orientation = optionsState.orientation,
)
}
}

FilesViewModel.State.Unsupported -> {
item(
span = { GridItemSpan(maxLineSpan) },
content = { UnsupportedComposable() }
)
}
}
}
FullScreenMoveButtonComposable(
isLoading = isMoving,
isEnabled = !isMoving && canMoveHere,
onClick = onMoveStart
)
}
}
Loading

0 comments on commit 50ef64b

Please sign in to comment.