Skip to content

Commit

Permalink
feat: New folder
Browse files Browse the repository at this point in the history
  • Loading branch information
jing332 committed Feb 3, 2024
1 parent daedc20 commit 6f2467c
Show file tree
Hide file tree
Showing 11 changed files with 273 additions and 128 deletions.
Original file line number Diff line number Diff line change
@@ -1,25 +1,51 @@
package com.github.jing332.filepicker

import android.widget.Toast
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import kotlin.math.max

data class NavBarItem(val name: String, val path: String)

fun toNavBarItems(
rootPath: String,
rootName: String = "root",
path: String,
separator: String = "/"
): List<NavBarItem> {
val items = mutableListOf<NavBarItem>()
var currentPath = rootPath
items.add(NavBarItem(rootName, rootPath))

val paths = path.removePrefix(rootPath).split(separator).filter { it.isNotEmpty() }
for (p in paths) {
currentPath += separator + p
items.add(NavBarItem(p, currentPath))
}
return items
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun FileNavBar(
Expand All @@ -29,20 +55,36 @@ fun FileNavBar(
onClick: (NavBarItem) -> Unit,
) {
LaunchedEffect(key1 = list.size) {
state.animateScrollToItem(list.size - 1)
state.animateScrollToItem(max(0, list.size - 1))
}

val context = LocalContext.current
LazyRow(modifier, state = state) {
itemsIndexed(list) { index, item ->
Row(
modifier = Modifier.animateItemPlacement(),
verticalAlignment = Alignment.CenterVertically
) {
TextButton(
onClick = { onClick(item) },
contentPadding = PaddingValues(horizontal = 2.dp)
Surface(
modifier = Modifier
.clip(MaterialTheme.shapes.extraSmall)
.combinedClickable(
onClick = {
onClick(item)
},
onLongClick = {
Toast
.makeText(context, item.path, Toast.LENGTH_SHORT)
.show()
}
),
) {
Text(text = item.name)
Text(
modifier = Modifier
.padding(2.dp)
.defaultMinSize(minWidth = 48.dp, minHeight = 24.dp),
text = item.name,
textAlign = TextAlign.Center
)
}

if (index != list.size - 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.util.Log
import android.widget.Toast
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
Expand Down Expand Up @@ -71,9 +72,17 @@ private fun PermissionGrant() {
@Composable
fun FilePicker(
modifier: Modifier = Modifier,
initialPath: String = Environment.getExternalStorageDirectory().path,
rootName: String = "root",
rootPath: String = Environment.getExternalStorageDirectory().path,
initialPath: String = rootPath,
state: FilePickerState = rememberNavController().run {
remember { FilePickerState(initialPath, this) }
remember {
FilePickerState(
rootPath = rootPath,
initialPath = initialPath,
navController = this
)
}
},
config: FilePickerConfiguration = remember { FilePickerConfiguration() },
onConfirmSelect: (List<IFileModel>) -> Unit,
Expand All @@ -87,11 +96,11 @@ fun FilePicker(
}
},
) {
val context = LocalContext.current
val navController = state.navController
val navBarItems = remember { mutableStateListOf<NavBarItem>() }

fun popBack() {
navBarItems.remove(navBarItems.last())
navController.popBackStack()
}

Expand Down Expand Up @@ -119,6 +128,23 @@ fun FilePicker(
onConfirmSelect = {
onConfirmSelect(state.currentListState?.items?.filter { it.isChecked.value }
?.map { it.model } ?: emptyList())
},
onNewFolder = {
try {
state.currentListState?.createNewFolder(it)
state.reload()
} catch (e: SecurityException) {
Log.e(TAG, "createNewFolder", e)
Toast.makeText(
context,
"权限不足:${e.localizedMessage ?: ""}",
Toast.LENGTH_LONG
).show()
} catch (e: Exception) {
Log.e(TAG, "createNewFolder", e)
Toast.makeText(context, "失败:${e.localizedMessage ?: ""}", Toast.LENGTH_LONG)
.show()
}
}
)

Expand Down Expand Up @@ -150,6 +176,11 @@ fun FilePicker(

LaunchedEffect(key1 = Unit) {
state.currentPath = path
toNavBarItems(
rootPath = rootPath,
rootName = rootName,
path = path
).also { navBarItems.clear(); navBarItems.addAll(it) }
}
BackHandler(path != initialPath) {
popBack()
Expand All @@ -159,13 +190,16 @@ fun FilePicker(
}

val file = File(path)
if (navBarItems.isEmpty())
navBarItems.add(NavBarItem(name = file.name, path = file.path))
FileListPage(
file = NormalFile(file),
state = fileListState,
config = config,
onBack = { popBack() },
onBack = {
if (fileListState.hasChecked()) {
state.currentListState?.uncheckAll()
} else
popBack()
},
onEnter = { enterFile ->
if (onEnterDirectory(enterFile))
navBarItems += NavBarItem(name = enterFile.name, path = enterFile.path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import androidx.navigation.NavHostController
import com.github.jing332.filepicker.listpage.FileListPageState
import com.github.jing332.filepicker.utils.navigate

data class FilePickerState(val initialPath: String, val navController: NavHostController) {
data class FilePickerState(
val rootPath: String,
val initialPath: String,
val navController: NavHostController
) {
// var currentModel by mutableStateOf<IFileModel?>(null)
var currentPath by mutableStateOf(initialPath)
val fileListStates = mutableMapOf<String, FileListPageState>()
Expand Down
Loading

0 comments on commit 6f2467c

Please sign in to comment.