core settings added

This commit is contained in:
T8RIN
2024-01-21 03:34:06 +03:00
parent 0377ec86b2
commit 042a9ebcf5
28 changed files with 148 additions and 164 deletions

View File

@ -168,7 +168,6 @@ android {
} }
dependencies { dependencies {
coreLibraryDesugaring(libs.desugaring) coreLibraryDesugaring(libs.desugaring)
//Di //Di
@ -185,12 +184,12 @@ dependencies {
implementation(projects.core.ui) implementation(projects.core.ui)
implementation(projects.core.data) implementation(projects.core.data)
implementation(projects.core.resources) implementation(projects.core.resources)
implementation(projects.core.settings)
implementation(projects.feature.main) implementation(projects.feature.main)
"marketImplementation"(libs.firebase.crashlytics.ktx) "marketImplementation"(libs.firebase.crashlytics.ktx)
"marketImplementation"(libs.firebase.analytics.ktx) "marketImplementation"(libs.firebase.analytics.ktx)
} }

View File

@ -26,8 +26,8 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import ru.tech.imageresizershrinker.core.domain.model.SettingsState import ru.tech.imageresizershrinker.core.domain.model.SettingsState
import ru.tech.imageresizershrinker.core.domain.use_case.get_settings_state.GetSettingsStateFlowUseCase import ru.tech.imageresizershrinker.core.settings.domain.use_case.GetSettingsStateFlowUseCase
import ru.tech.imageresizershrinker.core.domain.use_case.get_settings_state.GetSettingsStateUseCase import ru.tech.imageresizershrinker.core.settings.domain.use_case.GetSettingsStateUseCase
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel @HiltViewModel

View File

@ -32,6 +32,7 @@ class ImageToolboxLibraryFeaturePlugin : Plugin<Project> {
"implementation"(project(":core:ui")) "implementation"(project(":core:ui"))
"implementation"(project(":core:domain")) "implementation"(project(":core:domain"))
"implementation"(project(":core:resources")) "implementation"(project(":core:resources"))
"implementation"(project(":core:settings"))
} }
} }
} }

View File

@ -45,4 +45,6 @@ dependencies {
implementation(projects.core.resources) implementation(projects.core.resources)
implementation(projects.core.filters) implementation(projects.core.filters)
implementation(projects.core.settings)
} }

View File

