11package me.rosuh.easywatermark.data.repo
22
33import android.graphics.Color
4+ import android.graphics.Shader
45import android.net.Uri
6+ import android.util.Log
7+ import androidx.collection.ArrayMap
58import androidx.datastore.core.DataStore
69import androidx.datastore.preferences.core.*
7- import androidx.lifecycle.asLiveData
8- import kotlinx.coroutines.flow.Flow
9- import kotlinx.coroutines.flow.MutableStateFlow
10- import kotlinx.coroutines.flow.catch
11- import kotlinx.coroutines.flow.map
10+ import kotlinx.coroutines.Dispatchers
11+ import kotlinx.coroutines.flow.*
12+ import kotlinx.coroutines.withContext
1213import me.rosuh.easywatermark.MyApp
1314import me.rosuh.easywatermark.R
1415import me.rosuh.easywatermark.data.model.ImageInfo
@@ -21,6 +22,8 @@ import me.rosuh.easywatermark.data.repo.WaterMarkRepository.PreferenceKeys.KEY_E
2122import me.rosuh.easywatermark.data.repo.WaterMarkRepository.PreferenceKeys.KEY_HORIZON_GAP
2223import me.rosuh.easywatermark.data.repo.WaterMarkRepository.PreferenceKeys.KEY_ICON_URI
2324import me.rosuh.easywatermark.data.repo.WaterMarkRepository.PreferenceKeys.KEY_MODE
25+ import me.rosuh.easywatermark.data.repo.WaterMarkRepository.PreferenceKeys.KEY_OFFSET_X
26+ import me.rosuh.easywatermark.data.repo.WaterMarkRepository.PreferenceKeys.KEY_OFFSET_Y
2427import me.rosuh.easywatermark.data.repo.WaterMarkRepository.PreferenceKeys.KEY_TEXT
2528import me.rosuh.easywatermark.data.repo.WaterMarkRepository.PreferenceKeys.KEY_TEXT_COLOR
2629import me.rosuh.easywatermark.data.repo.WaterMarkRepository.PreferenceKeys.KEY_TEXT_SIZE
@@ -31,6 +34,7 @@ import java.io.IOException
3134import javax.inject.Inject
3235import javax.inject.Named
3336import javax.inject.Singleton
37+ import kotlin.collections.ArrayList
3438
3539@Singleton
3640class WaterMarkRepository @Inject constructor(
@@ -48,10 +52,18 @@ class WaterMarkRepository @Inject constructor(
4852 val KEY_VERTICAL_GAP = intPreferencesKey(SP_KEY_VERTICAL_GAP )
4953 val KEY_DEGREE = floatPreferencesKey(SP_KEY_DEGREE )
5054 val KEY_ICON_URI = stringPreferencesKey(SP_KEY_ICON_URI )
55+ val KEY_URI = stringPreferencesKey(SP_KEY_URI )
5156 val KEY_MODE = intPreferencesKey(SP_KEY_WATERMARK_MODE )
5257 val KEY_ENABLE_BOUNDS = booleanPreferencesKey(SP_KEY_ENABLE_BOUNDS )
58+ val KEY_TILE_MODE = intPreferencesKey(SP_KEY_TILE_MODEL )
59+ val KEY_OFFSET_X = floatPreferencesKey(SP_KEY_OFFSET_X )
60+ val KEY_OFFSET_Y = floatPreferencesKey(SP_KEY_OFFSET_Y )
5361 }
5462
63+ private val _selectedImage = MutableStateFlow (ImageInfo .empty())
64+
65+ val selectedImage: StateFlow <ImageInfo > = _selectedImage
66+
5567 val waterMark: Flow <WaterMark > = dataStore.data
5668 .catch { exception ->
5769 if (exception is IOException ) {
@@ -78,16 +90,19 @@ class WaterMarkRepository @Inject constructor(
7890 )
7991 }
8092
81- private val imageListFlow : MutableStateFlow <List <ImageInfo >> =
82- MutableStateFlow (emptyList() )
93+ private val _imageMapFlow : MutableStateFlow <List <ImageInfo >> = MutableStateFlow (emptyList())
94+ private val imageInfoMap : MutableMap < Uri , Int > = ArrayMap ( _imageMapFlow .value.size )
8395
84- val uriLivedData = imageListFlow.asLiveData()
96+ val imageInfoMapFlow = _imageMapFlow
8597
8698 val imageInfoList: List <ImageInfo >
87- get() = uriLivedData .value ? : emptyList()
99+ get() = imageInfoMapFlow .value
88100
89101 suspend fun updateImageList (imageList : List <ImageInfo >) {
90- imageListFlow.emit(imageList)
102+ val map = imageList.mapIndexed { index, imageInfo -> imageInfo.uri to index }.toMap()
103+ imageInfoMap.clear()
104+ imageInfoMap.putAll(map)
105+ _imageMapFlow .emit(imageList)
91106 }
92107
93108 suspend fun updateText (text : String ) {
@@ -138,6 +153,40 @@ class WaterMarkRepository @Inject constructor(
138153 }
139154 }
140155
156+ suspend fun updateTileMode (imageInfo : ImageInfo , mode : Shader .TileMode ): ImageInfo {
157+ if (imageInfo.tileMode == mode.ordinal) {
158+ Log .i(" WaterMarkRepository" , " updateTileMode: same mode" )
159+ return imageInfo
160+ }
161+ val index = imageInfoMap[imageInfo.uri] ? : kotlin.run {
162+ Log .e(" WaterMarkRepository" , " updateTileMode: imageInfo not found, uri = ${imageInfo.uri} " )
163+ return imageInfo
164+ }
165+
166+ val info = imageInfo.copy(tileMode = mode.ordinal)
167+ val list = ArrayList (imageInfoList)
168+ list[index] = info
169+ imageInfoMap[info.uri] = index
170+ _imageMapFlow .emit(list)
171+ _selectedImage .emit(info)
172+ return info
173+ }
174+
175+ suspend fun updateOffset (imageInfo : ImageInfo ) {
176+ if (imageInfo == selectedImage.value) {
177+ return
178+ }
179+ val index = imageInfoMap[selectedImage.value.uri] ? : kotlin.run {
180+ Log .e(" WaterMarkRepository" , " updateOffset: imageInfo not found, uri = ${selectedImage.value.uri} " )
181+ return
182+ }
183+ val list = ArrayList (imageInfoList)
184+ list[index] = imageInfo
185+ imageInfoMap[imageInfo.uri] = index
186+ _imageMapFlow .emit(list)
187+ _selectedImage .emit(imageInfo)
188+ }
189+
141190 suspend fun resetModeToText () {
142191 dataStore.edit { it[KEY_MODE ] = MarkMode .Text .value }
143192 }
@@ -150,6 +199,11 @@ class WaterMarkRepository @Inject constructor(
150199 updateImageList(emptyList())
151200 }
152201
202+ suspend fun select (uri : Uri ) = withContext(Dispatchers .Default ) {
203+ val info = imageInfoList.find { it.uri == uri } ? : ImageInfo (uri)
204+ _selectedImage .emit(info)
205+ }
206+
153207 sealed class MarkMode (val value : Int ) {
154208 object Text : MarkMode(0 )
155209
@@ -171,9 +225,15 @@ class WaterMarkRepository @Inject constructor(
171225 const val SP_KEY_CHANGE_LOG = " ${SP_NAME } _key_change_log"
172226 const val SP_KEY_ENABLE_BOUNDS = " ${SP_NAME } _key_enable_bounds"
173227 const val SP_KEY_ICON_URI = " ${SP_NAME } _key_icon_uri"
228+ const val SP_KEY_URI = " ${SP_NAME } _key_uri"
174229 const val SP_KEY_WATERMARK_MODE = " ${SP_NAME } _key_watermark_mode"
175230 const val SP_KEY_IMAGE_ROTATION = " ${SP_NAME } _key_watermark_mode"
231+ const val SP_KEY_TILE_MODEL = " ${SP_NAME } _key_tile_model"
232+ const val SP_KEY_OFFSET_X = " ${SP_NAME } _key_offset_x"
233+ const val SP_KEY_OFFSET_Y = " ${SP_NAME } _key_offset_y"
176234 const val MAX_TEXT_SIZE = 100f
235+ const val MIN_TEXT_SIZE = 1f
236+ const val DEFAULT_TEXT_SIZE = 14f
177237 const val MAX_DEGREE = 360f
178238 const val MAX_HORIZON_GAP = 500
179239 const val MAX_VERTICAL_GAP = 500
0 commit comments