last commit
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
package com.megboyzz.devmenu.data.repositories
|
||||
|
||||
class MyClass {
|
||||
|
||||
fun main(){
|
||||
|
||||
val input = readln().split(",").associate {
|
||||
val s = it.trim().split(" ")
|
||||
s[0] to s[1].toInt()
|
||||
}
|
||||
|
||||
var sum = 0
|
||||
|
||||
readln().split(" ").forEach {
|
||||
|
||||
val s = input[it] ?: 0
|
||||
sum += s
|
||||
|
||||
}
|
||||
|
||||
println(sum)
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,15 +17,13 @@ abstract class BaseObserver(source: String) : FileObserver(source) {
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
final override fun onEvent(event: Int, path: String?) {
|
||||
|
||||
if(eventQueue.size < 3) eventQueue.add(event)
|
||||
|
||||
val e = FileEvent.entries.find { it.value == event }
|
||||
|
||||
val fileEvent = e ?: FileEvent.UNKNOWN
|
||||
|
||||
Log.i("BaseObserver", "event code = ${event.toHexString()}, FileEvent is $fileEvent")
|
||||
|
||||
if(hasLastThreeEvents()) onEvent(fileEvent, path)
|
||||
onEvent(fileEvent, path)
|
||||
}
|
||||
|
||||
private fun hasLastThreeEvents() = runCatching {
|
||||
@@ -38,7 +36,9 @@ abstract class BaseObserver(source: String) : FileObserver(source) {
|
||||
this.list { dir, _ -> Regex(regex).matches(dir.absolutePath) }?.asList() ?: listOf()
|
||||
|
||||
|
||||
protected infix fun File.copyToThe(destination: File) = this.copyTo(destination, overwrite = true)
|
||||
protected infix fun File.copyToThe(destination: File){
|
||||
this.copyTo(destination, overwrite = true)
|
||||
}
|
||||
|
||||
protected fun zipAll(outputFolder: String, filesToCompress: List<String>) {
|
||||
if(filesToCompress.isEmpty()){
|
||||
|
||||
@@ -15,10 +15,10 @@ class SaveFileObserver(
|
||||
private val checkList = listOf(
|
||||
FileEvent.CLOSE_WRITE,
|
||||
FileEvent.MODIFY,
|
||||
FileEvent.DELETE,
|
||||
//FileEvent.DELETE,
|
||||
FileEvent.CREATE,
|
||||
FileEvent.ACCESS,
|
||||
FileEvent.OPEN,
|
||||
//FileEvent.ACCESS,
|
||||
//FileEvent.OPEN,
|
||||
FileEvent.CLOSE_NOWRITE
|
||||
)
|
||||
init {
|
||||
|
||||
@@ -11,12 +11,12 @@ java {
|
||||
dependencies {
|
||||
implementation("javax.inject:javax.inject:1")
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("org.mockito:mockito-core:3.12.4")
|
||||
testImplementation("org.mockito.kotlin:mockito-kotlin:3.12.4")
|
||||
//testImplementation("org.mockito:mockito-core:5.7.0")
|
||||
//testImplementation("org.mockito.kotlin:mockito-kotlin:5.7.0")
|
||||
}
|
||||
|
||||
/*
|
||||
sourceSets {
|
||||
test {
|
||||
java.srcDir("src/test/java") // Путь к исходным файлам тестов на Kotlin
|
||||
}
|
||||
}
|
||||
}*/
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.megboyzz.devmenu.domain.entities
|
||||
|
||||
data class Settings(
|
||||
val enable: Boolean,
|
||||
val trackingInterval: Int,
|
||||
val pathToSaveTrackable: String,
|
||||
val lang: GameLang
|
||||
)
|
||||
@@ -11,4 +11,10 @@ interface FilesRepository {
|
||||
|
||||
fun getFileProps(file: File): FileProps
|
||||
|
||||
suspend fun hideFile(file: File): Boolean
|
||||
|
||||
suspend fun unHideFile(file: File): Boolean
|
||||
|
||||
val allHidedFiles: List<File>
|
||||
|
||||
}
|
||||
+2
-3
@@ -1,11 +1,10 @@
|
||||
package com.megboyzz.devmenu.domain.repository
|
||||
|
||||
import com.megboyzz.devmenu.domain.entities.Settings
|
||||
import com.megboyzz.devmenu.domain.entities.GameLang
|
||||
|
||||
interface SettingsRepository {
|
||||
|
||||
suspend fun getSettings(): Settings
|
||||
fun setGameLang(lang: GameLang): Boolean
|
||||
|
||||
suspend fun setSettings(settings: Settings)
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.megboyzz.devmenu.domain.repository
|
||||
|
||||
interface TrackingRepository {
|
||||
|
||||
fun setTracking(enabled: Boolean, pathToSave: String): Boolean
|
||||
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.files
|
||||
|
||||
import com.megboyzz.devmenu.domain.repository.FilesRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class RemoveInternalDataUseCase @Inject constructor(
|
||||
private val filesRepository: FilesRepository
|
||||
) {
|
||||
operator fun invoke(): Boolean{
|
||||
val listFiles = filesRepository.internalRoot.listFiles() ?: return false
|
||||
listFiles.forEach { it.deleteRecursively() }
|
||||
return true
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.files
|
||||
|
||||
import java.io.File
|
||||
|
||||
class RenameFileUseCase {
|
||||
operator fun invoke(file: File, newName: String) =
|
||||
if(file.exists())
|
||||
file.renameTo(File(file.parent, newName))
|
||||
else
|
||||
false
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.hidefiles
|
||||
|
||||
import com.megboyzz.devmenu.domain.repository.FilesRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class GetAllHidedFilesUseCase @Inject constructor(
|
||||
private val filesRepository: FilesRepository
|
||||
) {
|
||||
|
||||
operator fun invoke() = filesRepository.allHidedFiles
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.hidefiles
|
||||
|
||||
import com.megboyzz.devmenu.domain.repository.FilesRepository
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
class HideFileUseCase @Inject constructor(
|
||||
private val filesRepository: FilesRepository
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(file: File) = filesRepository.hideFile(file)
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.hidefiles
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class UnHideAllUseCase @Inject constructor(
|
||||
private val unHideFileUseCase: UnHideFileUseCase,
|
||||
private val getAllHidedFilesUseCase: GetAllHidedFilesUseCase
|
||||
) {
|
||||
|
||||
suspend operator fun invoke() = getAllHidedFilesUseCase().forEach {
|
||||
unHideFileUseCase(it)
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.hidefiles
|
||||
|
||||
import com.megboyzz.devmenu.domain.repository.FilesRepository
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
class UnHideFileUseCase @Inject constructor(
|
||||
private val filesRepository: FilesRepository
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(file: File) = filesRepository.unHideFile(file)
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.files
|
||||
package com.megboyzz.devmenu.domain.usecases.replacement
|
||||
|
||||
import com.megboyzz.devmenu.domain.repository.ReplacementRepository
|
||||
import java.io.File
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.settings
|
||||
|
||||
import com.megboyzz.devmenu.domain.usecases.files.GetInternalFilesUseCase
|
||||
import javax.inject.Inject
|
||||
|
||||
class RemoveGameDataUseCase @Inject constructor(
|
||||
private val getInternalFilesUseCase: GetInternalFilesUseCase
|
||||
) {
|
||||
operator fun invoke() = getInternalFilesUseCase().listFiles()?.forEach { it.delete() }
|
||||
}
|
||||
+5
-3
@@ -1,11 +1,13 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.settings
|
||||
|
||||
import com.megboyzz.devmenu.domain.entities.Settings
|
||||
import com.megboyzz.devmenu.domain.entities.GameLang
|
||||
import com.megboyzz.devmenu.domain.repository.SettingsRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class GetSettingsUseCase @Inject constructor(
|
||||
class SetGameLangUseCase @Inject constructor(
|
||||
private val settingsRepository: SettingsRepository
|
||||
) {
|
||||
suspend operator fun invoke(): Settings = settingsRepository.getSettings()
|
||||
|
||||
operator fun invoke(gameLang: GameLang) = settingsRepository.setGameLang(gameLang)
|
||||
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.settings
|
||||
|
||||
import com.megboyzz.devmenu.domain.entities.Settings
|
||||
import com.megboyzz.devmenu.domain.repository.SettingsRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class SetSettingsUseCase @Inject constructor(
|
||||
private val settingsRepository: SettingsRepository
|
||||
) {
|
||||
suspend operator fun invoke(settings: Settings) = settingsRepository.setSettings(settings)
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.megboyzz.devmenu.domain.usecases.settings
|
||||
|
||||
import com.megboyzz.devmenu.domain.repository.TrackingRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class SetTrackingSaveFileUseCase @Inject constructor(
|
||||
private val trackingRepository: TrackingRepository
|
||||
) {
|
||||
|
||||
operator fun invoke(enabled: Boolean, pathToSave: String) =
|
||||
trackingRepository.setTracking(enabled, pathToSave)
|
||||
|
||||
}
|
||||
@@ -1,19 +1,16 @@
|
||||
import com.megboyzz.devmenu.domain.repository.FilesRepository
|
||||
import com.megboyzz.devmenu.domain.repository.ReplacementRepository
|
||||
import com.megboyzz.devmenu.domain.repository.SaveRepository
|
||||
import com.megboyzz.devmenu.domain.repository.SettingsRepository
|
||||
import com.megboyzz.devmenu.domain.repository.SvmwRepository
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.`when`
|
||||
import java.io.File
|
||||
import kotlin.coroutines.coroutineContext
|
||||
|
||||
class UseCaseTest {
|
||||
|
||||
private val filesRepository = mock(FilesRepository::class.java)
|
||||
private val replacementRepository = mock(ReplacementRepository::class.java)
|
||||
private val saveRepository = mock(SaveRepository::class.java)
|
||||
private val settingsRepository = mock(SettingsRepository::class.java)
|
||||
private val svmwRepository = mock(SvmwRepository::class.java)
|
||||
|
||||
private val externalFile = File("D:\\NFSMW Online\\com.ea.games.nfs13_na")
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.megboyzz.devmenu.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
|
||||
@Composable
|
||||
fun Int.asPainter() = painterResource(this)
|
||||
|
||||
@Composable
|
||||
fun Int.asString() = stringResource(this)
|
||||
|
||||
@Composable
|
||||
fun SpacerWidth(width: Dp) = Spacer(Modifier.width(width))
|
||||
|
||||
@Composable
|
||||
fun SpacerHeight(height: Dp) = Spacer(Modifier.height(height))
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.megboyzz.devmenu.ui.components
|
||||
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Search
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.megboyzz.devmenu.ui.theme.DevMenuTheme
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MainScaffold() {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("") },
|
||||
|
||||
)
|
||||
}
|
||||
) {
|
||||
it.calculateBottomPadding()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun TopBar(
|
||||
searchValue: String,
|
||||
onSearchValueChanged: (String) -> Unit,
|
||||
onSettingsClick: () -> Unit
|
||||
) {
|
||||
|
||||
var text by remember { mutableStateOf("") }
|
||||
|
||||
var isSearching by remember { mutableStateOf(false) }
|
||||
val context = LocalContext.current
|
||||
TopAppBar(
|
||||
title = {
|
||||
Box {
|
||||
if(isSearching) {
|
||||
SearchFileTextField(
|
||||
value = text,
|
||||
onValueChange = { text = it }
|
||||
)
|
||||
} else Text("NFSMW DevMenu")
|
||||
}
|
||||
|
||||
},
|
||||
actions = {
|
||||
SearchButton {
|
||||
Toast.makeText(context, "hh", Toast.LENGTH_LONG).show()
|
||||
isSearching = !isSearching
|
||||
}
|
||||
SettingsButton(onClick = onSettingsClick)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SettingsButton(
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
IconButton(onClick) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Settings,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SearchButton(
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
IconButton(onClick) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Search,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun TopBarPrev() {
|
||||
DevMenuTheme {
|
||||
TopBar(
|
||||
searchValue = "А как какать",
|
||||
onSearchValueChanged = {},
|
||||
onSettingsClick = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SearchFileTextField(
|
||||
value: String,
|
||||
onValueChange: (String) -> Unit
|
||||
) {
|
||||
BasicTextField(
|
||||
value = value,
|
||||
onValueChange = onValueChange,
|
||||
decorationBox = { innerTextField ->
|
||||
Box(
|
||||
|
||||
) {
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.background(Color.White, RoundedCornerShape(percent = 30))
|
||||
.padding(start = 12.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
innerTextField()
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
@@ -23,15 +23,15 @@ private val DarkColorScheme = darkColorScheme(
|
||||
)
|
||||
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = Purple40,
|
||||
primary = Color(0xFF36A0EA),
|
||||
secondary = PurpleGrey40,
|
||||
tertiary = Pink40,
|
||||
background = Color(0xFFFFFBFE),
|
||||
background = Color(0xFFF2F7FA),
|
||||
surface = Color(0xFFFFFBFE),
|
||||
onPrimary = Color.White,
|
||||
onSecondary = Color.White,
|
||||
onTertiary = Color.White,
|
||||
onBackground = Color(0xFF1C1B1F),
|
||||
onBackground = Color(0xFF1B3D54),
|
||||
onSurface = Color(0xFF1C1B1F),
|
||||
)
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@ val Typography = Typography(
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
/* Other default text styles to override
|
||||
),
|
||||
titleLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
@@ -30,5 +29,4 @@ val Typography = Typography(
|
||||
lineHeight = 16.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
*/
|
||||
)
|
||||
@@ -1,5 +1,5 @@
|
||||
[versions]
|
||||
agp = "8.3.0-alpha05"
|
||||
agp = "8.1.2"
|
||||
junit-junit = "4.13.2"
|
||||
kotlin = "1.9.0"
|
||||
core-ktx = "1.12.0"
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
#Thu Oct 12 20:31:26 MSK 2023
|
||||
#Wed Nov 08 15:56:25 MSK 2023
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-rc-2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
Reference in New Issue
Block a user