mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
chore: Preparing for Unified Storage
This commit is contained in:
parent
6c777d5b71
commit
db996acfb6
6 changed files with 132 additions and 0 deletions
73
app/src/main/java/dev/yokai/domain/storage/StorageManager.kt
Normal file
73
app/src/main/java/dev/yokai/domain/storage/StorageManager.kt
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
package dev.yokai.domain.storage
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
import com.hippo.unifile.UniFile
|
||||||
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.channels.Channel
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
import kotlinx.coroutines.flow.drop
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
|
import kotlinx.coroutines.flow.shareIn
|
||||||
|
|
||||||
|
class StorageManager(
|
||||||
|
private val context: Context,
|
||||||
|
storagePreferences: StoragePreferences,
|
||||||
|
) {
|
||||||
|
private val scope = CoroutineScope(Dispatchers.IO)
|
||||||
|
|
||||||
|
private var baseDir: UniFile? = getBaseDir(storagePreferences.baseStorageDirectory().get())
|
||||||
|
|
||||||
|
private val _changes: Channel<Unit> = Channel(Channel.UNLIMITED)
|
||||||
|
val changes = _changes.receiveAsFlow()
|
||||||
|
.shareIn(scope, SharingStarted.Lazily, 1)
|
||||||
|
|
||||||
|
init {
|
||||||
|
storagePreferences.baseStorageDirectory().changes()
|
||||||
|
.drop(1)
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.onEach { uri ->
|
||||||
|
baseDir = getBaseDir(uri)
|
||||||
|
baseDir?.let { parent ->
|
||||||
|
parent.createDirectory(AUTOMATIC_BACKUPS_PATH)
|
||||||
|
parent.createDirectory(LOCAL_SOURCE_PATH)
|
||||||
|
parent.createDirectory(DOWNLOADS_PATH).also {
|
||||||
|
DiskUtil.createNoMediaFile(it, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_changes.send(Unit)
|
||||||
|
}
|
||||||
|
.launchIn(scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getBaseDir(uri: String): UniFile? {
|
||||||
|
return UniFile.fromUri(context, uri.toUri())
|
||||||
|
.takeIf { it?.exists() == true }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBackupsDirectory(): UniFile? {
|
||||||
|
return baseDir?.createDirectory(BACKUPS_PATH)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAutomaticBackupsDirectory(): UniFile? {
|
||||||
|
return baseDir?.createDirectory(AUTOMATIC_BACKUPS_PATH)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDownloadsDirectory(): UniFile? {
|
||||||
|
return baseDir?.createDirectory(DOWNLOADS_PATH)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLocalSourceDirectory(): UniFile? {
|
||||||
|
return baseDir?.createDirectory(LOCAL_SOURCE_PATH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val BACKUPS_PATH = "autobackup"
|
||||||
|
private const val AUTOMATIC_BACKUPS_PATH = "autobackup"
|
||||||
|
private const val DOWNLOADS_PATH = "downloads"
|
||||||
|
private const val LOCAL_SOURCE_PATH = "local"
|
|
@ -0,0 +1,12 @@
|
||||||
|
package dev.yokai.domain.storage
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.core.preference.Preference
|
||||||
|
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
||||||
|
import eu.kanade.tachiyomi.core.storage.FolderProvider
|
||||||
|
|
||||||
|
class StoragePreferences(
|
||||||
|
private val folderProvider: FolderProvider,
|
||||||
|
private val preferenceStore: PreferenceStore,
|
||||||
|
) {
|
||||||
|
fun baseStorageDirectory() = preferenceStore.getString(Preference.appStateKey("storage_dir"), folderProvider.path())
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package eu.kanade.tachiyomi.core.storage
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Environment
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class AndroidStorageFolderProvider(
|
||||||
|
private val context: Context,
|
||||||
|
) : FolderProvider {
|
||||||
|
|
||||||
|
override fun directory(): File {
|
||||||
|
return File(
|
||||||
|
Environment.getExternalStorageDirectory().absolutePath + File.separator +
|
||||||
|
context.getString(R.string.app_normalized_name),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun path(): String {
|
||||||
|
return directory().toUri().toString()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package eu.kanade.tachiyomi.core.storage
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
interface FolderProvider {
|
||||||
|
|
||||||
|
fun directory(): File
|
||||||
|
|
||||||
|
fun path(): String
|
||||||
|
}
|
|
@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.di
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import dev.yokai.domain.extension.TrustExtension
|
import dev.yokai.domain.extension.TrustExtension
|
||||||
|
import dev.yokai.domain.storage.StorageManager
|
||||||
|
import eu.kanade.tachiyomi.core.storage.AndroidStorageFolderProvider
|
||||||
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
|
@ -59,6 +61,9 @@ class AppModule(val app: Application) : InjektModule {
|
||||||
|
|
||||||
addSingletonFactory { TrustExtension() }
|
addSingletonFactory { TrustExtension() }
|
||||||
|
|
||||||
|
addSingletonFactory { AndroidStorageFolderProvider(app) }
|
||||||
|
addSingletonFactory { StorageManager(app, get()) }
|
||||||
|
|
||||||
// Asynchronously init expensive components for a faster cold start
|
// Asynchronously init expensive components for a faster cold start
|
||||||
|
|
||||||
ContextCompat.getMainExecutor(app).execute {
|
ContextCompat.getMainExecutor(app).execute {
|
||||||
|
|
|
@ -4,10 +4,12 @@ import android.app.Application
|
||||||
import dev.yokai.domain.base.BasePreferences
|
import dev.yokai.domain.base.BasePreferences
|
||||||
import dev.yokai.domain.recents.RecentsPreferences
|
import dev.yokai.domain.recents.RecentsPreferences
|
||||||
import dev.yokai.domain.source.SourcePreferences
|
import dev.yokai.domain.source.SourcePreferences
|
||||||
|
import dev.yokai.domain.storage.StoragePreferences
|
||||||
import dev.yokai.domain.ui.UiPreferences
|
import dev.yokai.domain.ui.UiPreferences
|
||||||
import dev.yokai.domain.ui.settings.ReaderPreferences
|
import dev.yokai.domain.ui.settings.ReaderPreferences
|
||||||
import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore
|
import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore
|
||||||
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
import eu.kanade.tachiyomi.core.preference.PreferenceStore
|
||||||
|
import eu.kanade.tachiyomi.core.storage.AndroidStorageFolderProvider
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.track.TrackPreferences
|
import eu.kanade.tachiyomi.data.track.TrackPreferences
|
||||||
import uy.kohesive.injekt.api.InjektModule
|
import uy.kohesive.injekt.api.InjektModule
|
||||||
|
@ -37,5 +39,12 @@ class PreferenceModule(val application: Application) : InjektModule {
|
||||||
preferenceStore = get(),
|
preferenceStore = get(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addSingletonFactory {
|
||||||
|
StoragePreferences(
|
||||||
|
folderProvider = get<AndroidStorageFolderProvider>(),
|
||||||
|
preferenceStore = get(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue