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

Refactor rename and file creation modules #995

Merged
merged 5 commits into from
Dec 2, 2024
Merged
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

- [Feature] Add count subfolders for new file manager
- [Feature] Add file downloading for new file manager
- [Refactor] Move rename and file create to separated modules
- [FIX] Migrate url host from metric.flipperdevices.com to metric.flipp.dev
- [FIX] Fix empty response in faphub category
- [FIX] New file manager uploading progress
Expand Down
4 changes: 4 additions & 0 deletions components/bridge/connection/sample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ dependencies {
implementation(projects.components.filemngr.editor.impl)
implementation(projects.components.filemngr.download.api)
implementation(projects.components.filemngr.download.impl)
implementation(projects.components.filemngr.rename.api)
implementation(projects.components.filemngr.rename.impl)
implementation(projects.components.filemngr.create.api)
implementation(projects.components.filemngr.create.impl)

implementation(projects.components.newfilemanager.api)
implementation(projects.components.newfilemanager.impl)
Expand Down
17 changes: 17 additions & 0 deletions components/filemngr/create/api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
plugins {
id("flipper.multiplatform")
id("flipper.multiplatform-dependencies")
}

android.namespace = "com.flipperdevices.filemanager.create.api"

commonDependencies {
implementation(projects.components.bridge.connection.feature.storage.api)

implementation(projects.components.core.ui.decompose)

implementation(libs.compose.ui)
implementation(libs.decompose)

implementation(libs.okio)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.flipperdevices.filemanager.create.api

import com.arkivanov.decompose.ComponentContext
import com.flipperdevices.bridge.connection.feature.storage.api.model.FileType
import com.flipperdevices.bridge.connection.feature.storage.api.model.ListingItem
import com.flipperdevices.ui.decompose.ScreenDecomposeComponent
import kotlinx.coroutines.flow.StateFlow
import okio.Path

abstract class CreateFileDecomposeComponent(
componentContext: ComponentContext
) : ScreenDecomposeComponent(componentContext) {
abstract val canCreateFiles: StateFlow<Boolean>

abstract fun startCreateFile(parent: Path)

abstract fun startCreateFolder(parent: Path)

abstract fun startCreate(parent: Path, type: FileType)

fun interface Factory {
operator fun invoke(
componentContext: ComponentContext,
createCallback: CreatedCallback,
): CreateFileDecomposeComponent
}

fun interface CreatedCallback {
fun invoke(item: ListingItem)
}
}
52 changes: 52 additions & 0 deletions components/filemngr/create/impl/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
plugins {
id("flipper.multiplatform-compose")
id("flipper.multiplatform-dependencies")
id("flipper.anvil-multiplatform")
id("kotlinx-serialization")
}
android.namespace = "com.flipperdevices.filemanager.create.impl"

commonDependencies {
implementation(projects.components.core.di)
implementation(projects.components.core.ktx)
implementation(projects.components.core.log)
implementation(projects.components.core.preference)

implementation(projects.components.core.ui.lifecycle)
implementation(projects.components.core.ui.theme)
implementation(projects.components.core.ui.decompose)
implementation(projects.components.core.ui.ktx)
implementation(projects.components.core.ui.res)
implementation(projects.components.core.ui.dialog)

implementation(projects.components.bridge.connection.feature.common.api)
implementation(projects.components.bridge.connection.transport.common.api)
implementation(projects.components.bridge.connection.feature.provider.api)
implementation(projects.components.bridge.connection.feature.storage.api)
implementation(projects.components.bridge.connection.feature.storageinfo.api)
implementation(projects.components.bridge.connection.feature.serialspeed.api)
implementation(projects.components.bridge.connection.feature.rpcinfo.api)
implementation(projects.components.bridge.dao.api)

implementation(projects.components.filemngr.util)
implementation(projects.components.filemngr.uiComponents)
implementation(projects.components.filemngr.create.api)

// Compose
implementation(libs.compose.ui)
implementation(libs.compose.tooling)
implementation(libs.compose.foundation)
implementation(libs.compose.material)

implementation(libs.kotlin.serialization.json)
implementation(libs.ktor.client)

implementation(libs.decompose)
implementation(libs.kotlin.coroutines)
implementation(libs.essenty.lifecycle)
implementation(libs.essenty.lifecycle.coroutines)

implementation(libs.bundles.decompose)
implementation(libs.okio)
implementation(libs.kotlin.immutable.collections)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="fmc_create_file_title">Enter Name:</string>
<string name="fml_create_file_btn">Create File</string>
<string name="fml_create_folder_btn">Create Folder</string>
<string name="fmc_create_file_allowed_chars">Allowed characters: %1$s</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.flipperdevices.filemanager.create.impl.api

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import com.arkivanov.decompose.ComponentContext
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.filemanager.create.api.CreateFileDecomposeComponent
import com.flipperdevices.filemanager.create.impl.viewmodel.CreateFileViewModel
import com.flipperdevices.filemanager.ui.components.name.NameDialog
import com.flipperdevices.filemanager.util.constant.FileManagerConstants
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import flipperapp.components.filemngr.create.impl.generated.resources.fmc_create_file_allowed_chars
import flipperapp.components.filemngr.create.impl.generated.resources.fmc_create_file_title
import flipperapp.components.filemngr.create.impl.generated.resources.fml_create_file_btn
import flipperapp.components.filemngr.create.impl.generated.resources.fml_create_folder_btn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import me.gulya.anvil.assisted.ContributesAssistedFactory
import okio.Path
import org.jetbrains.compose.resources.stringResource
import javax.inject.Provider
import flipperapp.components.filemngr.create.impl.generated.resources.Res as FMC

@ContributesAssistedFactory(AppGraph::class, CreateFileDecomposeComponent.Factory::class)
class CreateFileDecomposeComponentImpl @AssistedInject constructor(
@Assisted componentContext: ComponentContext,
@Assisted val createdCallback: CreatedCallback,
renameViewModelProvider: Provider<CreateFileViewModel>
) : CreateFileDecomposeComponent(componentContext) {
private val createFileViewModel = instanceKeeper.getOrCreate {
renameViewModelProvider.get()
}

override val canCreateFiles = createFileViewModel.canCreateFiles

override fun startCreateFile(parent: Path) {
createFileViewModel.startCreateFile(parent)
}

override fun startCreateFolder(parent: Path) {
createFileViewModel.startCreateFolder(parent)
}

override fun startCreate(parent: Path, type: FileType) {
createFileViewModel.startCreate(parent, type)
}

@Composable
override fun Render() {
val state by createFileViewModel.state.collectAsState()
LaunchedEffect(createFileViewModel) {
createFileViewModel.event
.onEach { event ->
when (event) {
is CreateFileViewModel.Event.Created -> {
createdCallback.invoke(event.item)
}
}
}.launchIn(this)
}
when (val localState = state) {
CreateFileViewModel.State.Pending -> Unit
is CreateFileViewModel.State.Creating -> {
NameDialog(
value = localState.name,
title = stringResource(FMC.string.fmc_create_file_title),
buttonText = when (localState.type) {
FileType.FILE -> stringResource(FMC.string.fml_create_file_btn)
FileType.DIR -> stringResource(FMC.string.fml_create_folder_btn)
},
subtitle = stringResource(
FMC.string.fmc_create_file_allowed_chars,
FileManagerConstants.FILE_NAME_AVAILABLE_CHARACTERS
),
onFinish = createFileViewModel::onConfirm,
isError = !localState.isValid,
isEnabled = !localState.isCreating,
needShowOptions = localState.needShowOptions,
onTextChange = createFileViewModel::onNameChange,
onDismissRequest = createFileViewModel::dismiss,
onOptionSelect = createFileViewModel::onOptionSelected,
options = localState.options
)
}
}
}
}
Loading
Loading