diff --git a/app/src/main/kotlin/top/laoxin/modmanager/ui/state/ModUiState.kt b/app/src/main/kotlin/top/laoxin/modmanager/ui/state/ModUiState.kt index a9b5e25..db4d1ad 100644 --- a/app/src/main/kotlin/top/laoxin/modmanager/ui/state/ModUiState.kt +++ b/app/src/main/kotlin/top/laoxin/modmanager/ui/state/ModUiState.kt @@ -45,6 +45,8 @@ data class ModUiState( val currentMods: List = emptyList(), // 当前路径 val currentPath: String = "", -) { - -} + // 是否显示返回按钮 + val isBackPathExist: Boolean = false, + // 执行返回操作 + val doBackFunction: Boolean = false, +) diff --git a/app/src/main/kotlin/top/laoxin/modmanager/ui/view/modView/ModBrowser.kt b/app/src/main/kotlin/top/laoxin/modmanager/ui/view/modView/ModBrowser.kt index f010ab9..8e871cc 100644 --- a/app/src/main/kotlin/top/laoxin/modmanager/ui/view/modView/ModBrowser.kt +++ b/app/src/main/kotlin/top/laoxin/modmanager/ui/view/modView/ModBrowser.kt @@ -45,6 +45,7 @@ import top.laoxin.modmanager.tools.ModTools import top.laoxin.modmanager.ui.state.ModUiState import top.laoxin.modmanager.ui.viewmodel.ModViewModel import java.io.File +import kotlin.collections.set const val TAG = "ModsBrowser" @@ -56,11 +57,30 @@ fun ModsBrowser(viewModel: ModViewModel, uiState: ModUiState) { val listState = rememberLazyListState() val scrollPositions = remember { mutableMapOf() } val scrollOffsets = remember { mutableMapOf() } + val doBackFunction by rememberUpdatedState(uiState.doBackFunction) if (currentPath == ModTools.MOD_PATH) { return NoMod() } - // 返回上级目录是否显示 + fun doBack() { + if (currentPath != uiState.currentGameModPath && currentPath != Environment.getExternalStorageDirectory().path) { + // 记录当前路径的滚动位置 + scrollPositions[currentPath] = listState.firstVisibleItemIndex + scrollOffsets[currentPath] = listState.firstVisibleItemScrollOffset + previousPath = currentPath + currentPath = File(currentPath).parent ?: currentPath + } + } + + LaunchedEffect(doBackFunction) { + if (doBackFunction) { + doBack() + viewModel.setDoBackFunction(false) + viewModel.setBackIconVisiable(false) + } + } + + // 监听当前路径变化并更新文件列表 LaunchedEffect(currentPath) { viewModel.updateFiles(currentPath) } @@ -82,13 +102,7 @@ fun ModsBrowser(viewModel: ModViewModel, uiState: ModUiState) { // 监听返回按键事件 if (currentPath != uiState.currentGameModPath) { BackHandler { - if (currentPath != Environment.getExternalStorageDirectory().path) { - // 记录当前路径的滚动位置 - scrollPositions[currentPath] = listState.firstVisibleItemIndex - scrollOffsets[currentPath] = listState.firstVisibleItemScrollOffset - previousPath = currentPath - currentPath = File(currentPath).parent ?: currentPath - } + viewModel.setDoBackFunction(true) } } @@ -119,59 +133,19 @@ fun ModsBrowser(viewModel: ModViewModel, uiState: ModUiState) { ) } viewModel.setCurrentMods(mods) - // 返回上级目录按钮 + + // 空目录的返回上级目录按钮 if (currentPath != uiState.currentGameModPath && files.isEmpty()) { - FileListItem( - modifier = Modifier.padding(horizontal = 8.dp, vertical = 8.dp), - name = stringResource(R.string.mod_browser_file_list_back), - isSelected = false, - onLongClick = { - // 长按事件 - }, - onClick = { - if (currentPath != uiState.currentGameModPath) { - // 记录当前路径的滚动位置 - scrollPositions[currentPath] = listState.firstVisibleItemIndex - scrollOffsets[currentPath] = listState.firstVisibleItemScrollOffset - previousPath = currentPath - currentPath = File(currentPath).parent ?: currentPath - } - }, - onMultiSelectClick = { - // 多选状态下的点击事件 - }, - isMultiSelect = uiState.isMultiSelect, - description = currentPath.replace(uiState.currentGameModPath, ""), - iconId = R.drawable.back_icon - ) + viewModel.setBackIconVisiable(true) } + LazyColumn(state = listState) { + items(files) { file: File -> - if (currentPath != uiState.currentGameModPath && files.indexOf(file) == 0) { - FileListItem( - modifier = Modifier.padding(horizontal = 8.dp, vertical = 8.dp), - name = stringResource(R.string.mod_browser_file_list_back), - isSelected = false, - onLongClick = { - // 长按事件 - }, - onClick = { - if (currentPath != uiState.currentGameModPath) { - // 记录当前路径的滚动位置 - scrollPositions[currentPath] = listState.firstVisibleItemIndex - scrollOffsets[currentPath] = - listState.firstVisibleItemScrollOffset - previousPath = currentPath - currentPath = File(currentPath).parent ?: currentPath - } - }, - onMultiSelectClick = { - // 多选状态下的点击事件 - }, - isMultiSelect = uiState.isMultiSelect, - description = currentPath.replace(uiState.currentGameModPath, ""), - iconId = R.drawable.back_icon - ) + + // 非空目录的返回上级目录按钮 + if (!uiState.isBackPathExist && currentPath != uiState.currentGameModPath) { + viewModel.setBackIconVisiable(true) } // 通过filepath获取mods @@ -180,7 +154,6 @@ fun ModsBrowser(viewModel: ModViewModel, uiState: ModUiState) { val modsByVirtualPaths = viewModel.getModsByVirtualPathsStrict(file.path) // 设置当前页面的mods - val modCount = if (viewModel.getModsByPath(file.path) .isNotEmpty() ) viewModel.getModsByPath(file.path).size else viewModel.getModsByVirtualPaths( diff --git a/app/src/main/kotlin/top/laoxin/modmanager/ui/view/modView/ModTopBar.kt b/app/src/main/kotlin/top/laoxin/modmanager/ui/view/modView/ModTopBar.kt index 9b54339..d156d2f 100644 --- a/app/src/main/kotlin/top/laoxin/modmanager/ui/view/modView/ModTopBar.kt +++ b/app/src/main/kotlin/top/laoxin/modmanager/ui/view/modView/ModTopBar.kt @@ -9,9 +9,11 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBackIosNew import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Deselect @@ -21,6 +23,7 @@ import androidx.compose.material.icons.filled.Menu import androidx.compose.material.icons.filled.Refresh import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.SelectAll +import androidx.compose.material3.Button import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api @@ -94,7 +97,44 @@ fun MultiSelectTopBar( modifier = modifier, colors = TopAppBarDefaults.topAppBarColors( containerColor = if (configuration == Configuration.ORIENTATION_LANDSCAPE) MaterialTheme.colorScheme.surface else MaterialTheme.colorScheme.surfaceContainer, - ), title = { + ), + navigationIcon = { + if (uiState.modsView == NavigationIndex.MODS_BROWSER && uiState.isBackPathExist) { + Button( + onClick = { + viewModel.setDoBackFunction(true) + }, + ) { + Box( + contentAlignment = Alignment.CenterStart + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = Icons.Filled.ArrowBackIosNew, + contentDescription = null, + Modifier.size(16.dp) + ) + Text( + text = uiState.currentPath.replace( + uiState.currentGameModPath, + "" + ) + .substringAfterLast('/') + .substringBeforeLast('.') + .takeLast(5), + style = MaterialTheme.typography.titleLarge, + modifier = Modifier.padding(start = 8.dp) + ) + } + } + } + } else { + null + } + }, + title = { Box(contentAlignment = Alignment.CenterStart) { Text( stringResource(id = uiState.modsView.title), @@ -128,7 +168,8 @@ fun MultiSelectTopBar( } } - }, actions = { + }, + actions = { // 全选 IconButton(onClick = { // 在这里处理图标按钮的点击事件 @@ -232,7 +273,44 @@ fun GeneralTopBar( modifier = modifier, colors = TopAppBarDefaults.topAppBarColors( containerColor = if (configuration == Configuration.ORIENTATION_LANDSCAPE) MaterialTheme.colorScheme.surface else MaterialTheme.colorScheme.surfaceContainer, - ), title = { + ), + navigationIcon = { + if (uiState.modsView == NavigationIndex.MODS_BROWSER && uiState.isBackPathExist) { + Button( + onClick = { + viewModel.setDoBackFunction(true) + }, + ) { + Box( + contentAlignment = Alignment.CenterStart + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + imageVector = Icons.Filled.ArrowBackIosNew, + contentDescription = null, + Modifier.size(16.dp) + ) + Text( + text = uiState.currentPath.replace( + uiState.currentGameModPath, + "" + ) + .substringAfterLast('/') + .substringBeforeLast('.') + .takeLast(5), + style = MaterialTheme.typography.titleLarge, + modifier = Modifier.padding(start = 8.dp) + ) + } + } + } + } else { + null + } + }, + title = { Box(contentAlignment = Alignment.CenterStart) { Text( stringResource(id = uiState.modsView.title), @@ -257,7 +335,8 @@ fun GeneralTopBar( } } - }, actions = { + }, + actions = { // IconButton(onClick = { // // 在这里处理图标按钮的点击事件 // viewModel.setUserTipsDialog(true) diff --git a/app/src/main/kotlin/top/laoxin/modmanager/ui/viewmodel/ModViewModel.kt b/app/src/main/kotlin/top/laoxin/modmanager/ui/viewmodel/ModViewModel.kt index fd4ba98..b1b4ba6 100644 --- a/app/src/main/kotlin/top/laoxin/modmanager/ui/viewmodel/ModViewModel.kt +++ b/app/src/main/kotlin/top/laoxin/modmanager/ui/viewmodel/ModViewModel.kt @@ -146,7 +146,7 @@ class ModViewModel( scanDirectoryMods, delUnzipDictionaryFlow, showCategoryView - ) { values -> + ) { values: Array -> UserPreferencesState( scanQQDirectory = values[0] as Boolean, selectedDirectory = values[1] as String, @@ -897,6 +897,18 @@ class ModViewModel( } } + fun setBackIconVisiable(b: Boolean) { + _uiState.update { + it.copy(isBackPathExist = b) + } + } + + fun setDoBackFunction(b: Boolean) { + _uiState.update { + it.copy(doBackFunction = b) + } + } + fun modLongClick(modBean: ModBean) { Log.d("ModViewModel", "长按事件: $modBean") if (!_uiState.value.isMultiSelect) {