@ -38,7 +38,6 @@ import ru.tech.imageresizershrinker.core.domain.image.ImagePreviewCreator
import ru.tech.imageresizershrinker.core.domain.image.ImageScaler import ru.tech.imageresizershrinker.core.domain.image.ImageScaler
import ru.tech.imageresizershrinker.core.domain.image.ImageTransformer import ru.tech.imageresizershrinker.core.domain.image.ImageTransformer
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository
import ru.tech.imageresizershrinker.core.domain.saving.FileController import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.filters.domain.FilterProvider import ru.tech.imageresizershrinker.core.filters.domain.FilterProvider
import javax.inject.Singleton import javax.inject.Singleton
@ -60,7 +59,7 @@ object ImageModule {
@Singleton @Singleton
@Provides @Provides
fun provideImageScaler( fun provideImageScaler(
settingsRepository: SettingsRepository, settingsRepository: ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository,
imageCompressor: ImageCompressor<Bitmap>, imageCompressor: ImageCompressor<Bitmap>,
imageTransformer: ImageTransformer<Bitmap>, imageTransformer: ImageTransformer<Bitmap>,
filterProvider: FilterProvider<Bitmap> filterProvider: FilterProvider<Bitmap>
@ -76,7 +75,7 @@ object ImageModule {
fun provideImageCompressor( fun provideImageCompressor(
@ApplicationContext context: Context, @ApplicationContext context: Context,
imageTransformer: ImageTransformer<Bitmap>, imageTransformer: ImageTransformer<Bitmap>,
settingsRepository: SettingsRepository, settingsRepository: ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository,
filterProvider: FilterProvider<Bitmap> filterProvider: FilterProvider<Bitmap>
): ImageCompressor<Bitmap> = AndroidImageCompressor( ): ImageCompressor<Bitmap> = AndroidImageCompressor(
context = context, context = context,

View File

@ -18,8 +18,6 @@
package ru.tech.imageresizershrinker.core.data.di package ru.tech.imageresizershrinker.core.data.di
import android.content.Context import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
@ -28,6 +26,7 @@ import dagger.hilt.components.SingletonComponent
import ru.tech.imageresizershrinker.core.data.saving.FileControllerImpl import ru.tech.imageresizershrinker.core.data.saving.FileControllerImpl
import ru.tech.imageresizershrinker.core.domain.saving.FileController import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.RandomStringGenerator import ru.tech.imageresizershrinker.core.domain.saving.RandomStringGenerator
import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import javax.inject.Singleton import javax.inject.Singleton
@Module @Module
@ -38,11 +37,11 @@ object SavingModule {
@Provides @Provides
fun provideFileController( fun provideFileController(
@ApplicationContext context: Context, @ApplicationContext context: Context,
dataStore: DataStore<Preferences>, settingsRepository: SettingsRepository,
randomStringGenerator: RandomStringGenerator randomStringGenerator: RandomStringGenerator
): FileController = FileControllerImpl( ): FileController = FileControllerImpl(
context = context, context = context,
dataStore = dataStore, settingsRepository = settingsRepository,
randomStringGenerator = randomStringGenerator randomStringGenerator = randomStringGenerator
) )

View File

@ -34,8 +34,8 @@ import ru.tech.imageresizershrinker.core.domain.image.ImageScaler
import ru.tech.imageresizershrinker.core.domain.image.ImageTransformer import ru.tech.imageresizershrinker.core.domain.image.ImageTransformer
import ru.tech.imageresizershrinker.core.domain.model.ImageFormat import ru.tech.imageresizershrinker.core.domain.model.ImageFormat
import ru.tech.imageresizershrinker.core.domain.model.ImageInfo import ru.tech.imageresizershrinker.core.domain.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository
import ru.tech.imageresizershrinker.core.filters.domain.FilterProvider import ru.tech.imageresizershrinker.core.filters.domain.FilterProvider
import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import javax.inject.Inject import javax.inject.Inject

View File

@ -36,9 +36,9 @@ import ru.tech.imageresizershrinker.core.domain.model.ImageFormat
import ru.tech.imageresizershrinker.core.domain.model.ImageInfo import ru.tech.imageresizershrinker.core.domain.model.ImageInfo
import ru.tech.imageresizershrinker.core.domain.model.ImageScaleMode import ru.tech.imageresizershrinker.core.domain.model.ImageScaleMode
import ru.tech.imageresizershrinker.core.domain.model.ResizeType import ru.tech.imageresizershrinker.core.domain.model.ResizeType
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository
import ru.tech.imageresizershrinker.core.filters.domain.FilterProvider import ru.tech.imageresizershrinker.core.filters.domain.FilterProvider
import ru.tech.imageresizershrinker.core.filters.domain.model.Filter import ru.tech.imageresizershrinker.core.filters.domain.model.Filter
import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import javax.inject.Inject import javax.inject.Inject

View File

@ -32,9 +32,6 @@ import android.provider.OpenableColumns
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.exifinterface.media.ExifInterface import androidx.exifinterface.media.ExifInterface
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -42,26 +39,17 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import okio.use import okio.use
import ru.tech.imageresizershrinker.core.data.keys.Keys.ADD_ORIGINAL_NAME_TO_FILENAME
import ru.tech.imageresizershrinker.core.data.keys.Keys.ADD_SEQ_NUM_TO_FILENAME
import ru.tech.imageresizershrinker.core.data.keys.Keys.ADD_SIZE_TO_FILENAME
import ru.tech.imageresizershrinker.core.data.keys.Keys.COPY_TO_CLIPBOARD_MODE
import ru.tech.imageresizershrinker.core.data.keys.Keys.FILENAME_PREFIX
import ru.tech.imageresizershrinker.core.data.keys.Keys.FILENAME_SUFFIX
import ru.tech.imageresizershrinker.core.data.keys.Keys.IMAGE_PICKER_MODE
import ru.tech.imageresizershrinker.core.data.keys.Keys.OVERWRITE_FILE
import ru.tech.imageresizershrinker.core.data.keys.Keys.RANDOMIZE_FILENAME
import ru.tech.imageresizershrinker.core.data.keys.Keys.SAVE_FOLDER_URI
import ru.tech.imageresizershrinker.core.domain.image.Metadata import ru.tech.imageresizershrinker.core.domain.image.Metadata
import ru.tech.imageresizershrinker.core.domain.model.CopyToClipboardMode import ru.tech.imageresizershrinker.core.domain.model.CopyToClipboardMode
import ru.tech.imageresizershrinker.core.domain.model.SettingsState
import ru.tech.imageresizershrinker.core.domain.saving.FileController import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.saving.RandomStringGenerator import ru.tech.imageresizershrinker.core.domain.saving.RandomStringGenerator
import ru.tech.imageresizershrinker.core.domain.saving.SaveResult import ru.tech.imageresizershrinker.core.domain.saving.SaveResult
import ru.tech.imageresizershrinker.core.domain.saving.SaveTarget import ru.tech.imageresizershrinker.core.domain.saving.SaveTarget
import ru.tech.imageresizershrinker.core.domain.saving.model.FileParams
import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget import ru.tech.imageresizershrinker.core.domain.saving.model.ImageSaveTarget
import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount import ru.tech.imageresizershrinker.core.domain.utils.readableByteCount
import ru.tech.imageresizershrinker.core.resources.R import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.OutputStream import java.io.OutputStream
@ -74,40 +62,18 @@ import kotlin.random.Random
class FileControllerImpl @Inject constructor( class FileControllerImpl @Inject constructor(
private val context: Context, private val context: Context,
private val dataStore: DataStore<Preferences>, private val settingsRepository: SettingsRepository,
private val randomStringGenerator: RandomStringGenerator private val randomStringGenerator: RandomStringGenerator
) : FileController { ) : FileController {
private var _fileParams: FileParams = FileParams( private var _settingsState: SettingsState = SettingsState.Default
treeUri = null,
filenamePrefix = "",
filenameSuffix = "",
addSizeInFilename = false,
addOriginalFilename = false,
addSequenceNumber = false,
randomizeFilename = false,
copyToClipboardMode = CopyToClipboardMode.Disabled,
overwriteFile = false
)
private val fileParams get() = _fileParams private val settingsState get() = _settingsState
init { init {
CoroutineScope(Dispatchers.IO).launch { CoroutineScope(Dispatchers.IO).launch {
dataStore.data.collect { preferences -> settingsRepository.getSettingsStateFlow().collect { state ->
_fileParams = _fileParams.copy( _settingsState = state
treeUri = preferences[SAVE_FOLDER_URI]?.takeIf { it.isNotEmpty() },
filenamePrefix = preferences[FILENAME_PREFIX] ?: "ResizedImage",
filenameSuffix = preferences[FILENAME_SUFFIX] ?: "",
addSizeInFilename = preferences[ADD_SIZE_TO_FILENAME] ?: false,
addOriginalFilename = preferences[ADD_ORIGINAL_NAME_TO_FILENAME] ?: false,
addSequenceNumber = preferences[ADD_SEQ_NUM_TO_FILENAME] ?: true,
randomizeFilename = preferences[RANDOMIZE_FILENAME] ?: false,
copyToClipboardMode = preferences[COPY_TO_CLIPBOARD_MODE]?.let {
CopyToClipboardMode.fromInt(it)
} ?: CopyToClipboardMode.Disabled,
overwriteFile = preferences[OVERWRITE_FILE] ?: false
)
} }
} }
} }
@ -137,7 +103,7 @@ class FileControllerImpl @Inject constructor(
} }
override val savingPath: String override val savingPath: String
get() = fileParams.treeUri?.takeIf { it.isNotEmpty() }?.toUri().toUiPath( get() = settingsState.saveFolderUri?.takeIf { it.isNotEmpty() }?.toUri().toUiPath(
context = context, context = context,
default = context.getString(R.string.default_folder) default = context.getString(R.string.default_folder)
) )
@ -175,7 +141,7 @@ class FileControllerImpl @Inject constructor(
} }
kotlin.runCatching { kotlin.runCatching {
if (fileParams.copyToClipboardMode is CopyToClipboardMode.Enabled) { if (settingsState.copyToClipboardMode is CopyToClipboardMode.Enabled) {
val clipboardManager = ContextCompat.getSystemService( val clipboardManager = ContextCompat.getSystemService(
context, context,
ClipboardManager::class.java ClipboardManager::class.java
@ -192,7 +158,7 @@ class FileControllerImpl @Inject constructor(
} }
} }
if (fileParams.copyToClipboardMode is CopyToClipboardMode.Enabled.WithoutSaving) { if (settingsState.copyToClipboardMode is CopyToClipboardMode.Enabled.WithoutSaving) {
return SaveResult.Success(context.getString(R.string.copied)) return SaveResult.Success(context.getString(R.string.copied))
} }
@ -201,15 +167,13 @@ class FileControllerImpl @Inject constructor(
context.contentResolver.openFileDescriptor(originalUri, "r") context.contentResolver.openFileDescriptor(originalUri, "r")
}.isSuccess }.isSuccess
if (fileParams.overwriteFile && hasOriginalUri) { if (settingsState.overwriteFiles && hasOriginalUri) {
runCatching { runCatching {
if (originalUri == Uri.EMPTY) throw IllegalStateException() if (originalUri == Uri.EMPTY) throw IllegalStateException()
context.contentResolver.openFileDescriptor(originalUri, "wt") context.contentResolver.openFileDescriptor(originalUri, "wt")
}.onFailure { }.onFailure {
dataStore.edit { settingsRepository.setImagePickerMode(2)
it[IMAGE_PICKER_MODE] = 2
}
return SaveResult.Error.Exception( return SaveResult.Error.Exception(
Exception( Exception(
context.getString( context.getString(
@ -238,7 +202,7 @@ class FileControllerImpl @Inject constructor(
) )
} }
} else { } else {
fileParams.treeUri.takeIf { settingsState.saveFolderUri.takeIf {
it != null it != null
}?.let { treeUri -> }?.let { treeUri ->
val hasDir: Boolean = treeUri.toUri().let { val hasDir: Boolean = treeUri.toUri().let {
@ -246,9 +210,7 @@ class FileControllerImpl @Inject constructor(
}?.exists() == true }?.exists() == true
if (!hasDir) { if (!hasDir) {
dataStore.edit { settingsRepository.setSaveFolderUri(null)
it[SAVE_FOLDER_URI] = ""
}
return SaveResult.Error.Exception( return SaveResult.Error.Exception(
Exception( Exception(
context.getString( context.getString(
@ -274,7 +236,7 @@ class FileControllerImpl @Inject constructor(
} else saveTarget } else saveTarget
val savingFolder = context.getSavingFolder( val savingFolder = context.getSavingFolder(
treeUri = fileParams.treeUri?.takeIf { it.isNotEmpty() }?.toUri(), treeUri = settingsState.saveFolderUri?.takeIf { it.isNotEmpty() }?.toUri(),
saveTarget = newSaveTarget saveTarget = newSaveTarget
) )
@ -383,7 +345,7 @@ class FileControllerImpl @Inject constructor(
): String { ): String {
val extension = saveTarget.imageInfo.imageFormat.extension val extension = saveTarget.imageInfo.imageFormat.extension
if (fileParams.randomizeFilename) return "${randomStringGenerator.generate(32)}.$extension" if (settingsState.randomizeFilename) return "${randomStringGenerator.generate(32)}.$extension"
val wh = val wh =
"(" + (if (saveTarget.originalUri.toUri() == Uri.EMPTY) context.getString(R.string.width) "(" + (if (saveTarget.originalUri.toUri() == Uri.EMPTY) context.getString(R.string.width)
@ -391,20 +353,20 @@ class FileControllerImpl @Inject constructor(
R.string.height R.string.height
).split(" ")[0] else saveTarget.imageInfo.height) + ")" ).split(" ")[0] else saveTarget.imageInfo.height) + ")"
var prefix = fileParams.filenamePrefix var prefix = settingsState.filenamePrefix
var suffix = fileParams.filenameSuffix var suffix = settingsState.filenameSuffix
if (prefix.isNotEmpty()) prefix = "${prefix}_" if (prefix.isNotEmpty()) prefix = "${prefix}_"
if (suffix.isNotEmpty()) suffix = "_$suffix" if (suffix.isNotEmpty()) suffix = "_$suffix"
if (fileParams.addOriginalFilename) { if (settingsState.addOriginalFilename) {
prefix += if (saveTarget.originalUri.toUri() != Uri.EMPTY) { prefix += if (saveTarget.originalUri.toUri() != Uri.EMPTY) {
context.getFileName(saveTarget.originalUri.toUri()) ?: "" context.getFileName(saveTarget.originalUri.toUri()) ?: ""
} else { } else {
context.getString(R.string.original_filename) context.getString(R.string.original_filename)
} }
} }
if (fileParams.addSizeInFilename) prefix += wh if (settingsState.addSizeInFilename) prefix += wh
val timeStamp = SimpleDateFormat( val timeStamp = SimpleDateFormat(
"yyyy-MM-dd_HH-mm-ss", "yyyy-MM-dd_HH-mm-ss",
@ -412,7 +374,7 @@ class FileControllerImpl @Inject constructor(
).format(Date()) + "_${Random(Random.nextInt()).hashCode().toString().take(4)}" ).format(Date()) + "_${Random(Random.nextInt()).hashCode().toString().take(4)}"
return "$prefix${ return "$prefix${
if (fileParams.addSequenceNumber && saveTarget.sequenceNumber != null) { if (settingsState.addSequenceNumber && saveTarget.sequenceNumber != null) {
SimpleDateFormat( SimpleDateFormat(
"yyyy-MM-dd_HH-mm-ss", "yyyy-MM-dd_HH-mm-ss",
Locale.getDefault() Locale.getDefault()

1
core/settings/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -15,18 +15,16 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.domain.saving.model plugins {
alias(libs.plugins.image.toolbox.library)
alias(libs.plugins.image.toolbox.hilt)
}
import ru.tech.imageresizershrinker.core.domain.model.CopyToClipboardMode android.namespace = "ru.tech.imageresizershrinker.core.settings"
data class FileParams( dependencies {
val treeUri: String?, api(libs.datastore.preferences.android)
val filenamePrefix: String,
val filenameSuffix: String, implementation(projects.core.domain)
val addSizeInFilename: Boolean, implementation(projects.core.resources)
val addOriginalFilename: Boolean, }
val addSequenceNumber: Boolean,
val randomizeFilename: Boolean,
val copyToClipboardMode: CopyToClipboardMode,
val overwriteFile: Boolean
)

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ ImageToolbox is an image editor for android
~ Copyright (c) 2024 T8RIN (Malik Mukhametzyanov)
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~
~ You should have received a copy of the Apache License
~ along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
-->
<manifest>
</manifest>

View File

@ -15,14 +15,13 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.data.migrations package ru.tech.imageresizershrinker.core.settings.data
import androidx.datastore.core.DataMigration import androidx.datastore.core.DataMigration
import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.booleanPreferencesKey
import ru.tech.imageresizershrinker.core.data.keys.Keys
class BorderWidthMigration : DataMigration<Preferences> { internal class BorderWidthMigration : DataMigration<Preferences> {
private val migrated = booleanPreferencesKey("migratedBorders") private val migrated = booleanPreferencesKey("migratedBorders")
override suspend fun cleanUp() = Unit override suspend fun cleanUp() = Unit

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.data.keys package ru.tech.imageresizershrinker.core.settings.data
import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.doublePreferencesKey import androidx.datastore.preferences.core.doublePreferencesKey
@ -23,7 +23,7 @@ import androidx.datastore.preferences.core.floatPreferencesKey
import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey
object Keys { internal object Keys {
val SAVE_FOLDER_URI = stringPreferencesKey("saveFolder") val SAVE_FOLDER_URI = stringPreferencesKey("saveFolder")
val NIGHT_MODE = intPreferencesKey("nightMode") val NIGHT_MODE = intPreferencesKey("nightMode")
val DYNAMIC_COLORS = booleanPreferencesKey("dynamicColors") val DYNAMIC_COLORS = booleanPreferencesKey("dynamicColors")

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.data.repository package ru.tech.imageresizershrinker.core.settings.data
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.content.Context
@ -30,62 +30,62 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import ru.tech.imageresizershrinker.core.data.keys.Keys.ADD_ORIGINAL_NAME_TO_FILENAME
import ru.tech.imageresizershrinker.core.data.keys.Keys.ADD_SEQ_NUM_TO_FILENAME
import ru.tech.imageresizershrinker.core.data.keys.Keys.ADD_SIZE_TO_FILENAME
import ru.tech.imageresizershrinker.core.data.keys.Keys.ALLOW_ANALYTICS
import ru.tech.imageresizershrinker.core.data.keys.Keys.ALLOW_BETAS
import ru.tech.imageresizershrinker.core.data.keys.Keys.ALLOW_CRASHLYTICS
import ru.tech.imageresizershrinker.core.data.keys.Keys.ALLOW_IMAGE_MONET
import ru.tech.imageresizershrinker.core.data.keys.Keys.AMOLED_MODE
import ru.tech.imageresizershrinker.core.data.keys.Keys.APP_COLOR_TUPLE
import ru.tech.imageresizershrinker.core.data.keys.Keys.APP_OPEN_COUNT
import ru.tech.imageresizershrinker.core.data.keys.Keys.AUTO_CACHE_CLEAR
import ru.tech.imageresizershrinker.core.data.keys.Keys.BORDER_WIDTH
import ru.tech.imageresizershrinker.core.data.keys.Keys.COLOR_TUPLES
import ru.tech.imageresizershrinker.core.data.keys.Keys.COPY_TO_CLIPBOARD_MODE
import ru.tech.imageresizershrinker.core.data.keys.Keys.DRAW_APPBAR_SHADOWS
import ru.tech.imageresizershrinker.core.data.keys.Keys.DRAW_BUTTON_SHADOWS
import ru.tech.imageresizershrinker.core.data.keys.Keys.DRAW_CONTAINER_SHADOWS
import ru.tech.imageresizershrinker.core.data.keys.Keys.DRAW_FAB_SHADOWS
import ru.tech.imageresizershrinker.core.data.keys.Keys.DRAW_SLIDER_SHADOWS
import ru.tech.imageresizershrinker.core.data.keys.Keys.DRAW_SWITCH_SHADOWS
import ru.tech.imageresizershrinker.core.data.keys.Keys.DYNAMIC_COLORS
import ru.tech.imageresizershrinker.core.data.keys.Keys.EMOJI_COUNT
import ru.tech.imageresizershrinker.core.data.keys.Keys.EXIF_WIDGET_INITIAL_STATE
import ru.tech.imageresizershrinker.core.data.keys.Keys.FAB_ALIGNMENT
import ru.tech.imageresizershrinker.core.data.keys.Keys.FILENAME_PREFIX
import ru.tech.imageresizershrinker.core.data.keys.Keys.FILENAME_SUFFIX
import ru.tech.imageresizershrinker.core.data.keys.Keys.FONT_SCALE
import ru.tech.imageresizershrinker.core.data.keys.Keys.GROUP_OPTIONS_BY_TYPE
import ru.tech.imageresizershrinker.core.data.keys.Keys.IMAGE_PICKER_MODE
import ru.tech.imageresizershrinker.core.data.keys.Keys.IMAGE_SCALE_MODE
import ru.tech.imageresizershrinker.core.data.keys.Keys.INITIAL_OCR_CODES
import ru.tech.imageresizershrinker.core.data.keys.Keys.INVERT_THEME
import ru.tech.imageresizershrinker.core.data.keys.Keys.LOCK_DRAW_ORIENTATION
import ru.tech.imageresizershrinker.core.data.keys.Keys.MAGNIFIER_ENABLED
import ru.tech.imageresizershrinker.core.data.keys.Keys.NIGHT_MODE
import ru.tech.imageresizershrinker.core.data.keys.Keys.OVERWRITE_FILE
import ru.tech.imageresizershrinker.core.data.keys.Keys.PRESETS
import ru.tech.imageresizershrinker.core.data.keys.Keys.RANDOMIZE_FILENAME
import ru.tech.imageresizershrinker.core.data.keys.Keys.SAVE_FOLDER_URI
import ru.tech.imageresizershrinker.core.data.keys.Keys.SCREEN_ORDER
import ru.tech.imageresizershrinker.core.data.keys.Keys.SCREEN_SEARCH_ENABLED
import ru.tech.imageresizershrinker.core.data.keys.Keys.SELECTED_EMOJI_INDEX
import ru.tech.imageresizershrinker.core.data.keys.Keys.SELECTED_FONT_INDEX
import ru.tech.imageresizershrinker.core.data.keys.Keys.SHOW_UPDATE_DIALOG
import ru.tech.imageresizershrinker.core.data.keys.Keys.THEME_CONTRAST_LEVEL
import ru.tech.imageresizershrinker.core.data.keys.Keys.THEME_STYLE
import ru.tech.imageresizershrinker.core.data.keys.Keys.USE_PIXEL_SWITCH
import ru.tech.imageresizershrinker.core.data.keys.Keys.VIBRATION_STRENGTH
import ru.tech.imageresizershrinker.core.domain.model.CopyToClipboardMode import ru.tech.imageresizershrinker.core.domain.model.CopyToClipboardMode
import ru.tech.imageresizershrinker.core.domain.model.FontFam import ru.tech.imageresizershrinker.core.domain.model.FontFam
import ru.tech.imageresizershrinker.core.domain.model.ImageScaleMode import ru.tech.imageresizershrinker.core.domain.model.ImageScaleMode
import ru.tech.imageresizershrinker.core.domain.model.NightMode import ru.tech.imageresizershrinker.core.domain.model.NightMode
import ru.tech.imageresizershrinker.core.domain.model.Preset import ru.tech.imageresizershrinker.core.domain.model.Preset
import ru.tech.imageresizershrinker.core.domain.model.SettingsState import ru.tech.imageresizershrinker.core.domain.model.SettingsState
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository
import ru.tech.imageresizershrinker.core.resources.R import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.settings.data.Keys.ADD_ORIGINAL_NAME_TO_FILENAME
import ru.tech.imageresizershrinker.core.settings.data.Keys.ADD_SEQ_NUM_TO_FILENAME
import ru.tech.imageresizershrinker.core.settings.data.Keys.ADD_SIZE_TO_FILENAME
import ru.tech.imageresizershrinker.core.settings.data.Keys.ALLOW_ANALYTICS
import ru.tech.imageresizershrinker.core.settings.data.Keys.ALLOW_BETAS
import ru.tech.imageresizershrinker.core.settings.data.Keys.ALLOW_CRASHLYTICS
import ru.tech.imageresizershrinker.core.settings.data.Keys.ALLOW_IMAGE_MONET
import ru.tech.imageresizershrinker.core.settings.data.Keys.AMOLED_MODE
import ru.tech.imageresizershrinker.core.settings.data.Keys.APP_COLOR_TUPLE
import ru.tech.imageresizershrinker.core.settings.data.Keys.APP_OPEN_COUNT
import ru.tech.imageresizershrinker.core.settings.data.Keys.AUTO_CACHE_CLEAR
import ru.tech.imageresizershrinker.core.settings.data.Keys.BORDER_WIDTH
import ru.tech.imageresizershrinker.core.settings.data.Keys.COLOR_TUPLES
import ru.tech.imageresizershrinker.core.settings.data.Keys.COPY_TO_CLIPBOARD_MODE
import ru.tech.imageresizershrinker.core.settings.data.Keys.DRAW_APPBAR_SHADOWS
import ru.tech.imageresizershrinker.core.settings.data.Keys.DRAW_BUTTON_SHADOWS
import ru.tech.imageresizershrinker.core.settings.data.Keys.DRAW_CONTAINER_SHADOWS
import ru.tech.imageresizershrinker.core.settings.data.Keys.DRAW_FAB_SHADOWS
import ru.tech.imageresizershrinker.core.settings.data.Keys.DRAW_SLIDER_SHADOWS
import ru.tech.imageresizershrinker.core.settings.data.Keys.DRAW_SWITCH_SHADOWS
import ru.tech.imageresizershrinker.core.settings.data.Keys.DYNAMIC_COLORS
import ru.tech.imageresizershrinker.core.settings.data.Keys.EMOJI_COUNT
import ru.tech.imageresizershrinker.core.settings.data.Keys.EXIF_WIDGET_INITIAL_STATE
import ru.tech.imageresizershrinker.core.settings.data.Keys.FAB_ALIGNMENT
import ru.tech.imageresizershrinker.core.settings.data.Keys.FILENAME_PREFIX
import ru.tech.imageresizershrinker.core.settings.data.Keys.FILENAME_SUFFIX
import ru.tech.imageresizershrinker.core.settings.data.Keys.FONT_SCALE
import ru.tech.imageresizershrinker.core.settings.data.Keys.GROUP_OPTIONS_BY_TYPE
import ru.tech.imageresizershrinker.core.settings.data.Keys.IMAGE_PICKER_MODE
import ru.tech.imageresizershrinker.core.settings.data.Keys.IMAGE_SCALE_MODE
import ru.tech.imageresizershrinker.core.settings.data.Keys.INITIAL_OCR_CODES
import ru.tech.imageresizershrinker.core.settings.data.Keys.INVERT_THEME
import ru.tech.imageresizershrinker.core.settings.data.Keys.LOCK_DRAW_ORIENTATION
import ru.tech.imageresizershrinker.core.settings.data.Keys.MAGNIFIER_ENABLED
import ru.tech.imageresizershrinker.core.settings.data.Keys.NIGHT_MODE
import ru.tech.imageresizershrinker.core.settings.data.Keys.OVERWRITE_FILE
import ru.tech.imageresizershrinker.core.settings.data.Keys.PRESETS
import ru.tech.imageresizershrinker.core.settings.data.Keys.RANDOMIZE_FILENAME
import ru.tech.imageresizershrinker.core.settings.data.Keys.SAVE_FOLDER_URI
import ru.tech.imageresizershrinker.core.settings.data.Keys.SCREEN_ORDER
import ru.tech.imageresizershrinker.core.settings.data.Keys.SCREEN_SEARCH_ENABLED
import ru.tech.imageresizershrinker.core.settings.data.Keys.SELECTED_EMOJI_INDEX
import ru.tech.imageresizershrinker.core.settings.data.Keys.SELECTED_FONT_INDEX
import ru.tech.imageresizershrinker.core.settings.data.Keys.SHOW_UPDATE_DIALOG
import ru.tech.imageresizershrinker.core.settings.data.Keys.THEME_CONTRAST_LEVEL
import ru.tech.imageresizershrinker.core.settings.data.Keys.THEME_STYLE
import ru.tech.imageresizershrinker.core.settings.data.Keys.USE_PIXEL_SWITCH
import ru.tech.imageresizershrinker.core.settings.data.Keys.VIBRATION_STRENGTH
import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.DataInputStream import java.io.DataInputStream

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.data.di package ru.tech.imageresizershrinker.core.settings.di
import android.content.Context import android.content.Context
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore
@ -27,7 +27,7 @@ import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import ru.tech.imageresizershrinker.core.data.migrations.BorderWidthMigration import ru.tech.imageresizershrinker.core.settings.data.BorderWidthMigration
import javax.inject.Singleton import javax.inject.Singleton
@Module @Module

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.data.di package ru.tech.imageresizershrinker.core.settings.di
import android.content.Context import android.content.Context
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore
@ -25,13 +25,14 @@ import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import ru.tech.imageresizershrinker.core.data.repository.SettingsRepositoryImpl import ru.tech.imageresizershrinker.core.settings.data.SettingsRepositoryImpl
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import javax.inject.Singleton import javax.inject.Singleton
@Module @Module
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
object RepositoryModule { object SettingsModule {
@Singleton @Singleton
@Provides @Provides

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.domain.repository package ru.tech.imageresizershrinker.core.settings.domain
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import ru.tech.imageresizershrinker.core.domain.model.CopyToClipboardMode import ru.tech.imageresizershrinker.core.domain.model.CopyToClipboardMode

View File

@ -15,9 +15,9 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.domain.use_case.backup_and_restore package ru.tech.imageresizershrinker.core.settings.domain.use_case
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import javax.inject.Inject import javax.inject.Inject
class CreateBackupFileUseCase @Inject constructor( class CreateBackupFileUseCase @Inject constructor(

View File

@ -15,9 +15,9 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.domain.use_case.backup_and_restore package ru.tech.imageresizershrinker.core.settings.domain.use_case
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import javax.inject.Inject import javax.inject.Inject
class CreateBackupFilenameUseCase @Inject constructor( class CreateBackupFilenameUseCase @Inject constructor(

View File

@ -15,9 +15,9 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.domain.use_case.get_settings_state package ru.tech.imageresizershrinker.core.settings.domain.use_case
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import javax.inject.Inject import javax.inject.Inject
class GetSettingsStateFlowUseCase @Inject constructor( class GetSettingsStateFlowUseCase @Inject constructor(

View File

@ -15,9 +15,9 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.domain.use_case.get_settings_state package ru.tech.imageresizershrinker.core.settings.domain.use_case
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import javax.inject.Inject import javax.inject.Inject
class GetSettingsStateUseCase @Inject constructor( class GetSettingsStateUseCase @Inject constructor(

View File

@ -15,9 +15,9 @@
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>. * along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
*/ */
package ru.tech.imageresizershrinker.core.domain.use_case.backup_and_restore package ru.tech.imageresizershrinker.core.settings.domain.use_case
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository import ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
import javax.inject.Inject import javax.inject.Inject
class RestoreFromBackupFileUseCase @Inject constructor( class RestoreFromBackupFileUseCase @Inject constructor(

View File

@ -83,4 +83,6 @@ dependencies {
"marketImplementation"(libs.app.update.ktx) "marketImplementation"(libs.app.update.ktx)
api(projects.core.resources) api(projects.core.resources)
implementation(projects.core.settings)
} }

View File

@ -20,7 +20,7 @@ package ru.tech.imageresizershrinker.core.ui.widget.activity
import dagger.hilt.EntryPoint import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import ru.tech.imageresizershrinker.core.domain.use_case.get_settings_state.GetSettingsStateUseCase import ru.tech.imageresizershrinker.core.settings.domain.use_case.GetSettingsStateUseCase
@EntryPoint @EntryPoint
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)

View File

@ -48,11 +48,10 @@ import ru.tech.imageresizershrinker.core.domain.model.FontFam
import ru.tech.imageresizershrinker.core.domain.model.ImageScaleMode import ru.tech.imageresizershrinker.core.domain.model.ImageScaleMode
import ru.tech.imageresizershrinker.core.domain.model.NightMode import ru.tech.imageresizershrinker.core.domain.model.NightMode
import ru.tech.imageresizershrinker.core.domain.model.SettingsState import ru.tech.imageresizershrinker.core.domain.model.SettingsState
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository
import ru.tech.imageresizershrinker.core.domain.saving.FileController import ru.tech.imageresizershrinker.core.domain.saving.FileController
import ru.tech.imageresizershrinker.core.domain.use_case.get_settings_state.GetSettingsStateFlowUseCase
import ru.tech.imageresizershrinker.core.domain.use_case.get_settings_state.GetSettingsStateUseCase
import ru.tech.imageresizershrinker.core.resources.BuildConfig import ru.tech.imageresizershrinker.core.resources.BuildConfig
import ru.tech.imageresizershrinker.core.settings.domain.use_case.GetSettingsStateFlowUseCase
import ru.tech.imageresizershrinker.core.settings.domain.use_case.GetSettingsStateUseCase
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
import ru.tech.imageresizershrinker.core.ui.utils.state.update import ru.tech.imageresizershrinker.core.ui.utils.state.update
import ru.tech.imageresizershrinker.core.ui.widget.other.ToastHostState import ru.tech.imageresizershrinker.core.ui.widget.other.ToastHostState
@ -68,7 +67,7 @@ class MainViewModel @Inject constructor(
private val imageGetter: ImageGetter<Bitmap, ExifInterface>, private val imageGetter: ImageGetter<Bitmap, ExifInterface>,
private val fileController: FileController, private val fileController: FileController,
private val getSettingsStateUseCase: GetSettingsStateUseCase, private val getSettingsStateUseCase: GetSettingsStateUseCase,
private val settingsRepository: SettingsRepository private val settingsRepository: ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
) : ViewModel() { ) : ViewModel() {
private val _settingsState = mutableStateOf(SettingsState.Default) private val _settingsState = mutableStateOf(SettingsState.Default)

View File

@ -31,7 +31,6 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import ru.tech.imageresizershrinker.core.domain.repository.SettingsRepository
import ru.tech.imageresizershrinker.core.ui.utils.state.update import ru.tech.imageresizershrinker.core.ui.utils.state.update
import ru.tech.imageresizershrinker.feature.recognize.text.domain.DownloadData import ru.tech.imageresizershrinker.feature.recognize.text.domain.DownloadData
import ru.tech.imageresizershrinker.feature.recognize.text.domain.ImageTextReader import ru.tech.imageresizershrinker.feature.recognize.text.domain.ImageTextReader
@ -46,7 +45,7 @@ import javax.inject.Inject
@HiltViewModel @HiltViewModel
class RecognizeTextViewModel @Inject constructor( class RecognizeTextViewModel @Inject constructor(
private val imageTextReader: ImageTextReader<Bitmap>, private val imageTextReader: ImageTextReader<Bitmap>,
private val settingsRepository: SettingsRepository private val settingsRepository: ru.tech.imageresizershrinker.core.settings.domain.SettingsRepository
) : ViewModel() { ) : ViewModel() {
private val _segmentationMode: MutableState<SegmentationMode> = private val _segmentationMode: MutableState<SegmentationMode> =

View File

@ -17,6 +17,9 @@
@file:Suppress("UnstableApiUsage") @file:Suppress("UnstableApiUsage")
include(":core:settings")
pluginManagement { pluginManagement {
repositories { repositories {
includeBuild("build-logic") includeBuild("build-logic")