Большая реструктуризация проекта
This commit is contained in:
@@ -75,7 +75,10 @@ dependencies {
|
|||||||
androidTestImplementation(libs.androidx.espresso.core)
|
androidTestImplementation(libs.androidx.espresso.core)
|
||||||
|
|
||||||
implementation(project(":domain"))
|
implementation(project(":domain"))
|
||||||
implementation(project(":data"))
|
implementation(project(":usecases"))
|
||||||
implementation(project(":presentation"))
|
implementation(project(":domain-storage"))
|
||||||
implementation(project(":vault-api"))
|
implementation(project(":infrastructure-android"))
|
||||||
|
implementation(project(":task-runtime"))
|
||||||
|
implementation(project(":ui"))
|
||||||
|
implementation(project(":vault-contracts"))
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ import androidx.activity.enableEdgeToEdge
|
|||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.github.nullptroma.wallenc.app.auth.YandexSignInService
|
import com.github.nullptroma.wallenc.app.auth.YandexSignInService
|
||||||
import com.github.nullptroma.wallenc.presentation.WallencUi
|
import com.github.nullptroma.wallenc.ui.WallencUi
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ package com.github.nullptroma.wallenc.app.auth
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import com.github.nullptroma.wallenc.data.vaults.yandex.YandexRegistration
|
import com.github.nullptroma.wallenc.infrastructure.vaults.yandex.YandexRegistration
|
||||||
import com.github.nullptroma.wallenc.vaultapi.CloudBrand
|
import com.github.nullptroma.wallenc.vault.contract.CloudBrand
|
||||||
import com.github.nullptroma.wallenc.vaultapi.RemoteVaultAuthenticator
|
import com.github.nullptroma.wallenc.vault.contract.RemoteVaultAuthenticator
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultLinkOutcome
|
import com.github.nullptroma.wallenc.vault.contract.VaultLinkOutcome
|
||||||
import com.yandex.authsdk.YandexAuthLoginOptions
|
import com.yandex.authsdk.YandexAuthLoginOptions
|
||||||
import com.yandex.authsdk.YandexAuthOptions
|
import com.yandex.authsdk.YandexAuthOptions
|
||||||
import com.yandex.authsdk.YandexAuthResult
|
import com.yandex.authsdk.YandexAuthResult
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.github.nullptroma.wallenc.app.di.modules.auth
|
package com.github.nullptroma.wallenc.app.di.modules.auth
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.app.auth.YandexSignInService
|
import com.github.nullptroma.wallenc.app.auth.YandexSignInService
|
||||||
import com.github.nullptroma.wallenc.vaultapi.RemoteVaultAuthenticator
|
import com.github.nullptroma.wallenc.vault.contract.RemoteVaultAuthenticator
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.github.nullptroma.wallenc.app.di.modules.data
|
package com.github.nullptroma.wallenc.app.di.modules.data
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.github.nullptroma.wallenc.data.db.RoomFactory
|
import com.github.nullptroma.wallenc.infrastructure.db.RoomFactory
|
||||||
import com.github.nullptroma.wallenc.data.db.app.IAppDb
|
import com.github.nullptroma.wallenc.infrastructure.db.app.IAppDb
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.StorageKeyMapDao
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.StorageKeyMapDao
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.StorageMetaInfoDao
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.StorageMetaInfoDao
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.YandexAccountDao
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.YandexAccountDao
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
|||||||
@@ -2,23 +2,28 @@ package com.github.nullptroma.wallenc.app.di.modules.data
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.github.nullptroma.wallenc.app.di.modules.app.IoDispatcher
|
import com.github.nullptroma.wallenc.app.di.modules.app.IoDispatcher
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.StorageKeyMapDao
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.StorageKeyMapDao
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.StorageMetaInfoDao
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.StorageMetaInfoDao
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.YandexAccountDao
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.YandexAccountDao
|
||||||
import com.github.nullptroma.wallenc.data.db.app.repository.StorageKeyMapRepository
|
import com.github.nullptroma.wallenc.infrastructure.db.app.repository.StorageKeyMapRepository
|
||||||
import com.github.nullptroma.wallenc.data.db.app.repository.StorageMetaInfoRepository
|
import com.github.nullptroma.wallenc.infrastructure.db.app.repository.StorageMetaInfoRepository
|
||||||
import com.github.nullptroma.wallenc.data.db.app.repository.YandexAccountRepository
|
import com.github.nullptroma.wallenc.infrastructure.db.app.repository.YandexAccountRepository
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.YandexDiskApiFactory
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.YandexDiskApiFactory
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.repository.YandexDiskRepositoryFactory
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.repository.YandexDiskRepositoryFactory
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexuserinfo.YandexUserInfoApi
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexuserinfo.YandexUserInfoApi
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexuserinfo.YandexUserInfoApiFactory
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexuserinfo.YandexUserInfoApiFactory
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexuserinfo.repository.YandexUserInfoRepository
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexuserinfo.repository.YandexUserInfoRepository
|
||||||
import com.github.nullptroma.wallenc.data.tasks.TaskOrchestrator
|
import com.github.nullptroma.wallenc.infrastructure.ports.StorageKeyMapStore
|
||||||
import com.github.nullptroma.wallenc.data.vaults.VaultsManager
|
import com.github.nullptroma.wallenc.infrastructure.ports.YandexAccountStore
|
||||||
|
import com.github.nullptroma.wallenc.task.runtime.TaskOrchestrator
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.vaults.VaultsManager
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.vaults.local.LocalVault
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.vaults.local.LocalVaultIdStore
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
|
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
|
||||||
|
import com.github.nullptroma.wallenc.domain.interfaces.IVault
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultRegistrar
|
import com.github.nullptroma.wallenc.vault.contract.VaultRegistrar
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
@@ -43,10 +48,10 @@ class SingletonModule {
|
|||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideYandexDiskApiFactory(
|
fun provideYandexDiskApiFactory(
|
||||||
yandexAccountRepository: YandexAccountRepository,
|
yandexAccountStore: YandexAccountStore,
|
||||||
@IoDispatcher ioDispatcher: CoroutineDispatcher,
|
@IoDispatcher ioDispatcher: CoroutineDispatcher,
|
||||||
): YandexDiskApiFactory = YandexDiskApiFactory(
|
): YandexDiskApiFactory = YandexDiskApiFactory(
|
||||||
accountRepository = yandexAccountRepository,
|
accountRepository = yandexAccountStore,
|
||||||
ioDispatcher = ioDispatcher,
|
ioDispatcher = ioDispatcher,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -64,22 +69,33 @@ class SingletonModule {
|
|||||||
@Singleton
|
@Singleton
|
||||||
fun provideVaultsManager(
|
fun provideVaultsManager(
|
||||||
@IoDispatcher ioDispatcher: CoroutineDispatcher,
|
@IoDispatcher ioDispatcher: CoroutineDispatcher,
|
||||||
@ApplicationContext context: Context,
|
localVault: IVault,
|
||||||
keyRepo: StorageKeyMapRepository,
|
keyRepo: StorageKeyMapStore,
|
||||||
yandexAccountRepository: YandexAccountRepository,
|
yandexAccountStore: YandexAccountStore,
|
||||||
yandexUserInfoRepository: YandexUserInfoRepository,
|
yandexUserInfoRepository: YandexUserInfoRepository,
|
||||||
yandexDiskRepositoryFactory: YandexDiskRepositoryFactory,
|
yandexDiskRepositoryFactory: YandexDiskRepositoryFactory,
|
||||||
): VaultsManager {
|
): VaultsManager {
|
||||||
return VaultsManager(
|
return VaultsManager(
|
||||||
ioDispatcher = ioDispatcher,
|
ioDispatcher = ioDispatcher,
|
||||||
context = context,
|
localVault = localVault,
|
||||||
keyRepo = keyRepo,
|
keyRepo = keyRepo,
|
||||||
yandexAccountRepository = yandexAccountRepository,
|
yandexAccountStore = yandexAccountStore,
|
||||||
yandexUserInfoRepository = yandexUserInfoRepository,
|
yandexUserInfoRepository = yandexUserInfoRepository,
|
||||||
yandexDiskRepositoryFactory = yandexDiskRepositoryFactory,
|
yandexDiskRepositoryFactory = yandexDiskRepositoryFactory,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideLocalVault(
|
||||||
|
@IoDispatcher ioDispatcher: CoroutineDispatcher,
|
||||||
|
@ApplicationContext context: Context,
|
||||||
|
): IVault = LocalVault(
|
||||||
|
ioDispatcher = ioDispatcher,
|
||||||
|
context = context,
|
||||||
|
idStore = LocalVaultIdStore(context),
|
||||||
|
)
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideIVaultsManager(impl: VaultsManager): IVaultsManager = impl
|
fun provideIVaultsManager(impl: VaultsManager): IVaultsManager = impl
|
||||||
@@ -104,6 +120,12 @@ class SingletonModule {
|
|||||||
return StorageKeyMapRepository(dao, ioDispatcher)
|
return StorageKeyMapRepository(dao, ioDispatcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideStorageKeyMapStore(
|
||||||
|
impl: StorageKeyMapRepository,
|
||||||
|
): StorageKeyMapStore = impl
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideStorageMetaInfoRepository(
|
fun provideStorageMetaInfoRepository(
|
||||||
@@ -122,6 +144,12 @@ class SingletonModule {
|
|||||||
return YandexAccountRepository(dao, ioDispatcher)
|
return YandexAccountRepository(dao, ioDispatcher)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideYandexAccountStore(
|
||||||
|
impl: YandexAccountRepository,
|
||||||
|
): YandexAccountStore = impl
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideYandexUserInfoRepository(
|
fun provideYandexUserInfoRepository(
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package com.github.nullptroma.wallenc.app.di.modules.domain
|
|||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
|
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.GetOpenedStoragesUseCase
|
import com.github.nullptroma.wallenc.usecases.GetOpenedStoragesUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.ManageStoragesEncryptionUseCase
|
import com.github.nullptroma.wallenc.usecases.ManageStoragesEncryptionUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.ManageVaultUseCase
|
import com.github.nullptroma.wallenc.usecases.ManageVaultUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.RemoveStorageUseCase
|
import com.github.nullptroma.wallenc.usecases.RemoveStorageUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.RenameStorageUseCase
|
import com.github.nullptroma.wallenc.usecases.RenameStorageUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.StorageFileManagementUseCase
|
import com.github.nullptroma.wallenc.usecases.StorageFileManagementUseCase
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db.app.repository
|
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.StorageKeyMapDao
|
|
||||||
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageKeyMap
|
|
||||||
import com.github.nullptroma.wallenc.data.model.StorageKeyMap
|
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
class StorageKeyMapRepository(
|
|
||||||
private val dao: StorageKeyMapDao,
|
|
||||||
private val ioDispatcher: CoroutineDispatcher
|
|
||||||
) {
|
|
||||||
suspend fun getAll() = withContext(ioDispatcher) { dao.getAll().map { it.toModel() } }
|
|
||||||
suspend fun add(vararg keymaps: StorageKeyMap) = withContext(ioDispatcher) {
|
|
||||||
val dbModels = keymaps.map { DbStorageKeyMap.fromModel(it) }
|
|
||||||
dao.add(*dbModels.toTypedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun delete(vararg keymaps: StorageKeyMap) = withContext(ioDispatcher) {
|
|
||||||
val dbModels = keymaps.map { DbStorageKeyMap.fromModel(it) }
|
|
||||||
dao.delete(*dbModels.toTypedArray())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db.app.repository
|
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.YandexAccountDao
|
|
||||||
import com.github.nullptroma.wallenc.data.db.app.model.DbYandexAccount
|
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
|
|
||||||
class YandexAccountRepository(
|
|
||||||
private val dao: YandexAccountDao,
|
|
||||||
private val ioDispatcher: CoroutineDispatcher
|
|
||||||
) {
|
|
||||||
fun observeAll(): Flow<List<DbYandexAccount>> = dao.observeAll()
|
|
||||||
|
|
||||||
suspend fun getByYandexUserId(id: String): DbYandexAccount? = withContext(ioDispatcher) {
|
|
||||||
dao.getByYandexUserId(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getByVaultUuid(vaultUuid: String): DbYandexAccount? = withContext(ioDispatcher) {
|
|
||||||
dao.getByVaultUuid(vaultUuid)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun insert(account: DbYandexAccount) = withContext(ioDispatcher) {
|
|
||||||
dao.insert(account)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun updateCredentials(vaultUuid: String, email: String, token: String) =
|
|
||||||
withContext(ioDispatcher) {
|
|
||||||
dao.updateCredentials(vaultUuid, email, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun deleteByVaultUuid(vaultUuid: String) = withContext(ioDispatcher) {
|
|
||||||
dao.deleteByVaultUuid(vaultUuid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
27
domain-storage/build.gradle.kts
Normal file
27
domain-storage/build.gradle.kts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
plugins {
|
||||||
|
id("java-library")
|
||||||
|
alias(libs.plugins.jetbrains.kotlin.jvm)
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(17)
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// jackson
|
||||||
|
implementation(libs.jackson.module.kotlin)
|
||||||
|
implementation(libs.jackson.datatype.jsr310)
|
||||||
|
|
||||||
|
// Retrofit
|
||||||
|
implementation(libs.retrofit)
|
||||||
|
implementation(libs.retrofit.converter.scalars)
|
||||||
|
implementation(libs.retrofit.converter.jackson)
|
||||||
|
|
||||||
|
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
||||||
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
|
|
||||||
|
testImplementation(libs.junit)
|
||||||
|
|
||||||
|
implementation(project(":domain"))
|
||||||
|
implementation(project(":vault-contracts"))
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation
|
package com.github.nullptroma.wallenc.infrastructure
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
@@ -19,6 +19,6 @@ class ExampleInstrumentedTest {
|
|||||||
fun useAppContext() {
|
fun useAppContext() {
|
||||||
// Context of the app under test.
|
// Context of the app under test.
|
||||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
assertEquals("com.github.nullptroma.wallenc.presentation.test", appContext.packageName)
|
assertEquals("com.github.nullptroma.wallenc.infrastructure.test", appContext.packageName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.auth
|
package com.github.nullptroma.wallenc.infrastructure.auth
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scope-ы Яндекс.OAuth, которые нам нужны: только app_folder + disk.info.
|
* Scope-ы Яндекс.OAuth, которые нам нужны: только app_folder + disk.info.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.model
|
package com.github.nullptroma.wallenc.infrastructure.model
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.github.nullptroma.wallenc.infrastructure.model
|
||||||
|
|
||||||
|
data class YandexAccount(
|
||||||
|
val vaultUuid: String,
|
||||||
|
val yandexUserId: String,
|
||||||
|
val email: String,
|
||||||
|
val oauthToken: String,
|
||||||
|
)
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.github.nullptroma.wallenc.data.network.yandexdisk
|
package com.github.nullptroma.wallenc.infrastructure.network.yandexdisk
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.CustomPropertiesPatchDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.CustomPropertiesPatchDto
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.DiskInfoDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.DiskInfoDto
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.LinkDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.LinkDto
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.OperationStatusDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.OperationStatusDto
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.ResourceDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.ResourceDto
|
||||||
import okhttp3.ResponseBody
|
import okhttp3.ResponseBody
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.github.nullptroma.wallenc.data.network.yandexdisk
|
package com.github.nullptroma.wallenc.infrastructure.network.yandexdisk
|
||||||
|
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import com.github.nullptroma.wallenc.data.db.app.repository.YandexAccountRepository
|
import com.github.nullptroma.wallenc.infrastructure.ports.YandexAccountStore
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
@@ -14,7 +14,7 @@ import java.util.UUID
|
|||||||
* плюс «голый» клиент для PUT/GET по одноразовым upload/download URL.
|
* плюс «голый» клиент для PUT/GET по одноразовым upload/download URL.
|
||||||
*/
|
*/
|
||||||
class YandexDiskApiFactory(
|
class YandexDiskApiFactory(
|
||||||
private val accountRepository: YandexAccountRepository,
|
private val accountRepository: YandexAccountStore,
|
||||||
private val ioDispatcher: CoroutineDispatcher,
|
private val ioDispatcher: CoroutineDispatcher,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.network.yandexdisk
|
package com.github.nullptroma.wallenc.infrastructure.network.yandexdisk
|
||||||
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.network.yandexdisk.dto
|
package com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
package com.github.nullptroma.wallenc.data.network.yandexdisk.repository
|
package com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.repository
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.YandexDiskApi
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.YandexDiskApi
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.YandexDiskAuthException
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.YandexDiskAuthException
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.CustomPropertiesPatchDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.CustomPropertiesPatchDto
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.DiskInfoDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.DiskInfoDto
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.EmbeddedResourceListDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.EmbeddedResourceListDto
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.LinkDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.LinkDto
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.OperationStatusDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.OperationStatusDto
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.ResourceDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.ResourceDto
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@@ -181,14 +180,10 @@ class YandexDiskRepository(
|
|||||||
} catch (e: HttpException) {
|
} catch (e: HttpException) {
|
||||||
when (e.code()) {
|
when (e.code()) {
|
||||||
401 -> {
|
401 -> {
|
||||||
Log.w(TAG, "Disk API 401: ${e.message()}")
|
|
||||||
throw YandexDiskAuthException(e.message())
|
throw YandexDiskAuthException(e.message())
|
||||||
}
|
}
|
||||||
404 -> throw e
|
404 -> throw e
|
||||||
else -> {
|
else -> throw e
|
||||||
Log.w(TAG, "Disk API HTTP ${e.code()}: ${e.message()}")
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,7 +197,6 @@ class YandexDiskRepository(
|
|||||||
jackson.readValue(body.string())
|
jackson.readValue(body.string())
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "YandexDiskRepo"
|
|
||||||
private val jackson = jacksonObjectMapper().apply { findAndRegisterModules() }
|
private val jackson = jacksonObjectMapper().apply { findAndRegisterModules() }
|
||||||
private val OCTET_STREAM = "application/octet-stream".toMediaType()
|
private val OCTET_STREAM = "application/octet-stream".toMediaType()
|
||||||
private const val OPERATION_POLL_DELAY_MS = 300L
|
private const val OPERATION_POLL_DELAY_MS = 300L
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.github.nullptroma.wallenc.data.network.yandexdisk.repository
|
package com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.repository
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.YandexDiskApiFactory
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.YandexDiskApiFactory
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.network.yandexuserinfo
|
package com.github.nullptroma.wallenc.infrastructure.network.yandexuserinfo
|
||||||
|
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import retrofit2.http.Header
|
import retrofit2.http.Header
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.network.yandexuserinfo
|
package com.github.nullptroma.wallenc.infrastructure.network.yandexuserinfo
|
||||||
|
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.network.yandexuserinfo
|
package com.github.nullptroma.wallenc.infrastructure.network.yandexuserinfo
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
import com.fasterxml.jackson.annotation.JsonProperty
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.github.nullptroma.wallenc.data.network.yandexuserinfo.repository
|
package com.github.nullptroma.wallenc.infrastructure.network.yandexuserinfo.repository
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexuserinfo.YandexUserInfoApi
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexuserinfo.YandexUserInfoApi
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexuserinfo.YandexUserInfoDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexuserinfo.YandexUserInfoDto
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.github.nullptroma.wallenc.infrastructure.ports
|
||||||
|
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.model.StorageKeyMap
|
||||||
|
|
||||||
|
interface StorageKeyMapStore {
|
||||||
|
suspend fun add(value: StorageKeyMap)
|
||||||
|
suspend fun getAll(): List<StorageKeyMap>
|
||||||
|
suspend fun delete(vararg values: StorageKeyMap)
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.github.nullptroma.wallenc.infrastructure.ports
|
||||||
|
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.model.YandexAccount
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
interface YandexAccountStore {
|
||||||
|
fun observeAll(): Flow<List<YandexAccount>>
|
||||||
|
suspend fun getByYandexUserId(id: String): YandexAccount?
|
||||||
|
suspend fun getByVaultUuid(vaultUuid: String): YandexAccount?
|
||||||
|
suspend fun insert(account: YandexAccount)
|
||||||
|
suspend fun updateCredentials(vaultUuid: String, email: String, token: String)
|
||||||
|
suspend fun deleteByVaultUuid(vaultUuid: String)
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.github.nullptroma.wallenc.data.storages
|
package com.github.nullptroma.wallenc.infrastructure.storages
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.db.app.repository.StorageKeyMapRepository
|
import com.github.nullptroma.wallenc.infrastructure.model.StorageKeyMap
|
||||||
import com.github.nullptroma.wallenc.data.model.StorageKeyMap
|
import com.github.nullptroma.wallenc.infrastructure.ports.StorageKeyMapStore
|
||||||
import com.github.nullptroma.wallenc.data.storages.encrypt.EncryptedStorage
|
import com.github.nullptroma.wallenc.infrastructure.storages.encrypt.EncryptedStorage
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
||||||
import com.github.nullptroma.wallenc.domain.encrypt.Encryptor
|
import com.github.nullptroma.wallenc.domain.encrypt.Encryptor
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
||||||
@@ -21,7 +21,7 @@ import java.security.MessageDigest
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
class UnlockManager(
|
class UnlockManager(
|
||||||
private val keymapRepository: StorageKeyMapRepository,
|
private val keymapRepository: StorageKeyMapStore,
|
||||||
private val ioDispatcher: CoroutineDispatcher,
|
private val ioDispatcher: CoroutineDispatcher,
|
||||||
vaultsManager: IVaultsManager
|
vaultsManager: IVaultsManager
|
||||||
) : IUnlockManager {
|
) : IUnlockManager {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.storages.common
|
package com.github.nullptroma.wallenc.infrastructure.storages.common
|
||||||
|
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonStorageMetaInfo
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonStorageMetaInfo
|
||||||
@@ -54,7 +54,7 @@ abstract class BaseStorage(
|
|||||||
/**
|
/**
|
||||||
* Базовая реализация [IStorageAccessor] передаёт UUID полностью; подклассы
|
* Базовая реализация [IStorageAccessor] передаёт UUID полностью; подклассы
|
||||||
* могут переопределить, чтобы сохранить совместимость с уже существующими
|
* могут переопределить, чтобы сохранить совместимость с уже существующими
|
||||||
* именами файлов (например, [com.github.nullptroma.wallenc.data.storages.encrypt.EncryptedStorage]
|
* именами файлов (например, [com.github.nullptroma.wallenc.infrastructure.storages.encrypt.EncryptedStorage]
|
||||||
* раньше использовал первые 8 символов).
|
* раньше использовал первые 8 символов).
|
||||||
*/
|
*/
|
||||||
protected open fun metaInfoUuidPart(): String = uuid.toString()
|
protected open fun metaInfoUuidPart(): String = uuid.toString()
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.github.nullptroma.wallenc.data.storages.encrypt
|
package com.github.nullptroma.wallenc.infrastructure.storages.encrypt
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.storages.common.BaseStorage
|
import com.github.nullptroma.wallenc.infrastructure.storages.common.BaseStorage
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
||||||
import com.github.nullptroma.wallenc.domain.encrypt.Encryptor
|
import com.github.nullptroma.wallenc.domain.encrypt.Encryptor
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.github.nullptroma.wallenc.data.storages.encrypt
|
package com.github.nullptroma.wallenc.infrastructure.storages.encrypt
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.utils.CloseHandledStreamExtension.Companion.onClosing
|
import com.github.nullptroma.wallenc.infrastructure.utils.CloseHandledStreamExtension.Companion.onClosing
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonDirectory
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonDirectory
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonFile
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonFile
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonMetaInfo
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonMetaInfo
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.github.nullptroma.wallenc.data.storages.local
|
package com.github.nullptroma.wallenc.infrastructure.storages.local
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.storages.common.BaseStorage
|
import com.github.nullptroma.wallenc.infrastructure.storages.common.BaseStorage
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorageAccessor
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorageAccessor
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.github.nullptroma.wallenc.data.storages.local
|
package com.github.nullptroma.wallenc.infrastructure.storages.local
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JacksonException
|
import com.fasterxml.jackson.core.JacksonException
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import com.fasterxml.jackson.module.kotlin.readValue
|
import com.fasterxml.jackson.module.kotlin.readValue
|
||||||
import com.github.nullptroma.wallenc.data.utils.CloseHandledStreamExtension.Companion.onClosed
|
import com.github.nullptroma.wallenc.infrastructure.utils.CloseHandledStreamExtension.Companion.onClosed
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonDirectory
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonDirectory
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonFile
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonFile
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonMetaInfo
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonMetaInfo
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.github.nullptroma.wallenc.data.storages.yandex
|
package com.github.nullptroma.wallenc.infrastructure.storages.yandex
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.repository.YandexDiskRepository
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.repository.YandexDiskRepository
|
||||||
import com.github.nullptroma.wallenc.data.storages.common.BaseStorage
|
import com.github.nullptroma.wallenc.infrastructure.storages.common.BaseStorage
|
||||||
import com.github.nullptroma.wallenc.data.storages.local.LocalStorage
|
import com.github.nullptroma.wallenc.infrastructure.storages.local.LocalStorage
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorageAccessor
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorageAccessor
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.github.nullptroma.wallenc.data.storages.yandex
|
package com.github.nullptroma.wallenc.infrastructure.storages.yandex
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.YandexDiskAuthException
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.YandexDiskAuthException
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.dto.ResourceDto
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.dto.ResourceDto
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.repository.YandexDiskRepository
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.repository.YandexDiskRepository
|
||||||
import com.github.nullptroma.wallenc.data.utils.CloseHandledStreamExtension.Companion.onClosed
|
import com.github.nullptroma.wallenc.infrastructure.utils.CloseHandledStreamExtension.Companion.onClosed
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonDirectory
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonDirectory
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonFile
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonFile
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonMetaInfo
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonMetaInfo
|
||||||
@@ -23,7 +23,6 @@ import kotlinx.coroutines.flow.combine
|
|||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import android.util.Log
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
@@ -73,15 +72,12 @@ class YandexStorageAccessor(
|
|||||||
try {
|
try {
|
||||||
scanSizeAndNumOfFiles()
|
scanSizeAndNumOfFiles()
|
||||||
_storageReady.value = true
|
_storageReady.value = true
|
||||||
Log.d(TAG, "init ok storageUuid=$storageUuid")
|
|
||||||
} catch (e: YandexDiskAuthException) {
|
} catch (e: YandexDiskAuthException) {
|
||||||
reportAuthFailure()
|
reportAuthFailure()
|
||||||
_storageReady.value = false
|
_storageReady.value = false
|
||||||
Log.w(TAG, "init auth failed storageUuid=$storageUuid", e)
|
|
||||||
throw e
|
throw e
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
_storageReady.value = false
|
_storageReady.value = false
|
||||||
Log.w(TAG, "init failed storageUuid=$storageUuid", e)
|
|
||||||
throw Exception("Yandex storage init failed", e)
|
throw Exception("Yandex storage init failed", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -436,7 +432,6 @@ class YandexStorageAccessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "YandexStorageAcc"
|
|
||||||
private const val SYSTEM_HIDDEN_DIRNAME = "wallenc-yandex-system"
|
private const val SYSTEM_HIDDEN_DIRNAME = "wallenc-yandex-system"
|
||||||
private const val DATA_PAGE_LENGTH = 10
|
private const val DATA_PAGE_LENGTH = 10
|
||||||
private const val API_LIST_LIMIT = 200
|
private const val API_LIST_LIMIT = 200
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.utils
|
package com.github.nullptroma.wallenc.infrastructure.utils
|
||||||
|
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.utils
|
package com.github.nullptroma.wallenc.infrastructure.utils
|
||||||
|
|
||||||
interface IProvider<T> {
|
interface IProvider<T> {
|
||||||
suspend fun get(): T?
|
suspend fun get(): T?
|
||||||
@@ -1,22 +1,19 @@
|
|||||||
package com.github.nullptroma.wallenc.data.vaults
|
package com.github.nullptroma.wallenc.infrastructure.vaults
|
||||||
|
|
||||||
import android.content.Context
|
import com.github.nullptroma.wallenc.infrastructure.model.YandexAccount
|
||||||
import com.github.nullptroma.wallenc.data.db.app.model.DbYandexAccount
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.repository.YandexDiskRepositoryFactory
|
||||||
import com.github.nullptroma.wallenc.data.db.app.repository.StorageKeyMapRepository
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexuserinfo.repository.YandexUserInfoRepository
|
||||||
import com.github.nullptroma.wallenc.data.db.app.repository.YandexAccountRepository
|
import com.github.nullptroma.wallenc.infrastructure.ports.StorageKeyMapStore
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.repository.YandexDiskRepositoryFactory
|
import com.github.nullptroma.wallenc.infrastructure.ports.YandexAccountStore
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexuserinfo.repository.YandexUserInfoRepository
|
import com.github.nullptroma.wallenc.infrastructure.storages.UnlockManager
|
||||||
import com.github.nullptroma.wallenc.data.storages.UnlockManager
|
import com.github.nullptroma.wallenc.infrastructure.vaults.yandex.YandexRegistration
|
||||||
import com.github.nullptroma.wallenc.data.vaults.local.LocalVault
|
import com.github.nullptroma.wallenc.infrastructure.vaults.yandex.YandexVault
|
||||||
import com.github.nullptroma.wallenc.data.vaults.local.LocalVaultIdStore
|
|
||||||
import com.github.nullptroma.wallenc.data.vaults.yandex.YandexRegistration
|
|
||||||
import com.github.nullptroma.wallenc.data.vaults.yandex.YandexVault
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
|
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IVault
|
import com.github.nullptroma.wallenc.domain.interfaces.IVault
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultRegistrar
|
import com.github.nullptroma.wallenc.vault.contract.VaultRegistrar
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultRegistration
|
import com.github.nullptroma.wallenc.vault.contract.VaultRegistration
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
@@ -34,22 +31,18 @@ import java.util.UUID
|
|||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
class VaultsManager(
|
class VaultsManager(
|
||||||
private val ioDispatcher: CoroutineDispatcher,
|
private val ioDispatcher: CoroutineDispatcher,
|
||||||
context: Context,
|
localVault: IVault,
|
||||||
keyRepo: StorageKeyMapRepository,
|
keyRepo: StorageKeyMapStore,
|
||||||
private val yandexAccountRepository: YandexAccountRepository,
|
private val yandexAccountStore: YandexAccountStore,
|
||||||
private val yandexUserInfoRepository: YandexUserInfoRepository,
|
private val yandexUserInfoRepository: YandexUserInfoRepository,
|
||||||
private val yandexDiskRepositoryFactory: YandexDiskRepositoryFactory,
|
private val yandexDiskRepositoryFactory: YandexDiskRepositoryFactory,
|
||||||
) : IVaultsManager, VaultRegistrar {
|
) : IVaultsManager, VaultRegistrar {
|
||||||
|
|
||||||
private val scope = CoroutineScope(SupervisorJob() + ioDispatcher)
|
private val scope = CoroutineScope(SupervisorJob() + ioDispatcher)
|
||||||
|
|
||||||
private val localVault: IVault = LocalVault(
|
private val localVault: IVault = localVault
|
||||||
ioDispatcher = ioDispatcher,
|
|
||||||
context = context,
|
|
||||||
idStore = LocalVaultIdStore(context),
|
|
||||||
)
|
|
||||||
|
|
||||||
private val yandexVaults: StateFlow<List<IVault>> = yandexAccountRepository.observeAll()
|
private val yandexVaults: StateFlow<List<IVault>> = yandexAccountStore.observeAll()
|
||||||
.map { rows ->
|
.map { rows ->
|
||||||
rows.map { row ->
|
rows.map { row ->
|
||||||
val vaultUuid = UUID.fromString(row.vaultUuid)
|
val vaultUuid = UUID.fromString(row.vaultUuid)
|
||||||
@@ -91,7 +84,7 @@ class VaultsManager(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun unregister(vaultUuid: UUID): Unit = withContext(ioDispatcher) {
|
override suspend fun unregister(vaultUuid: UUID): Unit = withContext(ioDispatcher) {
|
||||||
yandexAccountRepository.deleteByVaultUuid(vaultUuid.toString())
|
yandexAccountStore.deleteByVaultUuid(vaultUuid.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun registerYandex(registration: YandexRegistration) {
|
private suspend fun registerYandex(registration: YandexRegistration) {
|
||||||
@@ -99,13 +92,13 @@ class VaultsManager(
|
|||||||
val info = yandexUserInfoRepository.userInfo(token)
|
val info = yandexUserInfoRepository.userInfo(token)
|
||||||
val email = info.defaultEmail?.takeIf { it.isNotBlank() }
|
val email = info.defaultEmail?.takeIf { it.isNotBlank() }
|
||||||
?: "${info.login}@yandex.ru"
|
?: "${info.login}@yandex.ru"
|
||||||
val existing = yandexAccountRepository.getByYandexUserId(info.id)
|
val existing = yandexAccountStore.getByYandexUserId(info.id)
|
||||||
val vaultUuid = existing?.vaultUuid ?: UUID.randomUUID().toString()
|
val vaultUuid = existing?.vaultUuid ?: UUID.randomUUID().toString()
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
yandexAccountRepository.updateCredentials(vaultUuid, email, token)
|
yandexAccountStore.updateCredentials(vaultUuid, email, token)
|
||||||
} else {
|
} else {
|
||||||
yandexAccountRepository.insert(
|
yandexAccountStore.insert(
|
||||||
DbYandexAccount(
|
YandexAccount(
|
||||||
vaultUuid = vaultUuid,
|
vaultUuid = vaultUuid,
|
||||||
yandexUserId = info.id,
|
yandexUserId = info.id,
|
||||||
email = email,
|
email = email,
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.github.nullptroma.wallenc.data.vaults.yandex
|
package com.github.nullptroma.wallenc.infrastructure.vaults.yandex
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.vaultapi.CloudBrand
|
import com.github.nullptroma.wallenc.vault.contract.CloudBrand
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultRegistration
|
import com.github.nullptroma.wallenc.vault.contract.VaultRegistration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Регистрация удалённого vault'а Яндекс.Диска по результату OAuth.
|
* Регистрация удалённого vault'а Яндекс.Диска по результату OAuth.
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
package com.github.nullptroma.wallenc.data.vaults.yandex
|
package com.github.nullptroma.wallenc.infrastructure.vaults.yandex
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.YandexDiskAuthException
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.YandexDiskAuthException
|
||||||
import com.github.nullptroma.wallenc.data.network.yandexdisk.repository.YandexDiskRepository
|
import com.github.nullptroma.wallenc.infrastructure.network.yandexdisk.repository.YandexDiskRepository
|
||||||
import com.github.nullptroma.wallenc.data.storages.yandex.YandexStorage
|
import com.github.nullptroma.wallenc.infrastructure.storages.yandex.YandexStorage
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.StorageEncryptionInfo
|
import com.github.nullptroma.wallenc.domain.datatypes.StorageEncryptionInfo
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
||||||
import com.github.nullptroma.wallenc.vaultapi.CloudBrand
|
import com.github.nullptroma.wallenc.vault.contract.CloudBrand
|
||||||
import com.github.nullptroma.wallenc.vaultapi.DescribedVault
|
import com.github.nullptroma.wallenc.vault.contract.DescribedVault
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultDescriptor
|
import com.github.nullptroma.wallenc.vault.contract.VaultDescriptor
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import android.util.Log
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -65,15 +64,12 @@ class YandexVault(
|
|||||||
_availableSpace.value = (total - used).coerceAtLeast(0L)
|
_availableSpace.value = (total - used).coerceAtLeast(0L)
|
||||||
_vaultReachable.value = true
|
_vaultReachable.value = true
|
||||||
_storages.value = loadStoragesList()
|
_storages.value = loadStoragesList()
|
||||||
Log.d(TAG, "refresh ok uuid=$uuid storages=${_storages.value.size}")
|
|
||||||
} catch (e: YandexDiskAuthException) {
|
} catch (e: YandexDiskAuthException) {
|
||||||
_vaultReachable.value = false
|
_vaultReachable.value = false
|
||||||
_storages.value = emptyList()
|
_storages.value = emptyList()
|
||||||
Log.w(TAG, "refresh auth failed uuid=$uuid: ${e.message}")
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
_vaultReachable.value = false
|
_vaultReachable.value = false
|
||||||
_storages.value = emptyList()
|
_storages.value = emptyList()
|
||||||
Log.w(TAG, "refresh failed uuid=$uuid", e)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,9 +96,7 @@ class YandexVault(
|
|||||||
try {
|
try {
|
||||||
storage.init()
|
storage.init()
|
||||||
out.add(storage)
|
out.add(storage)
|
||||||
} catch (e: Exception) {
|
} catch (_: Exception) { }
|
||||||
Log.w(TAG, "skip broken storage uuid=$storageUuid: ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (items.size < APP_LIST_LIMIT) break
|
if (items.size < APP_LIST_LIMIT) break
|
||||||
offset += items.size
|
offset += items.size
|
||||||
@@ -112,7 +106,6 @@ class YandexVault(
|
|||||||
|
|
||||||
override suspend fun createStorage(): IStorage = withContext(ioDispatcher) {
|
override suspend fun createStorage(): IStorage = withContext(ioDispatcher) {
|
||||||
val id = UUID.randomUUID()
|
val id = UUID.randomUUID()
|
||||||
Log.d(TAG, "createStorage start vault=$uuid storage=$id")
|
|
||||||
repo.createFolder("app:/$id")
|
repo.createFolder("app:/$id")
|
||||||
val storage = YandexStorage(
|
val storage = YandexStorage(
|
||||||
uuid = id,
|
uuid = id,
|
||||||
@@ -126,7 +119,6 @@ class YandexVault(
|
|||||||
)
|
)
|
||||||
storage.init()
|
storage.init()
|
||||||
_storages.value = _storages.value + storage
|
_storages.value = _storages.value + storage
|
||||||
Log.d(TAG, "createStorage done storage=$id")
|
|
||||||
storage
|
storage
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,13 +130,11 @@ class YandexVault(
|
|||||||
|
|
||||||
override suspend fun remove(storage: IStorage) = withContext(ioDispatcher) {
|
override suspend fun remove(storage: IStorage) = withContext(ioDispatcher) {
|
||||||
if (storage !is YandexStorage) return@withContext
|
if (storage !is YandexStorage) return@withContext
|
||||||
Log.d(TAG, "remove storage=${storage.uuid}")
|
|
||||||
repo.delete("app:/${storage.uuid}", permanently = true)
|
repo.delete("app:/${storage.uuid}", permanently = true)
|
||||||
_storages.value = _storages.value.filter { it.uuid != storage.uuid }
|
_storages.value = _storages.value.filter { it.uuid != storage.uuid }
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
private const val TAG = "YandexVault"
|
|
||||||
private const val APP_LIST_LIMIT = 200
|
private const val APP_LIST_LIMIT = 200
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation
|
package com.github.nullptroma.wallenc.infrastructure
|
||||||
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@@ -9,6 +9,10 @@ java {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(17)
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.kotlinx.coroutines.core)
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
|
|||||||
@@ -4,13 +4,11 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.github.nullptroma.wallenc.data"
|
namespace = "com.github.nullptroma.wallenc.infrastructure.android"
|
||||||
compileSdk = 37
|
compileSdk = 37
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
||||||
consumerProguardFiles("consumer-rules.pro")
|
consumerProguardFiles("consumer-rules.pro")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,38 +21,27 @@ android {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
kotlin {
|
|
||||||
jvmToolchain(17)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// jackson
|
implementation(project(":domain"))
|
||||||
|
implementation(project(":domain-storage"))
|
||||||
|
implementation(project(":vault-contracts"))
|
||||||
|
|
||||||
implementation(libs.jackson.module.kotlin)
|
implementation(libs.jackson.module.kotlin)
|
||||||
implementation(libs.jackson.datatype.jsr310)
|
implementation(libs.jackson.datatype.jsr310)
|
||||||
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
|
|
||||||
// Room
|
|
||||||
implementation(libs.room.ktx)
|
implementation(libs.room.ktx)
|
||||||
implementation(libs.room.runtime)
|
implementation(libs.room.runtime)
|
||||||
ksp(libs.room.compiler)
|
ksp(libs.room.compiler)
|
||||||
|
|
||||||
// Retrofit
|
|
||||||
implementation(libs.retrofit)
|
|
||||||
implementation(libs.retrofit.converter.scalars)
|
|
||||||
implementation(libs.retrofit.converter.jackson)
|
|
||||||
|
|
||||||
implementation("com.squareup.okhttp3:okhttp:4.12.0")
|
|
||||||
|
|
||||||
implementation(libs.androidx.core.ktx)
|
implementation(libs.androidx.core.ktx)
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.androidx.junit)
|
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
|
||||||
|
|
||||||
implementation(project(":domain"))
|
|
||||||
implementation(project(":vault-api"))
|
|
||||||
}
|
}
|
||||||
2
infrastructure-android/src/main/AndroidManifest.xml
Normal file
2
infrastructure-android/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest />
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db
|
package com.github.nullptroma.wallenc.infrastructure.db
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import com.github.nullptroma.wallenc.data.db.app.AppDb
|
import com.github.nullptroma.wallenc.infrastructure.db.app.AppDb
|
||||||
|
|
||||||
class RoomFactory(private val context: Context) {
|
class RoomFactory(private val context: Context) {
|
||||||
fun buildAppDb(): AppDb {
|
fun buildAppDb(): AppDb {
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db.app
|
package com.github.nullptroma.wallenc.infrastructure.db.app
|
||||||
|
|
||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.StorageKeyMapDao
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.StorageKeyMapDao
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.StorageMetaInfoDao
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.StorageMetaInfoDao
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.YandexAccountDao
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.YandexAccountDao
|
||||||
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageKeyMap
|
import com.github.nullptroma.wallenc.infrastructure.db.app.model.DbStorageKeyMap
|
||||||
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageMetaInfo
|
import com.github.nullptroma.wallenc.infrastructure.db.app.model.DbStorageMetaInfo
|
||||||
import com.github.nullptroma.wallenc.data.db.app.model.DbYandexAccount
|
import com.github.nullptroma.wallenc.infrastructure.db.app.model.DbYandexAccount
|
||||||
|
|
||||||
interface IAppDb {
|
interface IAppDb {
|
||||||
val storageKeyMapDao: StorageKeyMapDao
|
val storageKeyMapDao: StorageKeyMapDao
|
||||||
@@ -18,7 +18,7 @@ interface IAppDb {
|
|||||||
@Database(
|
@Database(
|
||||||
entities = [DbStorageKeyMap::class, DbStorageMetaInfo::class, DbYandexAccount::class],
|
entities = [DbStorageKeyMap::class, DbStorageMetaInfo::class, DbYandexAccount::class],
|
||||||
version = 4,
|
version = 4,
|
||||||
exportSchema = false,
|
exportSchema = false
|
||||||
)
|
)
|
||||||
abstract class AppDb : IAppDb, RoomDatabase() {
|
abstract class AppDb : IAppDb, RoomDatabase() {
|
||||||
abstract override val storageKeyMapDao: StorageKeyMapDao
|
abstract override val storageKeyMapDao: StorageKeyMapDao
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db.app.dao
|
package com.github.nullptroma.wallenc.infrastructure.db.app.dao
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageKeyMap
|
import com.github.nullptroma.wallenc.infrastructure.db.app.model.DbStorageKeyMap
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface StorageKeyMapDao {
|
interface StorageKeyMapDao {
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db.app.dao
|
package com.github.nullptroma.wallenc.infrastructure.db.app.dao
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageMetaInfo
|
import com.github.nullptroma.wallenc.infrastructure.db.app.model.DbStorageMetaInfo
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db.app.dao
|
package com.github.nullptroma.wallenc.infrastructure.db.app.dao
|
||||||
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import com.github.nullptroma.wallenc.data.db.app.model.DbYandexAccount
|
import com.github.nullptroma.wallenc.infrastructure.db.app.model.DbYandexAccount
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db.app.model
|
package com.github.nullptroma.wallenc.infrastructure.db.app.model
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import com.github.nullptroma.wallenc.data.model.StorageKeyMap
|
import com.github.nullptroma.wallenc.infrastructure.model.StorageKeyMap
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db.app.model
|
package com.github.nullptroma.wallenc.infrastructure.db.app.model
|
||||||
|
|
||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db.app.model
|
package com.github.nullptroma.wallenc.infrastructure.db.app.model
|
||||||
|
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.Index
|
import androidx.room.Index
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.github.nullptroma.wallenc.infrastructure.db.app.repository
|
||||||
|
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.StorageKeyMapDao
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.db.app.model.DbStorageKeyMap
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.model.StorageKeyMap
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.ports.StorageKeyMapStore
|
||||||
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
class StorageKeyMapRepository(
|
||||||
|
private val dao: StorageKeyMapDao,
|
||||||
|
private val ioDispatcher: CoroutineDispatcher
|
||||||
|
) : StorageKeyMapStore {
|
||||||
|
override suspend fun getAll() = withContext(ioDispatcher) { dao.getAll().map { it.toModel() } }
|
||||||
|
override suspend fun add(value: StorageKeyMap) = withContext(ioDispatcher) {
|
||||||
|
val dbModel = DbStorageKeyMap.fromModel(value)
|
||||||
|
dao.add(dbModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun add(vararg keymaps: StorageKeyMap) = withContext(ioDispatcher) {
|
||||||
|
val dbModels = keymaps.map { DbStorageKeyMap.fromModel(it) }
|
||||||
|
dao.add(*dbModels.toTypedArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun delete(vararg keymaps: StorageKeyMap) = withContext(ioDispatcher) {
|
||||||
|
val dbModels = keymaps.map { DbStorageKeyMap.fromModel(it) }
|
||||||
|
dao.delete(*dbModels.toTypedArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.github.nullptroma.wallenc.data.db.app.repository
|
package com.github.nullptroma.wallenc.infrastructure.db.app.repository
|
||||||
|
|
||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import com.github.nullptroma.wallenc.data.db.app.dao.StorageMetaInfoDao
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.StorageMetaInfoDao
|
||||||
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageMetaInfo
|
import com.github.nullptroma.wallenc.infrastructure.db.app.model.DbStorageMetaInfo
|
||||||
import com.github.nullptroma.wallenc.data.utils.IProvider
|
import com.github.nullptroma.wallenc.infrastructure.utils.IProvider
|
||||||
import com.github.nullptroma.wallenc.domain.common.impl.CommonStorageMetaInfo
|
import com.github.nullptroma.wallenc.domain.common.impl.CommonStorageMetaInfo
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.github.nullptroma.wallenc.infrastructure.db.app.repository
|
||||||
|
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.db.app.dao.YandexAccountDao
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.db.app.model.DbYandexAccount
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.model.YandexAccount
|
||||||
|
import com.github.nullptroma.wallenc.infrastructure.ports.YandexAccountStore
|
||||||
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
class YandexAccountRepository(
|
||||||
|
private val dao: YandexAccountDao,
|
||||||
|
private val ioDispatcher: CoroutineDispatcher
|
||||||
|
) : YandexAccountStore {
|
||||||
|
override fun observeAll(): Flow<List<YandexAccount>> = dao.observeAll().map { rows ->
|
||||||
|
rows.map { it.toModel() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getByYandexUserId(id: String): YandexAccount? = withContext(ioDispatcher) {
|
||||||
|
dao.getByYandexUserId(id)?.toModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getByVaultUuid(vaultUuid: String): YandexAccount? = withContext(ioDispatcher) {
|
||||||
|
dao.getByVaultUuid(vaultUuid)?.toModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun insert(account: YandexAccount) = withContext(ioDispatcher) {
|
||||||
|
dao.insert(fromModel(account))
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun updateCredentials(vaultUuid: String, email: String, token: String) =
|
||||||
|
withContext(ioDispatcher) {
|
||||||
|
dao.updateCredentials(vaultUuid, email, token)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteByVaultUuid(vaultUuid: String) = withContext(ioDispatcher) {
|
||||||
|
dao.deleteByVaultUuid(vaultUuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DbYandexAccount.toModel(): YandexAccount =
|
||||||
|
YandexAccount(
|
||||||
|
vaultUuid = vaultUuid,
|
||||||
|
yandexUserId = yandexUserId,
|
||||||
|
email = email,
|
||||||
|
oauthToken = oauthToken,
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun fromModel(model: YandexAccount): DbYandexAccount =
|
||||||
|
DbYandexAccount(
|
||||||
|
vaultUuid = model.vaultUuid,
|
||||||
|
yandexUserId = model.yandexUserId,
|
||||||
|
email = model.email,
|
||||||
|
oauthToken = model.oauthToken,
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.github.nullptroma.wallenc.data.vaults.local
|
package com.github.nullptroma.wallenc.infrastructure.vaults.local
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.github.nullptroma.wallenc.data.storages.local.LocalStorage
|
import com.github.nullptroma.wallenc.infrastructure.storages.local.LocalStorage
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.StorageEncryptionInfo
|
import com.github.nullptroma.wallenc.domain.datatypes.StorageEncryptionInfo
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
||||||
import com.github.nullptroma.wallenc.vaultapi.DescribedVault
|
import com.github.nullptroma.wallenc.vault.contract.DescribedVault
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultDescriptor
|
import com.github.nullptroma.wallenc.vault.contract.VaultDescriptor
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.vaults.local
|
package com.github.nullptroma.wallenc.infrastructure.vaults.local
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main
|
|
||||||
|
|
||||||
class MainScreenState
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes
|
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.MainRoute
|
|
||||||
import kotlinx.parcelize.Parcelize
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
@Parcelize
|
|
||||||
class RemoteVaultsRoute : MainRoute()
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.tasks
|
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.ScreenRoute
|
|
||||||
import kotlinx.parcelize.Parcelize
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
@Parcelize
|
|
||||||
class TaskPipelineRoute : ScreenRoute()
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.vault
|
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.MainRoute
|
|
||||||
import kotlinx.parcelize.Parcelize
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
@Parcelize
|
|
||||||
class LocalVaultRoute : MainRoute()
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.settings
|
|
||||||
|
|
||||||
class SettingsScreenState
|
|
||||||
@@ -24,7 +24,10 @@ dependencyResolutionManagement {
|
|||||||
|
|
||||||
rootProject.name = "Wallenc"
|
rootProject.name = "Wallenc"
|
||||||
include(":app")
|
include(":app")
|
||||||
include(":data")
|
|
||||||
include(":domain")
|
include(":domain")
|
||||||
include(":presentation")
|
include(":usecases")
|
||||||
include(":vault-api")
|
include(":ui")
|
||||||
|
include(":domain-storage")
|
||||||
|
include(":infrastructure-android")
|
||||||
|
include(":vault-contracts")
|
||||||
|
include(":task-runtime")
|
||||||
|
|||||||
20
task-runtime/build.gradle.kts
Normal file
20
task-runtime/build.gradle.kts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
plugins {
|
||||||
|
id("java-library")
|
||||||
|
alias(libs.plugins.jetbrains.kotlin.jvm)
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain {
|
||||||
|
languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(17)
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":domain"))
|
||||||
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
|
testImplementation(libs.junit)
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data.tasks
|
package com.github.nullptroma.wallenc.task.runtime
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.PipelineState
|
import com.github.nullptroma.wallenc.domain.tasks.PipelineState
|
||||||
@@ -12,11 +12,11 @@ import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
|||||||
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLine
|
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLine
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.TaskProgress
|
import com.github.nullptroma.wallenc.domain.tasks.TaskProgress
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
||||||
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.CancellationException
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
0
presentation/.gitignore → ui/.gitignore
vendored
0
presentation/.gitignore → ui/.gitignore
vendored
@@ -8,7 +8,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.github.nullptroma.wallenc.presentation"
|
namespace = "com.github.nullptroma.wallenc.ui"
|
||||||
compileSdk = 37
|
compileSdk = 37
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
@@ -79,5 +79,6 @@ dependencies {
|
|||||||
androidTestImplementation(libs.androidx.ui.test.junit4)
|
androidTestImplementation(libs.androidx.ui.test.junit4)
|
||||||
|
|
||||||
implementation(project(":domain"))
|
implementation(project(":domain"))
|
||||||
implementation(project(":vault-api"))
|
implementation(project(":usecases"))
|
||||||
|
implementation(project(":vault-contracts"))
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.data
|
package com.github.nullptroma.wallenc.ui
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
@@ -19,6 +19,6 @@ class ExampleInstrumentedTest {
|
|||||||
fun useAppContext() {
|
fun useAppContext() {
|
||||||
// Context of the app under test.
|
// Context of the app under test.
|
||||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
assertEquals("com.github.nullptroma.wallenc.data.test", appContext.packageName)
|
assertEquals("com.github.nullptroma.wallenc.ui.test", appContext.packageName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation
|
package com.github.nullptroma.wallenc.ui
|
||||||
|
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation
|
package com.github.nullptroma.wallenc.ui
|
||||||
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
@@ -25,17 +25,17 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import com.github.nullptroma.wallenc.presentation.navigation.NavBarItemData
|
import com.github.nullptroma.wallenc.ui.navigation.NavBarItemData
|
||||||
import com.github.nullptroma.wallenc.presentation.navigation.rememberNavigationState
|
import com.github.nullptroma.wallenc.ui.navigation.rememberNavigationState
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.MainRoute
|
import com.github.nullptroma.wallenc.ui.screens.main.MainRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.MainScreen
|
import com.github.nullptroma.wallenc.ui.screens.main.MainScreen
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.MainViewModel
|
import com.github.nullptroma.wallenc.ui.screens.main.MainViewModel
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.tasks.TaskPipelineRoute
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.tasks.TaskPipelineRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.tasks.TaskPipelineScreen
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.tasks.TaskPipelineScreen
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsRoute
|
import com.github.nullptroma.wallenc.ui.screens.settings.SettingsRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsScreen
|
import com.github.nullptroma.wallenc.ui.screens.settings.SettingsScreen
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsViewModel
|
import com.github.nullptroma.wallenc.ui.screens.settings.SettingsViewModel
|
||||||
import com.github.nullptroma.wallenc.presentation.theme.WallencTheme
|
import com.github.nullptroma.wallenc.ui.theme.WallencTheme
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation
|
package com.github.nullptroma.wallenc.ui
|
||||||
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi
|
import androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi
|
||||||
import androidx.lifecycle.viewmodel.compose.saveable
|
import androidx.lifecycle.viewmodel.compose.saveable
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.ScreenRoute
|
import com.github.nullptroma.wallenc.ui.screens.ScreenRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.MainRoute
|
import com.github.nullptroma.wallenc.ui.screens.main.MainRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.tasks.TaskPipelineRoute
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.tasks.TaskPipelineRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsRoute
|
import com.github.nullptroma.wallenc.ui.screens.settings.SettingsRoute
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.elements
|
package com.github.nullptroma.wallenc.ui.elements
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.elements
|
package com.github.nullptroma.wallenc.ui.elements
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
@@ -47,8 +47,8 @@ import androidx.compose.ui.zIndex
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.Tree
|
import com.github.nullptroma.wallenc.domain.datatypes.Tree
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo
|
||||||
import com.github.nullptroma.wallenc.presentation.R
|
import com.github.nullptroma.wallenc.ui.R
|
||||||
import com.github.nullptroma.wallenc.presentation.utils.debouncedLambda
|
import com.github.nullptroma.wallenc.ui.utils.debouncedLambda
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun StorageTree(
|
fun StorageTree(
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.elements.indication
|
package com.github.nullptroma.wallenc.ui.elements.indication
|
||||||
|
|
||||||
import androidx.compose.animation.core.Animatable
|
import androidx.compose.animation.core.Animatable
|
||||||
import androidx.compose.animation.core.spring
|
import androidx.compose.animation.core.spring
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.extensions
|
package com.github.nullptroma.wallenc.ui.extensions
|
||||||
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.pointer.PointerEventPass
|
import androidx.compose.ui.input.pointer.PointerEventPass
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.extensions
|
package com.github.nullptroma.wallenc.ui.extensions
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.navigation
|
package com.github.nullptroma.wallenc.ui.navigation
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.navigation
|
package com.github.nullptroma.wallenc.ui.navigation
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.ScreenRoute
|
import com.github.nullptroma.wallenc.ui.screens.ScreenRoute
|
||||||
|
|
||||||
|
|
||||||
class NavigationState(
|
class NavigationState(
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens
|
package com.github.nullptroma.wallenc.ui.screens
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main
|
package com.github.nullptroma.wallenc.ui.screens.main
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.ScreenRoute
|
import com.github.nullptroma.wallenc.ui.screens.ScreenRoute
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main
|
package com.github.nullptroma.wallenc.ui.screens.main
|
||||||
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
@@ -23,21 +23,21 @@ import androidx.navigation.compose.NavHost
|
|||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.toRoute
|
import androidx.navigation.toRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.R
|
import com.github.nullptroma.wallenc.ui.R
|
||||||
import com.github.nullptroma.wallenc.presentation.navigation.NavBarItemData
|
import com.github.nullptroma.wallenc.ui.navigation.NavBarItemData
|
||||||
import com.github.nullptroma.wallenc.presentation.navigation.NavigationState
|
import com.github.nullptroma.wallenc.ui.navigation.NavigationState
|
||||||
import com.github.nullptroma.wallenc.presentation.navigation.rememberNavigationState
|
import com.github.nullptroma.wallenc.ui.navigation.rememberNavigationState
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes.RemoteVaultsRoute
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.remotes.RemoteVaultsRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes.RemoteVaultsScreen
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.remotes.RemoteVaultsScreen
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes.RemoteVaultsViewModel
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.remotes.RemoteVaultsViewModel
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.vault.LocalVaultRoute
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.vault.LocalVaultRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.vault.LocalVaultScreen
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.vault.LocalVaultScreen
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.vault.LocalVaultViewModel
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.vault.LocalVaultViewModel
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.vault.RemoteVaultViewModel
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.vault.RemoteVaultViewModel
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.vault.VaultBrowserRoute
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.vault.VaultBrowserRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.vault.VaultBrowserScreen
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.vault.VaultBrowserScreen
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.shared.TextEditRoute
|
import com.github.nullptroma.wallenc.ui.screens.shared.TextEditRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.shared.TextEditScreen
|
import com.github.nullptroma.wallenc.ui.screens.shared.TextEditScreen
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package com.github.nullptroma.wallenc.ui.screens.main
|
||||||
|
|
||||||
|
class MainScreenState
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main
|
package com.github.nullptroma.wallenc.ui.screens.main
|
||||||
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi
|
import androidx.lifecycle.viewmodel.compose.SavedStateHandleSaveableApi
|
||||||
import androidx.lifecycle.viewmodel.compose.saveable
|
import androidx.lifecycle.viewmodel.compose.saveable
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.ScreenRoute
|
import com.github.nullptroma.wallenc.ui.screens.ScreenRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes.RemoteVaultsRoute
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.remotes.RemoteVaultsRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.screens.main.screens.vault.LocalVaultRoute
|
import com.github.nullptroma.wallenc.ui.screens.main.screens.vault.LocalVaultRoute
|
||||||
import com.github.nullptroma.wallenc.presentation.ViewModelBase
|
import com.github.nullptroma.wallenc.ui.ViewModelBase
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.remotes
|
||||||
|
|
||||||
|
import com.github.nullptroma.wallenc.ui.screens.main.MainRoute
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@Parcelize
|
||||||
|
class RemoteVaultsRoute : MainRoute()
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.remotes
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
@@ -44,9 +44,9 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.github.nullptroma.wallenc.presentation.R
|
import com.github.nullptroma.wallenc.ui.R
|
||||||
import com.github.nullptroma.wallenc.vaultapi.CloudBrand
|
import com.github.nullptroma.wallenc.vault.contract.CloudBrand
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultLinkOutcome
|
import com.github.nullptroma.wallenc.vault.contract.VaultLinkOutcome
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RemoteVaultsScreen(
|
fun RemoteVaultsScreen(
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.remotes
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.vaultapi.CloudBrand
|
import com.github.nullptroma.wallenc.vault.contract.CloudBrand
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
data class RemoteVaultListItem(
|
data class RemoteVaultListItem(
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.remotes
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.remotes
|
||||||
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
||||||
import com.github.nullptroma.wallenc.presentation.ViewModelBase
|
import com.github.nullptroma.wallenc.ui.ViewModelBase
|
||||||
import com.github.nullptroma.wallenc.vaultapi.RemoteVaultAuthenticator
|
import com.github.nullptroma.wallenc.vault.contract.RemoteVaultAuthenticator
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultDescriptor
|
import com.github.nullptroma.wallenc.vault.contract.VaultDescriptor
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultRegistrar
|
import com.github.nullptroma.wallenc.vault.contract.VaultRegistrar
|
||||||
import com.github.nullptroma.wallenc.vaultapi.VaultRegistration
|
import com.github.nullptroma.wallenc.vault.contract.VaultRegistration
|
||||||
import com.github.nullptroma.wallenc.vaultapi.described
|
import com.github.nullptroma.wallenc.vault.contract.described
|
||||||
import com.github.nullptroma.wallenc.vaultapi.remotes
|
import com.github.nullptroma.wallenc.vault.contract.remotes
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.tasks
|
||||||
|
|
||||||
|
import com.github.nullptroma.wallenc.ui.screens.ScreenRoute
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@Parcelize
|
||||||
|
class TaskPipelineRoute : ScreenRoute()
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.tasks
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.tasks
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@@ -35,7 +35,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import com.github.nullptroma.wallenc.domain.tasks.PipelineTask
|
import com.github.nullptroma.wallenc.domain.tasks.PipelineTask
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
import com.github.nullptroma.wallenc.domain.tasks.TaskRunState
|
||||||
import com.github.nullptroma.wallenc.presentation.R
|
import com.github.nullptroma.wallenc.ui.R
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.tasks
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.tasks
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.vault
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.vault
|
||||||
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
|
||||||
@@ -10,14 +10,14 @@ import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
|||||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo
|
import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
import com.github.nullptroma.wallenc.domain.tasks.TaskLogLevel
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.GetOpenedStoragesUseCase
|
import com.github.nullptroma.wallenc.usecases.GetOpenedStoragesUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.ManageStoragesEncryptionUseCase
|
import com.github.nullptroma.wallenc.usecases.ManageStoragesEncryptionUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.ManageVaultUseCase
|
import com.github.nullptroma.wallenc.usecases.ManageVaultUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.RemoveStorageUseCase
|
import com.github.nullptroma.wallenc.usecases.RemoveStorageUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.RenameStorageUseCase
|
import com.github.nullptroma.wallenc.usecases.RenameStorageUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.StorageFileManagementUseCase
|
import com.github.nullptroma.wallenc.usecases.StorageFileManagementUseCase
|
||||||
import com.github.nullptroma.wallenc.presentation.ViewModelBase
|
import com.github.nullptroma.wallenc.ui.ViewModelBase
|
||||||
import com.github.nullptroma.wallenc.presentation.extensions.toPrintable
|
import com.github.nullptroma.wallenc.ui.extensions.toPrintable
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.vault
|
||||||
|
|
||||||
|
import com.github.nullptroma.wallenc.ui.screens.main.MainRoute
|
||||||
|
import kotlinx.parcelize.Parcelize
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@Parcelize
|
||||||
|
class LocalVaultRoute : MainRoute()
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.vault
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.vault
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
package com.github.nullptroma.wallenc.presentation.screens.main.screens.vault
|
package com.github.nullptroma.wallenc.ui.screens.main.screens.vault
|
||||||
|
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.ILogger
|
import com.github.nullptroma.wallenc.domain.interfaces.ILogger
|
||||||
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager
|
||||||
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
import com.github.nullptroma.wallenc.domain.tasks.ITaskOrchestrator
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.GetOpenedStoragesUseCase
|
import com.github.nullptroma.wallenc.usecases.GetOpenedStoragesUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.ManageStoragesEncryptionUseCase
|
import com.github.nullptroma.wallenc.usecases.ManageStoragesEncryptionUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.ManageVaultUseCase
|
import com.github.nullptroma.wallenc.usecases.ManageVaultUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.RemoveStorageUseCase
|
import com.github.nullptroma.wallenc.usecases.RemoveStorageUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.RenameStorageUseCase
|
import com.github.nullptroma.wallenc.usecases.RenameStorageUseCase
|
||||||
import com.github.nullptroma.wallenc.domain.usecases.StorageFileManagementUseCase
|
import com.github.nullptroma.wallenc.usecases.StorageFileManagementUseCase
|
||||||
import com.github.nullptroma.wallenc.vaultapi.described
|
import com.github.nullptroma.wallenc.vault.contract.described
|
||||||
import com.github.nullptroma.wallenc.vaultapi.locals
|
import com.github.nullptroma.wallenc.vault.contract.locals
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user