-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b78b24d
commit 68d093d
Showing
17 changed files
with
334 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
shared-compose-ui/src/commonMain/kotlin/com/softartdev/notedelight/ui/FileListScreen.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package com.softartdev.notedelight.ui | ||
|
||
import androidx.compose.foundation.clickable | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.lazy.LazyColumn | ||
import androidx.compose.foundation.lazy.items | ||
import androidx.compose.foundation.lazy.rememberLazyListState | ||
import androidx.compose.material.Divider | ||
import androidx.compose.material.Icon | ||
import androidx.compose.material.IconButton | ||
import androidx.compose.material.MaterialTheme | ||
import androidx.compose.material.Scaffold | ||
import androidx.compose.material.Text | ||
import androidx.compose.material.TopAppBar | ||
import androidx.compose.material.icons.Icons | ||
import androidx.compose.material.icons.filled.ArrowBack | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.DisposableEffect | ||
import androidx.compose.runtime.LaunchedEffect | ||
import androidx.compose.runtime.State | ||
import androidx.compose.runtime.collectAsState | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.semantics.clearAndSetSemantics | ||
import androidx.compose.ui.semantics.contentDescription | ||
import androidx.compose.ui.unit.dp | ||
import com.softartdev.notedelight.shared.presentation.files.FilesResult | ||
import com.softartdev.notedelight.shared.presentation.files.FilesViewModel | ||
|
||
@Composable | ||
fun FileListScreen( | ||
onBackClick: () -> Unit = {}, | ||
filesViewModel: FilesViewModel | ||
) { | ||
val fileListState: State<FilesResult> = filesViewModel.resultStateFlow.collectAsState() | ||
DisposableEffect(filesViewModel) { | ||
filesViewModel.updateFiles() | ||
onDispose(filesViewModel::onCleared) | ||
} | ||
FileListScreen(fileListState, onBackClick, filesViewModel::onItemClicked) | ||
} | ||
|
||
@Composable | ||
fun FileListScreen( | ||
fileListState: State<FilesResult>, | ||
onBackClick: () -> Unit = {}, | ||
onItemClicked: (text: String) -> Unit = {} | ||
) = Scaffold( | ||
topBar = { | ||
TopAppBar( | ||
title = { Text("File list") }, | ||
navigationIcon = { | ||
IconButton(onClick = onBackClick) { | ||
Icon( | ||
imageVector = Icons.Default.ArrowBack, | ||
contentDescription = Icons.Default.ArrowBack.name | ||
) | ||
} | ||
}, | ||
) | ||
}, | ||
content = { | ||
when (val result = fileListState.value) { | ||
is FilesResult.Loading -> Loader() | ||
is FilesResult.Success -> { | ||
val fileList: List<String> = result.result | ||
if (fileList.isEmpty()) Empty() else FileList(fileList, onItemClicked) | ||
} | ||
|
||
is FilesResult.Error -> Error(err = result.error ?: "Unknown error") | ||
} | ||
} | ||
) | ||
|
||
@Composable | ||
fun FileList(fileList: List<String>, onItemClicked: (text: String) -> Unit) { | ||
val listState = rememberLazyListState() | ||
|
||
LazyColumn(state = listState) { | ||
items(items = fileList) { | ||
FileItem( | ||
fileName = it, | ||
onItemClicked = onItemClicked, | ||
) | ||
Divider() | ||
} | ||
} | ||
LaunchedEffect(key1 = fileList.size, key2 = listState) { | ||
listState.animateScrollToItem(0) | ||
} | ||
} | ||
|
||
@Composable | ||
fun FileItem(fileName: String, onItemClicked: (fileName: String) -> Unit) = Column( | ||
modifier = Modifier | ||
.clickable { onItemClicked(fileName) } | ||
.fillMaxWidth() | ||
.padding(4.dp) | ||
.clearAndSetSemantics { contentDescription = fileName } | ||
) { | ||
Text( | ||
text = fileName, | ||
style = MaterialTheme.typography.h6, | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
shared/src/androidMain/kotlin/com/softartdev/notedelight/shared/files/androidFileRepo.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.softartdev.notedelight.shared.files | ||
|
||
import android.content.Context | ||
import okio.FileSystem | ||
import okio.Path | ||
import okio.Path.Companion.toPath | ||
|
||
class AndroidFileRepo(context: Context) : FileRepo( | ||
fileSystem = FileSystem.SYSTEM, | ||
zeroPath = zeroPath(context) | ||
) { | ||
|
||
companion object { | ||
|
||
private fun zeroPath(context: Context): Path { | ||
val filesDir = context.filesDir | ||
return filesDir.path.toPath() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
shared/src/commonMain/kotlin/com/softartdev/notedelight/shared/files/FileRepo.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package com.softartdev.notedelight.shared.files | ||
|
||
import io.github.aakira.napier.Napier | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import okio.FileMetadata | ||
import okio.FileSystem | ||
import okio.Path | ||
import okio.Path.Companion.toPath | ||
import okio.buffer | ||
import okio.use | ||
|
||
abstract class FileRepo(private val fileSystem: FileSystem, zeroPath: Path) { | ||
private val upFolder = "🔙.." | ||
private val fileContent = "📖" | ||
private lateinit var currentFileDir: Path | ||
private lateinit var currentFiles: List<Path> | ||
private lateinit var currentFileNames: List<String> | ||
private val _fileListFlow: MutableStateFlow<List<String>> = MutableStateFlow( | ||
value = listOf("🔁loading...") | ||
) | ||
val fileListFlow: Flow<List<String>> = _fileListFlow | ||
|
||
init { | ||
goTo(file = zeroPath) | ||
} | ||
|
||
fun onItemClicked(fileName: String) = when (fileName) { | ||
upFolder -> goTo(file = requireNotNull(currentFileDir.parent)) | ||
fileContent -> { | ||
_fileListFlow.value = _fileListFlow.value + fileContent // FIXME | ||
} | ||
else -> { | ||
val index = currentFileNames.indexOf(fileName) | ||
if (index != -1) { | ||
val file = currentFiles[index] | ||
goTo(file) | ||
} else Napier.e("file not found: $fileName") | ||
} | ||
} | ||
|
||
private fun goTo(file: Path) { | ||
Napier.d("📂go to: $file") | ||
val metadata: FileMetadata = fileSystem.metadataOrNull(file) ?: return | ||
if (metadata.isDirectory) { | ||
currentFileDir = file | ||
currentFiles = fileSystem.list(dir = file) | ||
currentFileNames = currentFiles.map { curFile: Path -> | ||
val curMetadata = fileSystem.metadataOrNull(curFile) ?: return@map "" | ||
val icon = if (curMetadata.isDirectory) "📁" else "📄" | ||
return@map "$icon ${curFile.name}" | ||
} | ||
} else if (metadata.isRegularFile) { | ||
currentFileDir = file | ||
currentFiles = emptyList() | ||
currentFileNames = listOf(fileContent, readFile(file)) | ||
} else { | ||
Napier.e("unknown file: $file") | ||
_fileListFlow.value = _fileListFlow.value + "❌ $metadata" // FIXME | ||
} | ||
val absolutePath = if (file.isAbsolute) file else fileSystem.canonicalize(file) | ||
_fileListFlow.value = listOf("📂${absolutePath.toString()}", upFolder) + currentFileNames | ||
} | ||
|
||
private fun readFile(file: Path): String { | ||
val stringBuilder = StringBuilder() | ||
fileSystem.source(file).use { fileSource -> | ||
fileSource.buffer().use { bufferedFileSource -> | ||
while (true) { | ||
val line = bufferedFileSource.readUtf8Line() ?: break | ||
stringBuilder.append(line) | ||
} | ||
} | ||
} | ||
return stringBuilder.toString() | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
...src/commonMain/kotlin/com/softartdev/notedelight/shared/presentation/files/FilesResult.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.softartdev.notedelight.shared.presentation.files | ||
|
||
|
||
sealed class FilesResult { | ||
object Loading : FilesResult() | ||
data class Success(val result: List<String>) : FilesResult() | ||
data class Error(val error: String? = null) : FilesResult() | ||
} |
Oops, something went wrong.