forked from geode-sdk/android-launcher
make crashviewmodel abstract
This commit is contained in:
4 files changed
+108
-72
No files matched your search
@@ -0,0 +1,68 @@
|
|||||||
|
package com.geode.launcher.log
|
||||||
|
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
abstract class BaseDirectoryViewModel<T>(protected val baseDirectory: File) : ViewModel() {
|
||||||
|
private val _lineState = mutableStateListOf<T>()
|
||||||
|
val lineState = _lineState
|
||||||
|
|
||||||
|
private val _isLoading = MutableStateFlow(false)
|
||||||
|
val isLoading = _isLoading.asStateFlow()
|
||||||
|
|
||||||
|
private var logJob: Job? = null
|
||||||
|
|
||||||
|
abstract fun getFileList(): List<T>
|
||||||
|
|
||||||
|
open fun clearAllFiles() {
|
||||||
|
logJob?.cancel()
|
||||||
|
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
if (baseDirectory.exists()) {
|
||||||
|
val files = baseDirectory.listFiles()
|
||||||
|
files?.forEach {
|
||||||
|
it.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_lineState.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadLogs() {
|
||||||
|
_isLoading.value = true
|
||||||
|
|
||||||
|
logJob?.cancel()
|
||||||
|
logJob = viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
val lines = getFileList()
|
||||||
|
|
||||||
|
_lineState.clear()
|
||||||
|
_lineState.addAll(lines)
|
||||||
|
|
||||||
|
_isLoading.value = false
|
||||||
|
|
||||||
|
logJob = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeFile(filename: String) {
|
||||||
|
logJob?.cancel()
|
||||||
|
|
||||||
|
val crashPath = File(baseDirectory, filename)
|
||||||
|
if (crashPath.exists()) {
|
||||||
|
crashPath.delete()
|
||||||
|
loadLogs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
loadLogs()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,12 @@
|
|||||||
package com.geode.launcher.log
|
package com.geode.launcher.log
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.lifecycle.viewmodel.initializer
|
import androidx.lifecycle.viewmodel.initializer
|
||||||
import androidx.lifecycle.viewmodel.viewModelFactory
|
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||||
import com.geode.launcher.utils.LaunchUtils
|
import com.geode.launcher.utils.LaunchUtils
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.time.ExperimentalTime
|
import kotlin.time.ExperimentalTime
|
||||||
@@ -22,33 +17,23 @@ data class CrashDump @OptIn(ExperimentalTime::class) constructor(
|
|||||||
val lastModified: Instant
|
val lastModified: Instant
|
||||||
)
|
)
|
||||||
|
|
||||||
class CrashViewModel(private val application: Application) : ViewModel() {
|
class CrashViewModel(crashDirectory: File) : BaseDirectoryViewModel<CrashDump>(crashDirectory) {
|
||||||
companion object {
|
companion object {
|
||||||
val Factory: ViewModelProvider.Factory = viewModelFactory {
|
val Factory: ViewModelProvider.Factory = viewModelFactory {
|
||||||
initializer {
|
initializer {
|
||||||
val application = this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as Application
|
val application = this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as Application
|
||||||
|
val crashDirectory = LaunchUtils.getCrashDirectory(application)
|
||||||
|
|
||||||
CrashViewModel(
|
CrashViewModel(crashDirectory)
|
||||||
application = application
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _lineState = mutableStateListOf<CrashDump>()
|
|
||||||
val lineState = _lineState
|
|
||||||
|
|
||||||
private val _isLoading = MutableStateFlow(false)
|
|
||||||
val isLoading = _isLoading.asStateFlow()
|
|
||||||
|
|
||||||
private var failedToLoad = false
|
|
||||||
|
|
||||||
private var logJob: Job? = null
|
|
||||||
|
|
||||||
var hasIndicator = false
|
var hasIndicator = false
|
||||||
|
|
||||||
private fun getCrashList(): List<CrashDump> {
|
override fun getFileList(): List<CrashDump> {
|
||||||
val crashDirectory = LaunchUtils.getCrashDirectory(application)
|
val crashDirectory = baseDirectory
|
||||||
|
|
||||||
if (!crashDirectory.exists()) {
|
if (!crashDirectory.exists()) {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
@@ -72,8 +57,7 @@ class CrashViewModel(private val application: Application) : ViewModel() {
|
|||||||
|
|
||||||
fun clearIndicator() {
|
fun clearIndicator() {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
val crashDirectory = LaunchUtils.getCrashDirectory(application)
|
File(baseDirectory, LaunchUtils.CRASH_INDICATOR_NAME).delete()
|
||||||
File(crashDirectory, LaunchUtils.CRASH_INDICATOR_NAME).delete()
|
|
||||||
|
|
||||||
hasIndicator = false
|
hasIndicator = false
|
||||||
}
|
}
|
||||||
@@ -81,56 +65,14 @@ class CrashViewModel(private val application: Application) : ViewModel() {
|
|||||||
|
|
||||||
fun createIndicator() {
|
fun createIndicator() {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
val crashDirectory = LaunchUtils.getCrashDirectory(application)
|
File(baseDirectory, LaunchUtils.CRASH_INDICATOR_NAME).createNewFile()
|
||||||
File(crashDirectory, LaunchUtils.CRASH_INDICATOR_NAME).createNewFile()
|
|
||||||
|
|
||||||
hasIndicator = true
|
hasIndicator = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearCrashes() {
|
override fun clearAllFiles() {
|
||||||
logJob?.cancel()
|
super.clearAllFiles()
|
||||||
|
hasIndicator = false
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
|
||||||
val crashDirectory = LaunchUtils.getCrashDirectory(application)
|
|
||||||
if (crashDirectory.exists()) {
|
|
||||||
val files = crashDirectory.listFiles()
|
|
||||||
files?.forEach {
|
|
||||||
it.delete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_lineState.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadLogs() {
|
|
||||||
_isLoading.value = true
|
|
||||||
|
|
||||||
logJob?.cancel()
|
|
||||||
logJob = viewModelScope.launch(Dispatchers.IO) {
|
|
||||||
val lines = getCrashList()
|
|
||||||
|
|
||||||
_lineState.clear()
|
|
||||||
_lineState.addAll(lines)
|
|
||||||
|
|
||||||
_isLoading.value = false
|
|
||||||
|
|
||||||
logJob = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeCrash(filename: String) {
|
|
||||||
logJob?.cancel()
|
|
||||||
|
|
||||||
val crashPath = File(LaunchUtils.getCrashDirectory(application), filename)
|
|
||||||
if (crashPath.exists()) {
|
|
||||||
crashPath.delete()
|
|
||||||
loadLogs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
loadLogs()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ fun CrashCard(crashDump: CrashDump, crashViewModel: CrashViewModel, modifier: Mo
|
|||||||
}
|
}
|
||||||
|
|
||||||
IconButton(onClick = {
|
IconButton(onClick = {
|
||||||
crashViewModel.removeCrash(crashDump.filename)
|
crashViewModel.removeFile(crashDump.filename)
|
||||||
}) {
|
}) {
|
||||||
Icon(
|
Icon(
|
||||||
painterResource(R.drawable.icon_delete),
|
painterResource(R.drawable.icon_delete),
|
||||||
@@ -228,14 +228,13 @@ fun CrashLogsScreen(
|
|||||||
text = {
|
text = {
|
||||||
Text(stringResource(R.string.application_logs_delete))
|
Text(stringResource(R.string.application_logs_delete))
|
||||||
}, onClick = {
|
}, onClick = {
|
||||||
crashViewModel.clearCrashes()
|
crashViewModel.clearAllFiles()
|
||||||
showMoreOptions = false
|
showMoreOptions = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
val developerMode by PreferenceUtils.useBooleanPreference(PreferenceUtils.Key.DEVELOPER_MODE)
|
val developerMode by PreferenceUtils.useBooleanPreference(PreferenceUtils.Key.DEVELOPER_MODE)
|
||||||
if (developerMode) {
|
if (developerMode) {
|
||||||
|
|
||||||
if (crashViewModel.hasIndicator) {
|
if (crashViewModel.hasIndicator) {
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
|
|||||||
@@ -463,6 +463,33 @@ fun GameplaySettingsGroup() {
|
|||||||
preferenceKey = PreferenceUtils.Key.LIMIT_FRAME_RATE,
|
preferenceKey = PreferenceUtils.Key.LIMIT_FRAME_RATE,
|
||||||
maxFrameRate = maxFrameRate
|
maxFrameRate = maxFrameRate
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var showSafeModeDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
OptionsButton(
|
||||||
|
title = stringResource(R.string.preference_launch_safe_mode),
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
painterResource(R.drawable.icon_shield),
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
showSafeModeDialog = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showSafeModeDialog) {
|
||||||
|
SafeModeDialog(onDismiss = {
|
||||||
|
showSafeModeDialog = false
|
||||||
|
}) {
|
||||||
|
val launchIntent = Intent(context, MainActivity::class.java).apply {
|
||||||
|
// hardcode it, why not
|
||||||
|
action = Intent.ACTION_VIEW
|
||||||
|
data = "geode-launcher://main/launch?safe-mode=true".toUri()
|
||||||
|
}
|
||||||
|
context.startActivity(launchIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user