chore: Preparing for Unified Storage

This commit is contained in:
Ahmad Ansori Palembani 2024-05-26 08:22:32 +07:00
parent 6c777d5b71
commit db996acfb6
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
6 changed files with 132 additions and 0 deletions

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

View file

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

View file

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

View file

@ -0,0 +1,10 @@
package eu.kanade.tachiyomi.core.storage
import java.io.File
interface FolderProvider {
fun directory(): File
fun path(): String
}

View file

@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.di
import android.app.Application
import androidx.core.content.ContextCompat
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.CoverCache
import eu.kanade.tachiyomi.data.database.DatabaseHelper
@ -59,6 +61,9 @@ class AppModule(val app: Application) : InjektModule {
addSingletonFactory { TrustExtension() }
addSingletonFactory { AndroidStorageFolderProvider(app) }
addSingletonFactory { StorageManager(app, get()) }
// Asynchronously init expensive components for a faster cold start
ContextCompat.getMainExecutor(app).execute {

View file

@ -4,10 +4,12 @@ import android.app.Application
import dev.yokai.domain.base.BasePreferences
import dev.yokai.domain.recents.RecentsPreferences
import dev.yokai.domain.source.SourcePreferences
import dev.yokai.domain.storage.StoragePreferences
import dev.yokai.domain.ui.UiPreferences
import dev.yokai.domain.ui.settings.ReaderPreferences
import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore
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.track.TrackPreferences
import uy.kohesive.injekt.api.InjektModule
@ -37,5 +39,12 @@ class PreferenceModule(val application: Application) : InjektModule {
preferenceStore = get(),
)
}
addSingletonFactory {
StoragePreferences(
folderProvider = get<AndroidStorageFolderProvider>(),
preferenceStore = get(),
)
}
}
}