Большая реструктуризация проекта

This commit is contained in:
2026-05-11 19:33:32 +03:00
parent ad985679ee
commit 3928ac5409
132 changed files with 574 additions and 450 deletions

View File

@@ -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"))
} }

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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(

View File

@@ -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

View File

@@ -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())
}
}

View File

@@ -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)
}
}

View 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"))
}

View File

@@ -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)
} }
} }

View File

@@ -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.

View File

@@ -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

View File

@@ -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,
)

View File

@@ -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

View File

@@ -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,
) { ) {

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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 {

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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?

View File

@@ -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,

View File

@@ -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.

View File

@@ -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
} }
} }

View File

@@ -1,4 +1,4 @@
package com.github.nullptroma.wallenc.presentation package com.github.nullptroma.wallenc.infrastructure
import org.junit.Test import org.junit.Test

View File

@@ -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)

View File

@@ -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"))
} }

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />

View File

@@ -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 {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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())
}
}

View File

@@ -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

View File

@@ -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,
)
}

View File

@@ -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

View File

@@ -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

View File

@@ -1,3 +0,0 @@
package com.github.nullptroma.wallenc.presentation.screens.main
class MainScreenState

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -1,3 +0,0 @@
package com.github.nullptroma.wallenc.presentation.screens.settings
class SettingsScreenState

View File

@@ -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")

View 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)
}

View File

@@ -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

View File

@@ -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"))
} }

View File

@@ -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)
} }
} }

View File

@@ -1,4 +1,4 @@
package com.github.nullptroma.wallenc.presentation package com.github.nullptroma.wallenc.ui
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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(

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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(

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -0,0 +1,3 @@
package com.github.nullptroma.wallenc.ui.screens.main
class MainScreenState

View File

@@ -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

View File

@@ -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()

View File

@@ -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(

View File

@@ -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(

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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