Skip to content

Commit 1f65f36

Browse files
committed
Remove strings in extra image type and pass sealed interface instead
1 parent cb0c754 commit 1f65f36

File tree

7 files changed

+106
-76
lines changed

7 files changed

+106
-76
lines changed

app/src/main/java/ru/tech/imageresizershrinker/app/presentation/AppActivity.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class AppActivity : M3Activity() {
5757
parseImageFromIntent(
5858
intent = intent,
5959
onStart = component::hideSelectDialog,
60-
onHasExtraImageType = component::updateExtraImageType,
60+
onHasExtraDataType = component::updateExtraDataType,
6161
onColdStart = component::cancelShowingExitDialog,
6262
onGetUris = component::updateUris,
6363
onShowToast = component::showToast,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* ImageToolbox is an image editor for android
3+
* Copyright (c) 2025 T8RIN (Malik Mukhametzyanov)
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*
14+
* You should have received a copy of the Apache License
15+
* along with this program. If not, see <http://www.apache.org/licenses/LICENSE-2.0>.
16+
*/
17+
18+
package ru.tech.imageresizershrinker.core.domain.model
19+
20+
sealed interface ExtraDataType {
21+
data object Gif : ExtraDataType
22+
data object Pdf : ExtraDataType
23+
data object File : ExtraDataType
24+
data object Jxl : ExtraDataType
25+
data object Audio : ExtraDataType
26+
27+
data class Backup(val uri: String) : ExtraDataType
28+
data class Text(val text: String) : ExtraDataType
29+
}

core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/utils/helper/ContextUtils.kt

+15-14
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import androidx.documentfile.provider.DocumentFile
5050
import kotlinx.coroutines.Dispatchers
5151
import kotlinx.coroutines.withContext
5252
import ru.tech.imageresizershrinker.core.domain.BackupFileExtension
53+
import ru.tech.imageresizershrinker.core.domain.model.ExtraDataType
5354
import ru.tech.imageresizershrinker.core.domain.model.PerformanceClass
5455
import ru.tech.imageresizershrinker.core.resources.R
5556
import ru.tech.imageresizershrinker.core.ui.utils.helper.IntentUtils.parcelable
@@ -199,7 +200,7 @@ object ContextUtils {
199200
onShowToast: (message: String, icon: ImageVector) -> Unit,
200201
onNavigate: (Screen) -> Unit,
201202
onGetUris: (List<Uri>) -> Unit,
202-
onHasExtraImageType: (String) -> Unit, //TODO: Add normal sealed class instead of string
203+
onHasExtraDataType: (ExtraDataType) -> Unit,
203204
isHasUris: Boolean,
204205
onWantGithubReview: () -> Unit,
205206
isOpenEditInsteadOfPreview: Boolean,
@@ -247,7 +248,7 @@ object ContextUtils {
247248
onNavigate(Screen.PickColorFromImage(it))
248249
} else {
249250
if (intent.type?.contains("gif") == true) {
250-
onHasExtraImageType("gif")
251+
onHasExtraDataType(ExtraDataType.Gif)
251252
}
252253
onGetUris(listOf(it))
253254
}
@@ -257,7 +258,7 @@ object ContextUtils {
257258
Intent.ACTION_SEND_MULTIPLE -> {
258259
intent.parcelableArrayList<Uri>(Intent.EXTRA_STREAM)?.let {
259260
if (intent.type?.contains("gif") == true) {
260-
onHasExtraImageType("gif")
261+
onHasExtraDataType(ExtraDataType.Gif)
261262
it.firstOrNull()?.let { uri ->
262263
onGetUris(listOf(uri))
263264
}
@@ -268,7 +269,7 @@ object ContextUtils {
268269
else -> {
269270
intent.data?.let {
270271
if (intent.type?.contains("gif") == true) {
271-
onHasExtraImageType("gif")
272+
onHasExtraDataType(ExtraDataType.Gif)
272273
}
273274
onGetUris(listOf(it))
274275
}
@@ -286,12 +287,12 @@ object ContextUtils {
286287
if (intent.action == Intent.ACTION_VIEW) {
287288
onNavigate(Screen.PdfTools(Screen.PdfTools.Type.Preview(it)))
288289
} else {
289-
onHasExtraImageType("pdf")
290+
onHasExtraDataType(ExtraDataType.Pdf)
290291
onGetUris(listOf(uri))
291292
}
292293
}
293294
} else if (text != null) {
294-
onHasExtraImageType(text)
295+
onHasExtraDataType(ExtraDataType.Text(text))
295296
onGetUris(listOf())
296297
} else {
297298
val isAudio = intent.type?.startsWith("audio/") == true
@@ -300,7 +301,7 @@ object ContextUtils {
300301
Intent.ACTION_SEND_MULTIPLE -> {
301302
intent.parcelableArrayList<Uri>(Intent.EXTRA_STREAM)?.let {
302303
if (isAudio) {
303-
onHasExtraImageType("audio")
304+
onHasExtraDataType(ExtraDataType.Audio)
304305
onGetUris(it)
305306
} else {
306307
onNavigate(Screen.Zip(it))
@@ -311,13 +312,13 @@ object ContextUtils {
311312
Intent.ACTION_SEND -> {
312313
intent.parcelable<Uri>(Intent.EXTRA_STREAM)?.let {
313314
if (it.toString().contains(BackupFileExtension, true)) {
314-
onHasExtraImageType("$BackupFileExtension $it")
315+
onHasExtraDataType(ExtraDataType.Backup(it.toString()))
315316
return
316317
}
317318
if (isAudio) {
318-
onHasExtraImageType("audio")
319+
onHasExtraDataType(ExtraDataType.Audio)
319320
} else {
320-
onHasExtraImageType("file")
321+
onHasExtraDataType(ExtraDataType.File)
321322
}
322323

323324
onGetUris(listOf(it))
@@ -334,20 +335,20 @@ object ContextUtils {
334335
val uri = uris.first()
335336

336337
if (uri.toString().contains(BackupFileExtension, true)) {
337-
onHasExtraImageType("$BackupFileExtension $uri")
338+
onHasExtraDataType(ExtraDataType.Backup(uri.toString()))
338339
return
339340
}
340341

341342
if (isAudio) {
342-
onHasExtraImageType("audio")
343+
onHasExtraDataType(ExtraDataType.Audio)
343344
} else {
344-
onHasExtraImageType("file")
345+
onHasExtraDataType(ExtraDataType.File)
345346
}
346347

347348
onGetUris(uris)
348349
} else if (uris.isNotEmpty()) {
349350
if (isAudio) {
350-
onHasExtraImageType("audio")
351+
onHasExtraDataType(ExtraDataType.Audio)
351352
onGetUris(uris)
352353
} else {
353354
onNavigate(Screen.Zip(uris))

core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/sheets/ProcessImagesPreferenceSheet.kt

+4-3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import androidx.compose.ui.res.stringResource
3737
import androidx.compose.ui.unit.dp
3838
import kotlinx.coroutines.delay
3939
import kotlinx.coroutines.launch
40+
import ru.tech.imageresizershrinker.core.domain.model.ExtraDataType
4041
import ru.tech.imageresizershrinker.core.resources.R
4142
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
4243
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedButton
@@ -50,7 +51,7 @@ import ru.tech.imageresizershrinker.core.ui.widget.utils.screenList
5051
@Composable
5152
fun ProcessImagesPreferenceSheet(
5253
uris: List<Uri>,
53-
extraImageType: String? = null,
54+
extraDataType: ExtraDataType? = null,
5455
visible: Boolean,
5556
onDismiss: () -> Unit,
5657
onNavigate: (Screen) -> Unit
@@ -73,7 +74,7 @@ fun ProcessImagesPreferenceSheet(
7374
}
7475
},
7576
sheetContent = {
76-
val urisCorrespondingScreens by uris.screenList(extraImageType)
77+
val urisCorrespondingScreens by uris.screenList(extraDataType)
7778

7879
Box(Modifier.fillMaxWidth()) {
7980
LazyVerticalStaggeredGrid(
@@ -82,7 +83,7 @@ fun ProcessImagesPreferenceSheet(
8283
verticalItemSpacing = 8.dp,
8384
horizontalArrangement = Arrangement.spacedBy(8.dp)
8485
) {
85-
if (extraImageType in listOf("gif", null)) {
86+
if (extraDataType == null || extraDataType == ExtraDataType.Gif) {
8687
item(
8788
span = StaggeredGridItemSpan.FullLine
8889
) {

core/ui/src/main/kotlin/ru/tech/imageresizershrinker/core/ui/widget/utils/ScreenList.kt

+47-48
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ import androidx.compose.runtime.getValue
2828
import androidx.compose.runtime.remember
2929
import androidx.compose.ui.platform.LocalContext
3030
import androidx.core.net.toUri
31+
import ru.tech.imageresizershrinker.core.domain.model.ExtraDataType
3132
import ru.tech.imageresizershrinker.core.settings.presentation.provider.LocalSettingsState
3233
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.getFilename
3334
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
3435
import java.util.Locale
3536

3637
@Composable
3738
internal fun List<Uri>.screenList(
38-
extraImageType: String? //TODO: Add normal sealed class instead of string
39+
extraDataType: ExtraDataType?
3940
): State<List<Screen>> {
4041
val uris = this
4142
val context = LocalContext.current
@@ -52,22 +53,22 @@ internal fun List<Uri>.screenList(
5253

5354
val filesAvailableScreens by remember(uris) {
5455
derivedStateOf {
55-
listOf(
56-
Screen.Cipher(uris.firstOrNull()),
57-
Screen.ChecksumTools(uris.firstOrNull()),
58-
Screen.Zip(uris)
59-
)
56+
if (uris.size > 1) {
57+
listOf(Screen.Zip(uris))
58+
} else {
59+
listOf(
60+
Screen.Cipher(uris.firstOrNull()),
61+
Screen.ChecksumTools(uris.firstOrNull()),
62+
Screen.Zip(uris)
63+
)
64+
}
6065
}
6166
}
6267
val audioAvailableScreens by remember(uris) {
6368
derivedStateOf {
6469
listOf(
6570
Screen.AudioCoverExtractor(uris)
66-
) + if (uris.size > 1) {
67-
filesAvailableScreens
68-
} else {
69-
listOf(Screen.Zip(uris))
70-
}
71+
) + filesAvailableScreens
7172
}
7273
}
7374
val gifAvailableScreens by remember(uris) {
@@ -83,11 +84,8 @@ internal fun List<Uri>.screenList(
8384
),
8485
Screen.GifTools(
8586
Screen.GifTools.Type.GifToWebp(uris)
86-
),
87-
Screen.Cipher(uris.firstOrNull()),
88-
Screen.ChecksumTools(uris.firstOrNull()),
89-
Screen.Zip(uris)
90-
)
87+
)
88+
) + filesAvailableScreens
9189
}
9290
}
9391
val pdfAvailableScreens by remember(uris) {
@@ -102,11 +100,8 @@ internal fun List<Uri>.screenList(
102100
Screen.PdfTools.Type.PdfToImages(
103101
uris.firstOrNull()
104102
)
105-
),
106-
Screen.Cipher(uris.firstOrNull()),
107-
Screen.ChecksumTools(uris.firstOrNull()),
108-
Screen.Zip(uris)
109-
)
103+
)
104+
) + filesAvailableScreens
110105
}
111106
}
112107
val singleImageScreens by remember(uris) {
@@ -141,8 +136,6 @@ internal fun List<Uri>.screenList(
141136
Screen.GifTools.Type.ImageToGif(uris)
142137
),
143138
Screen.Base64Tools(uris.firstOrNull()),
144-
Screen.Cipher(uris.firstOrNull()),
145-
Screen.ChecksumTools(uris.firstOrNull()),
146139
Screen.ImagePreview(uris),
147140
Screen.PickColorFromImage(uris.firstOrNull()),
148141
Screen.GeneratePalette(uris.firstOrNull()),
@@ -153,36 +146,37 @@ internal fun List<Uri>.screenList(
153146
Screen.JxlTools.Type.ImageToJxl(uris)
154147
),
155148
Screen.SvgMaker(uris),
156-
Screen.Zip(uris),
157149
Screen.EditExif(uris.firstOrNull()),
158150
Screen.DeleteExif(uris),
159151
Screen.LimitResize(uris)
160-
).let {
152+
).let { list ->
153+
val mergedList = list + filesAvailableScreens
154+
161155
val uri = uris.firstOrNull()
162156

163157
if (uri.type("png")) {
164-
it + Screen.ApngTools(
158+
mergedList + Screen.ApngTools(
165159
Screen.ApngTools.Type.ApngToImage(uris.firstOrNull())
166160
)
167161
} else if (uri.type("jpg", "jpeg")) {
168-
it + Screen.JxlTools(
162+
mergedList + Screen.JxlTools(
169163
Screen.JxlTools.Type.JpegToJxl(uris)
170164
)
171165
} else if (uri.type("jxl")) {
172-
it + Screen.JxlTools(
166+
mergedList + Screen.JxlTools(
173167
Screen.JxlTools.Type.JxlToJpeg(uris)
174168
) + Screen.JxlTools(
175169
Screen.JxlTools.Type.JxlToImage(uris.firstOrNull())
176170
)
177171
} else if (uri.type("webp")) {
178-
it + Screen.WebpTools(
172+
mergedList + Screen.WebpTools(
179173
Screen.WebpTools.Type.WebpToImage(uris.firstOrNull())
180174
)
181-
} else it
175+
} else mergedList
182176
}
183177
}
184178
}
185-
val multipleImagesScreens by remember(uris) {
179+
val multipleImageScreens by remember(uris) {
186180
derivedStateOf {
187181
mutableListOf(
188182
Screen.ResizeAndConvert(uris),
@@ -209,7 +203,7 @@ internal fun List<Uri>.screenList(
209203
add(Screen.ImageCutter(uris))
210204
add(Screen.ImagePreview(uris))
211205
add(Screen.LimitResize(uris))
212-
add(Screen.Zip(uris))
206+
addAll(filesAvailableScreens)
213207
add(Screen.SvgMaker(uris))
214208

215209
var haveJpeg = false
@@ -261,12 +255,19 @@ internal fun List<Uri>.screenList(
261255
}
262256
}
263257
}
258+
val imageScreens by remember(uris) {
259+
derivedStateOf {
260+
if (uris.size == 1) singleImageScreens
261+
else multipleImageScreens
262+
}
263+
}
264264

265-
val textAvailableScreens by remember(extraImageType) {
265+
val textAvailableScreens by remember(extraDataType) {
266266
derivedStateOf {
267+
val text = (extraDataType as? ExtraDataType.Text)?.text ?: ""
267268
listOf(
268-
Screen.ScanQrCode(extraImageType ?: ""),
269-
Screen.LoadNetImage(extraImageType ?: "")
269+
Screen.ScanQrCode(text),
270+
Screen.LoadNetImage(text)
270271
)
271272
}
272273
}
@@ -275,23 +276,21 @@ internal fun List<Uri>.screenList(
275276

276277
return remember(
277278
favoriteScreens,
278-
extraImageType,
279+
extraDataType,
279280
uris,
280281
pdfAvailableScreens,
281-
singleImageScreens,
282-
multipleImagesScreens
282+
audioAvailableScreens,
283+
imageScreens
283284
) {
284285
derivedStateOf {
285-
when {
286-
extraImageType == "audio" -> audioAvailableScreens
287-
extraImageType == "pdf" -> pdfAvailableScreens
288-
extraImageType == "gif" -> gifAvailableScreens
289-
extraImageType == "file" -> filesAvailableScreens
290-
uris.size == 1 -> singleImageScreens
291-
uris.size >= 2 -> multipleImagesScreens
292-
extraImageType != null -> textAvailableScreens
293-
294-
else -> multipleImagesScreens
286+
when (extraDataType) {
287+
is ExtraDataType.Backup -> filesAvailableScreens
288+
is ExtraDataType.Text -> textAvailableScreens
289+
ExtraDataType.Audio -> audioAvailableScreens
290+
ExtraDataType.File -> filesAvailableScreens
291+
ExtraDataType.Gif -> gifAvailableScreens
292+
ExtraDataType.Pdf -> pdfAvailableScreens
293+
null, ExtraDataType.Jxl -> imageScreens
295294
}.sortedWith(compareBy(nullsLast()) { s -> favoriteScreens.find { it == s.id } })
296295
}
297296
}

feature/root/src/main/java/ru/tech/imageresizershrinker/feature/root/presentation/components/RootDialogs.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ internal fun RootDialogs(component: RootComponent) {
4646
val essentials = rememberLocalEssentials()
4747
ProcessImagesPreferenceSheet(
4848
uris = component.uris ?: emptyList(),
49-
extraImageType = component.extraImageType,
49+
extraDataType = component.extraDataType,
5050
visible = component.showSelectDialog,
5151
onDismiss = component::hideSelectDialog,
5252
onNavigate = { screen ->

0 commit comments

Comments
 (0)