mirror of
https://github.com/T8RIN/ImageToolbox.git
synced 2025-05-20 06:56:22 +08:00
Fix possible OOM's
This commit is contained in:
@ -56,11 +56,9 @@ class CrashComponent @AssistedInject internal constructor(
|
|||||||
|
|
||||||
fun shareLogs() {
|
fun shareLogs() {
|
||||||
componentScope.launch {
|
componentScope.launch {
|
||||||
shareProvider.shareData(
|
shareProvider.shareUri(
|
||||||
writeData = {
|
uri = settingsManager.createLogsExport(),
|
||||||
it.writeBytes(settingsManager.createLogsExport())
|
onComplete = {}
|
||||||
},
|
|
||||||
filename = settingsManager.createLogsFilename()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ internal class AndroidShareProvider @Inject constructor(
|
|||||||
)
|
)
|
||||||
onComplete()
|
onComplete()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
val uri = cacheData(
|
val newUri = cacheData(
|
||||||
writeData = {
|
writeData = {
|
||||||
it.copyFrom(
|
it.copyFrom(
|
||||||
UriReadable(
|
UriReadable(
|
||||||
@ -143,7 +143,7 @@ internal class AndroidShareProvider @Inject constructor(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
shareUriImpl(
|
shareUriImpl(
|
||||||
uri = uri ?: return@onFailure,
|
uri = newUri ?: return@onFailure,
|
||||||
type = type
|
type = type
|
||||||
)
|
)
|
||||||
onComplete()
|
onComplete()
|
||||||
|
@ -221,13 +221,11 @@ interface SettingsInteractor : SimpleSettingsInteractor {
|
|||||||
|
|
||||||
suspend fun removeCustomFont(font: DomainFontFamily.Custom)
|
suspend fun removeCustomFont(font: DomainFontFamily.Custom)
|
||||||
|
|
||||||
suspend fun createCustomFontsExport(): ByteArray
|
suspend fun createCustomFontsExport(): String?
|
||||||
|
|
||||||
suspend fun toggleEnableToolExitConfirmation()
|
suspend fun toggleEnableToolExitConfirmation()
|
||||||
|
|
||||||
suspend fun createLogsExport(): ByteArray
|
suspend fun createLogsExport(): String
|
||||||
|
|
||||||
fun createLogsFilename(): String
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun SettingsInteractor.toSimpleSettingsInteractor(): SimpleSettingsInteractor =
|
fun SettingsInteractor.toSimpleSettingsInteractor(): SimpleSettingsInteractor =
|
||||||
|
@ -34,6 +34,7 @@ import kotlinx.coroutines.isActive
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import oupson.apng.decoder.ApngDecoder
|
import oupson.apng.decoder.ApngDecoder
|
||||||
import oupson.apng.encoder.ApngEncoder
|
import oupson.apng.encoder.ApngEncoder
|
||||||
|
import ru.tech.imageresizershrinker.core.data.utils.outputStream
|
||||||
import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
|
import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
|
||||||
import ru.tech.imageresizershrinker.core.domain.image.ImageGetter
|
import ru.tech.imageresizershrinker.core.domain.image.ImageGetter
|
||||||
import ru.tech.imageresizershrinker.core.domain.image.ImageScaler
|
import ru.tech.imageresizershrinker.core.domain.image.ImageScaler
|
||||||
@ -46,13 +47,12 @@ import ru.tech.imageresizershrinker.core.domain.model.IntegerSize
|
|||||||
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
|
import ru.tech.imageresizershrinker.core.domain.utils.runSuspendCatching
|
||||||
import ru.tech.imageresizershrinker.feature.apng_tools.domain.ApngConverter
|
import ru.tech.imageresizershrinker.feature.apng_tools.domain.ApngConverter
|
||||||
import ru.tech.imageresizershrinker.feature.apng_tools.domain.ApngParams
|
import ru.tech.imageresizershrinker.feature.apng_tools.domain.ApngParams
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
internal class AndroidApngConverter @Inject constructor(
|
internal class AndroidApngConverter @Inject constructor(
|
||||||
private val imageGetter: ImageGetter<Bitmap>,
|
private val imageGetter: ImageGetter<Bitmap>,
|
||||||
private val imageShareProvider: ShareProvider<Bitmap>,
|
private val shareProvider: ShareProvider<Bitmap>,
|
||||||
private val imageScaler: ImageScaler<Bitmap>,
|
private val imageScaler: ImageScaler<Bitmap>,
|
||||||
@ApplicationContext private val context: Context,
|
@ApplicationContext private val context: Context,
|
||||||
dispatchersHolder: DispatchersHolder
|
dispatchersHolder: DispatchersHolder
|
||||||
@ -71,7 +71,7 @@ internal class AndroidApngConverter @Inject constructor(
|
|||||||
currentCoroutineContext().cancel(null)
|
currentCoroutineContext().cancel(null)
|
||||||
return@decodeAsync
|
return@decodeAsync
|
||||||
}
|
}
|
||||||
imageShareProvider.cacheImage(
|
shareProvider.cacheImage(
|
||||||
image = frame,
|
image = frame,
|
||||||
imageInfo = ImageInfo(
|
imageInfo = ImageInfo(
|
||||||
width = frame.width,
|
width = frame.width,
|
||||||
@ -88,8 +88,7 @@ internal class AndroidApngConverter @Inject constructor(
|
|||||||
params: ApngParams,
|
params: ApngParams,
|
||||||
onFailure: (Throwable) -> Unit,
|
onFailure: (Throwable) -> Unit,
|
||||||
onProgress: () -> Unit
|
onProgress: () -> Unit
|
||||||
): ByteArray? = withContext(defaultDispatcher) {
|
): String? = withContext(defaultDispatcher) {
|
||||||
val out = ByteArrayOutputStream()
|
|
||||||
val size = params.size ?: imageGetter.getImage(data = imageUris[0])!!.run {
|
val size = params.size ?: imageGetter.getImage(data = imageUris[0])!!.run {
|
||||||
IntegerSize(width, height)
|
IntegerSize(width, height)
|
||||||
}
|
}
|
||||||
@ -99,8 +98,10 @@ internal class AndroidApngConverter @Inject constructor(
|
|||||||
return@withContext null
|
return@withContext null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shareProvider.cacheData(
|
||||||
|
writeData = { writeable ->
|
||||||
val encoder = ApngEncoder(
|
val encoder = ApngEncoder(
|
||||||
outputStream = out,
|
outputStream = writeable.outputStream(),
|
||||||
width = size.width,
|
width = size.width,
|
||||||
height = size.height,
|
height = size.height,
|
||||||
numberOfFrames = imageUris.size
|
numberOfFrames = imageUris.size
|
||||||
@ -134,8 +135,9 @@ internal class AndroidApngConverter @Inject constructor(
|
|||||||
onProgress()
|
onProgress()
|
||||||
}
|
}
|
||||||
encoder.writeEnd()
|
encoder.writeEnd()
|
||||||
|
},
|
||||||
out.toByteArray()
|
filename = "temp_apng.png"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun convertApngToJxl(
|
override suspend fun convertApngToJxl(
|
||||||
|
@ -34,7 +34,7 @@ interface ApngConverter {
|
|||||||
params: ApngParams,
|
params: ApngParams,
|
||||||
onFailure: (Throwable) -> Unit,
|
onFailure: (Throwable) -> Unit,
|
||||||
onProgress: () -> Unit
|
onProgress: () -> Unit
|
||||||
): ByteArray?
|
): String?
|
||||||
|
|
||||||
suspend fun convertApngToJxl(
|
suspend fun convertApngToJxl(
|
||||||
apngUris: List<String>,
|
apngUris: List<String>,
|
||||||
|
@ -108,7 +108,7 @@ class ApngToolsComponent @AssistedInject internal constructor(
|
|||||||
private val _jxlQuality: MutableState<Quality.Jxl> = mutableStateOf(Quality.Jxl())
|
private val _jxlQuality: MutableState<Quality.Jxl> = mutableStateOf(Quality.Jxl())
|
||||||
val jxlQuality by _jxlQuality
|
val jxlQuality by _jxlQuality
|
||||||
|
|
||||||
private var apngData: ByteArray? = null
|
private var _outputApngUri: String? = null
|
||||||
|
|
||||||
fun setType(type: Screen.ApngTools.Type) {
|
fun setType(type: Screen.ApngTools.Type) {
|
||||||
when (type) {
|
when (type) {
|
||||||
@ -166,7 +166,7 @@ class ApngToolsComponent @AssistedInject internal constructor(
|
|||||||
collectionJob = null
|
collectionJob = null
|
||||||
_type.update { null }
|
_type.update { null }
|
||||||
_convertedImageUris.update { emptyList() }
|
_convertedImageUris.update { emptyList() }
|
||||||
apngData = null
|
_outputApngUri = null
|
||||||
savingJob = null
|
savingJob = null
|
||||||
updateParams(ApngParams.Default)
|
updateParams(ApngParams.Default)
|
||||||
registerChangesCleared()
|
registerChangesCleared()
|
||||||
@ -191,14 +191,14 @@ class ApngToolsComponent @AssistedInject internal constructor(
|
|||||||
) {
|
) {
|
||||||
savingJob = componentScope.launch {
|
savingJob = componentScope.launch {
|
||||||
_isSaving.value = true
|
_isSaving.value = true
|
||||||
apngData?.let { byteArray ->
|
_outputApngUri?.let { apngUri ->
|
||||||
fileController.writeBytes(
|
fileController.transferBytes(
|
||||||
uri = uri.toString(),
|
fromUri = apngUri,
|
||||||
block = { it.writeBytes(byteArray) }
|
toUri = uri.toString(),
|
||||||
).also(onResult).onSuccess(::registerSave)
|
).also(onResult).onSuccess(::registerSave)
|
||||||
}
|
}
|
||||||
_isSaving.value = false
|
_isSaving.value = false
|
||||||
apngData = null
|
_outputApngUri = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +267,7 @@ class ApngToolsComponent @AssistedInject internal constructor(
|
|||||||
|
|
||||||
is Screen.ApngTools.Type.ImageToApng -> {
|
is Screen.ApngTools.Type.ImageToApng -> {
|
||||||
_left.value = type.imageUris?.size ?: -1
|
_left.value = type.imageUris?.size ?: -1
|
||||||
apngData = type.imageUris?.map { it.toString() }?.let { list ->
|
_outputApngUri = type.imageUris?.map { it.toString() }?.let { list ->
|
||||||
apngConverter.createApngFromImageUris(
|
apngConverter.createApngFromImageUris(
|
||||||
imageUris = list,
|
imageUris = list,
|
||||||
params = params,
|
params = params,
|
||||||
@ -441,13 +441,8 @@ class ApngToolsComponent @AssistedInject internal constructor(
|
|||||||
_done.update { it + 1 }
|
_done.update { it + 1 }
|
||||||
},
|
},
|
||||||
onFailure = {}
|
onFailure = {}
|
||||||
)?.also { byteArray ->
|
)?.also { uri ->
|
||||||
shareProvider.cacheByteArray(
|
onComplete(listOf(uri.toUri()))
|
||||||
byteArray = byteArray,
|
|
||||||
filename = "APNG_${timestamp()}.png"
|
|
||||||
)?.let {
|
|
||||||
onComplete(listOf(it.toUri()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package ru.tech.imageresizershrinker.feature.settings.data
|
package ru.tech.imageresizershrinker.feature.settings.data
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import androidx.core.net.toFile
|
import androidx.core.net.toFile
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
@ -27,6 +28,7 @@ import androidx.datastore.preferences.core.Preferences
|
|||||||
import androidx.datastore.preferences.core.edit
|
import androidx.datastore.preferences.core.edit
|
||||||
import com.t8rin.logger.Logger
|
import com.t8rin.logger.Logger
|
||||||
import com.t8rin.logger.makeLog
|
import com.t8rin.logger.makeLog
|
||||||
|
import dagger.Lazy
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@ -37,9 +39,11 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.tech.imageresizershrinker.core.data.utils.getFilename
|
import ru.tech.imageresizershrinker.core.data.utils.getFilename
|
||||||
import ru.tech.imageresizershrinker.core.data.utils.isInstalledFromPlayStore
|
import ru.tech.imageresizershrinker.core.data.utils.isInstalledFromPlayStore
|
||||||
|
import ru.tech.imageresizershrinker.core.data.utils.outputStream
|
||||||
import ru.tech.imageresizershrinker.core.domain.BackupFileExtension
|
import ru.tech.imageresizershrinker.core.domain.BackupFileExtension
|
||||||
import ru.tech.imageresizershrinker.core.domain.GlobalStorageName
|
import ru.tech.imageresizershrinker.core.domain.GlobalStorageName
|
||||||
import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
|
import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder
|
||||||
|
import ru.tech.imageresizershrinker.core.domain.image.ShareProvider
|
||||||
import ru.tech.imageresizershrinker.core.domain.image.model.ImageScaleMode
|
import ru.tech.imageresizershrinker.core.domain.image.model.ImageScaleMode
|
||||||
import ru.tech.imageresizershrinker.core.domain.image.model.ResizeType
|
import ru.tech.imageresizershrinker.core.domain.image.model.ResizeType
|
||||||
import ru.tech.imageresizershrinker.core.domain.model.ColorModel
|
import ru.tech.imageresizershrinker.core.domain.model.ColorModel
|
||||||
@ -151,7 +155,6 @@ import ru.tech.imageresizershrinker.feature.settings.data.keys.USE_RANDOM_EMOJIS
|
|||||||
import ru.tech.imageresizershrinker.feature.settings.data.keys.VIBRATION_STRENGTH
|
import ru.tech.imageresizershrinker.feature.settings.data.keys.VIBRATION_STRENGTH
|
||||||
import ru.tech.imageresizershrinker.feature.settings.data.keys.toSettingsState
|
import ru.tech.imageresizershrinker.feature.settings.data.keys.toSettingsState
|
||||||
import java.io.ByteArrayInputStream
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
@ -162,6 +165,7 @@ import kotlin.random.Random
|
|||||||
internal class AndroidSettingsManager @Inject constructor(
|
internal class AndroidSettingsManager @Inject constructor(
|
||||||
@ApplicationContext private val context: Context,
|
@ApplicationContext private val context: Context,
|
||||||
private val dataStore: DataStore<Preferences>,
|
private val dataStore: DataStore<Preferences>,
|
||||||
|
private val shareProvider: Lazy<ShareProvider<Bitmap>>,
|
||||||
dispatchersHolder: DispatchersHolder,
|
dispatchersHolder: DispatchersHolder,
|
||||||
) : DispatchersHolder by dispatchersHolder, SettingsManager {
|
) : DispatchersHolder by dispatchersHolder, SettingsManager {
|
||||||
|
|
||||||
@ -225,9 +229,9 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
it[APP_COLOR_TUPLE] = colorTuple
|
it[APP_COLOR_TUPLE] = colorTuple
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setPresets(newPresets: List<Int>) = edit {
|
override suspend fun setPresets(newPresets: List<Int>) = edit { preferences ->
|
||||||
if (newPresets.size > 3) {
|
if (newPresets.size > 3) {
|
||||||
it[PRESETS] = newPresets
|
preferences[PRESETS] = newPresets
|
||||||
.map { it.coerceIn(10..500) }
|
.map { it.coerceIn(10..500) }
|
||||||
.toSortedSet()
|
.toSortedSet()
|
||||||
.toList()
|
.toList()
|
||||||
@ -454,13 +458,15 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
it[INITIAL_OCR_MODE] ?: 1
|
it[INITIAL_OCR_MODE] ?: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createLogsExport(): ByteArray = withContext(ioDispatcher) {
|
override suspend fun createLogsExport(): String = withContext(ioDispatcher) {
|
||||||
"Start Logs Export".makeLog("SettingsManager")
|
"Start Logs Export".makeLog("SettingsManager")
|
||||||
|
|
||||||
val logsFile = Logger.getLogsFile().toFile()
|
val logsFile = Logger.getLogsFile().toFile()
|
||||||
val settingsFile = createBackupFile()
|
val settingsFile = createBackupFile()
|
||||||
|
|
||||||
val out = ByteArrayOutputStream()
|
shareProvider.get().cacheData(
|
||||||
|
writeData = { writeable ->
|
||||||
|
val out = writeable.outputStream()
|
||||||
|
|
||||||
ZipOutputStream(out).use { zipOut ->
|
ZipOutputStream(out).use { zipOut ->
|
||||||
FileInputStream(logsFile).use { fis ->
|
FileInputStream(logsFile).use { fis ->
|
||||||
@ -476,12 +482,11 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
zipOut.closeEntry()
|
zipOut.closeEntry()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
out.toByteArray()
|
filename = "image_toolbox_logs_${timestamp()}.zip"
|
||||||
|
) ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createLogsFilename(): String = "image_toolbox_logs_${timestamp()}.zip"
|
|
||||||
|
|
||||||
override suspend fun setScreensWithBrightnessEnforcement(data: String) = edit {
|
override suspend fun setScreensWithBrightnessEnforcement(data: String) = edit {
|
||||||
it[SCREENS_WITH_BRIGHTNESS_ENFORCEMENT] = data
|
it[SCREENS_WITH_BRIGHTNESS_ENFORCEMENT] = data
|
||||||
}
|
}
|
||||||
@ -561,8 +566,8 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
|
|
||||||
override suspend fun setOneTimeSaveLocations(
|
override suspend fun setOneTimeSaveLocations(
|
||||||
value: List<OneTimeSaveLocation>
|
value: List<OneTimeSaveLocation>
|
||||||
) = edit {
|
) = edit { preferences ->
|
||||||
it[ONE_TIME_SAVE_LOCATIONS] = value.filter {
|
preferences[ONE_TIME_SAVE_LOCATIONS] = value.filter {
|
||||||
it.uri.isNotEmpty() && it.date != null
|
it.uri.isNotEmpty() && it.date != null
|
||||||
}.distinctBy { it.uri }.joinToString(", ")
|
}.distinctBy { it.uri }.joinToString(", ")
|
||||||
}
|
}
|
||||||
@ -570,7 +575,7 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
override suspend fun toggleRecentColor(
|
override suspend fun toggleRecentColor(
|
||||||
color: ColorModel,
|
color: ColorModel,
|
||||||
forceExclude: Boolean,
|
forceExclude: Boolean,
|
||||||
) = edit {
|
) = edit { preferences ->
|
||||||
val current = currentSettings.recentColors
|
val current = currentSettings.recentColors
|
||||||
val newColors = if (color in current) {
|
val newColors = if (color in current) {
|
||||||
if (forceExclude) {
|
if (forceExclude) {
|
||||||
@ -582,13 +587,13 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
listOf(color) + current
|
listOf(color) + current
|
||||||
}
|
}
|
||||||
|
|
||||||
it[RECENT_COLORS] = newColors.take(30).map { it.colorInt.toString() }.toSet()
|
preferences[RECENT_COLORS] = newColors.take(30).map { it.colorInt.toString() }.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleFavoriteColor(
|
override suspend fun toggleFavoriteColor(
|
||||||
color: ColorModel,
|
color: ColorModel,
|
||||||
forceExclude: Boolean
|
forceExclude: Boolean
|
||||||
) = edit {
|
) = edit { preferences ->
|
||||||
val current = currentSettings.favoriteColors
|
val current = currentSettings.favoriteColors
|
||||||
val newColors = if (color in current) {
|
val newColors = if (color in current) {
|
||||||
if (forceExclude) {
|
if (forceExclude) {
|
||||||
@ -600,7 +605,7 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
listOf(color) + current
|
listOf(color) + current
|
||||||
}
|
}
|
||||||
|
|
||||||
it[FAVORITE_COLORS] = newColors.map { it.colorInt.toString() }.joinToString("/")
|
preferences[FAVORITE_COLORS] = newColors.joinToString("/") { it.colorInt.toString() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleOpenEditInsteadOfPreview() = toggle(
|
override suspend fun toggleOpenEditInsteadOfPreview() = toggle(
|
||||||
@ -668,7 +673,7 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
current + screenId
|
current + screenId
|
||||||
}
|
}
|
||||||
|
|
||||||
it[FAVORITE_SCREENS] = newScreens.joinToString("/") { it.toString() }
|
it[FAVORITE_SCREENS] = newScreens.joinToString("/")
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleIsLinkPreviewEnabled() = toggle(
|
override suspend fun toggleIsLinkPreviewEnabled() = toggle(
|
||||||
@ -698,8 +703,8 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
it[IS_TELEGRAM_GROUP_OPENED] = true
|
it[IS_TELEGRAM_GROUP_OPENED] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setDefaultResizeType(resizeType: ResizeType) = edit {
|
override suspend fun setDefaultResizeType(resizeType: ResizeType) = edit { preferences ->
|
||||||
it[DEFAULT_RESIZE_TYPE] = ResizeType.entries.indexOfFirst {
|
preferences[DEFAULT_RESIZE_TYPE] = ResizeType.entries.indexOfFirst {
|
||||||
it::class.isInstance(resizeType)
|
it::class.isInstance(resizeType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -742,8 +747,8 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
override suspend fun toggleSettingsGroupVisibility(
|
override suspend fun toggleSettingsGroupVisibility(
|
||||||
key: Int,
|
key: Int,
|
||||||
value: Boolean
|
value: Boolean
|
||||||
) = edit {
|
) = edit { preferences ->
|
||||||
it[SETTINGS_GROUP_VISIBILITY] =
|
preferences[SETTINGS_GROUP_VISIBILITY] =
|
||||||
currentSettings.settingGroupsInitialVisibility.toMutableMap().run {
|
currentSettings.settingGroupsInitialVisibility.toMutableMap().run {
|
||||||
this[key] = value
|
this[key] = value
|
||||||
map {
|
map {
|
||||||
@ -758,8 +763,8 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
|
|
||||||
override suspend fun updateFavoriteColors(
|
override suspend fun updateFavoriteColors(
|
||||||
colors: List<ColorModel>
|
colors: List<ColorModel>
|
||||||
) = edit {
|
) = edit { preferences ->
|
||||||
it[FAVORITE_COLORS] = colors.map { it.colorInt.toString() }.joinToString("/")
|
preferences[FAVORITE_COLORS] = colors.joinToString("/") { it.colorInt.toString() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setBackgroundColorForNoAlphaFormats(
|
override suspend fun setBackgroundColorForNoAlphaFormats(
|
||||||
@ -832,10 +837,10 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
setCustomFonts(currentSettings.customFonts - font)
|
setCustomFonts(currentSettings.customFonts - font)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createCustomFontsExport(): ByteArray = withContext(ioDispatcher) {
|
override suspend fun createCustomFontsExport(): String? = withContext(ioDispatcher) {
|
||||||
val out = ByteArrayOutputStream()
|
shareProvider.get().cacheData(
|
||||||
|
writeData = { writeable ->
|
||||||
ZipOutputStream(out).use { zipOut ->
|
ZipOutputStream(writeable.outputStream()).use { zipOut ->
|
||||||
val dir = File(context.filesDir, "customFonts")
|
val dir = File(context.filesDir, "customFonts")
|
||||||
dir.listFiles()?.forEach { file ->
|
dir.listFiles()?.forEach { file ->
|
||||||
FileInputStream(file).use { fis ->
|
FileInputStream(file).use { fis ->
|
||||||
@ -846,8 +851,9 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
out.toByteArray()
|
filename = "fonts_export.zip"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleEnableToolExitConfirmation() = toggle(
|
override suspend fun toggleEnableToolExitConfirmation() = toggle(
|
||||||
@ -863,7 +869,7 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
this[key] = !value
|
this[key] = !value
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun toggle(
|
private suspend fun toggle(
|
||||||
key: Preferences.Key<Boolean>,
|
key: Preferences.Key<Boolean>,
|
||||||
defaultValue: Boolean,
|
defaultValue: Boolean,
|
||||||
) = edit {
|
) = edit {
|
||||||
@ -873,7 +879,7 @@ internal class AndroidSettingsManager @Inject constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun edit(
|
private suspend fun edit(
|
||||||
transform: suspend (MutablePreferences) -> Unit
|
transform: suspend (MutablePreferences) -> Unit
|
||||||
) {
|
) {
|
||||||
dataStore.edit(transform)
|
dataStore.edit(transform)
|
||||||
|
@ -248,9 +248,9 @@ class SettingsComponent @AssistedInject internal constructor(
|
|||||||
uri: Uri,
|
uri: Uri,
|
||||||
onResult: (SaveResult) -> Unit,
|
onResult: (SaveResult) -> Unit,
|
||||||
) = settingsScope {
|
) = settingsScope {
|
||||||
fileController.writeBytes(
|
fileController.transferBytes(
|
||||||
uri = uri.toString(),
|
fromUri = createCustomFontsExport().toString(),
|
||||||
block = { it.writeBytes(createCustomFontsExport()) }
|
toUri = uri.toString()
|
||||||
).also(onResult)
|
).also(onResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,11 +466,9 @@ class SettingsComponent @AssistedInject internal constructor(
|
|||||||
fun toggleEnableToolExitConfirmation() = settingsScope { toggleEnableToolExitConfirmation() }
|
fun toggleEnableToolExitConfirmation() = settingsScope { toggleEnableToolExitConfirmation() }
|
||||||
|
|
||||||
fun shareLogs() = settingsScope {
|
fun shareLogs() = settingsScope {
|
||||||
shareProvider.shareData(
|
shareProvider.shareUri(
|
||||||
writeData = {
|
uri = settingsManager.createLogsExport(),
|
||||||
it.writeBytes(settingsManager.createLogsExport())
|
onComplete = {}
|
||||||
},
|
|
||||||
filename = settingsManager.createLogsFilename()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user