chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.image.toolbox.library)
|
||||
alias(libs.plugins.image.toolbox.feature)
|
||||
alias(libs.plugins.image.toolbox.hilt)
|
||||
alias(libs.plugins.image.toolbox.compose)
|
||||
}
|
||||
|
||||
android.namespace = "com.t8rin.imagetoolbox.feature.root"
|
||||
|
||||
dependencies {
|
||||
implementation(projects.feature.main)
|
||||
implementation(projects.feature.loadNetImage)
|
||||
implementation(projects.feature.crop)
|
||||
implementation(projects.feature.limitsResize)
|
||||
implementation(projects.feature.cipher)
|
||||
implementation(projects.feature.imagePreview)
|
||||
implementation(projects.feature.weightResize)
|
||||
implementation(projects.feature.compare)
|
||||
implementation(projects.feature.deleteExif)
|
||||
implementation(projects.feature.paletteTools)
|
||||
implementation(projects.feature.resizeConvert)
|
||||
implementation(projects.feature.pdfTools)
|
||||
implementation(projects.feature.singleEdit)
|
||||
implementation(projects.feature.eraseBackground)
|
||||
implementation(projects.feature.draw)
|
||||
implementation(projects.feature.filters)
|
||||
implementation(projects.feature.imageStitch)
|
||||
implementation(projects.feature.pickColor)
|
||||
implementation(projects.feature.recognizeText)
|
||||
implementation(projects.feature.gradientMaker)
|
||||
implementation(projects.feature.watermarking)
|
||||
implementation(projects.feature.gifTools)
|
||||
implementation(projects.feature.apngTools)
|
||||
implementation(projects.feature.zip)
|
||||
implementation(projects.feature.jxlTools)
|
||||
implementation(projects.feature.settings)
|
||||
implementation(projects.feature.easterEgg)
|
||||
implementation(projects.feature.svgMaker)
|
||||
implementation(projects.feature.formatConversion)
|
||||
implementation(projects.feature.documentScanner)
|
||||
implementation(projects.feature.scanQrCode)
|
||||
implementation(projects.feature.imageStacking)
|
||||
implementation(projects.feature.imageSplitting)
|
||||
implementation(projects.feature.colorTools)
|
||||
implementation(projects.feature.webpTools)
|
||||
implementation(projects.feature.noiseGeneration)
|
||||
implementation(projects.feature.textureGeneration)
|
||||
implementation(projects.feature.collageMaker)
|
||||
implementation(projects.feature.librariesInfo)
|
||||
implementation(projects.feature.markupLayers)
|
||||
implementation(projects.feature.base64Tools)
|
||||
implementation(projects.feature.checksumTools)
|
||||
implementation(projects.feature.meshGradients)
|
||||
implementation(projects.feature.editExif)
|
||||
implementation(projects.feature.imageCutting)
|
||||
implementation(projects.feature.audioCoverExtractor)
|
||||
implementation(projects.feature.libraryDetails)
|
||||
implementation(projects.feature.wallpapersExport)
|
||||
implementation(projects.feature.asciiArt)
|
||||
implementation(projects.feature.aiTools)
|
||||
implementation(projects.feature.colorLibrary)
|
||||
implementation(projects.feature.appLogs)
|
||||
implementation(projects.feature.shaderStudio)
|
||||
implementation(projects.feature.help)
|
||||
implementation(projects.feature.usageStatistics)
|
||||
implementation(projects.feature.batchRename)
|
||||
implementation(projects.feature.duplicateFinder)
|
||||
}
|
||||
@@ -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>
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.provider.ImageToolboxCompositionLocals
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.FileControllerEventsHandler
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.RootDialogs
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.ScreenSelector
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.utils.uiSettingsState
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent
|
||||
|
||||
@Composable
|
||||
fun RootContent(
|
||||
component: RootComponent
|
||||
) {
|
||||
val stack by component.childStack.subscribeAsState()
|
||||
|
||||
ImageToolboxCompositionLocals(
|
||||
settingsState = component.uiSettingsState(),
|
||||
filterPreviewModel = component.filterPreviewModel,
|
||||
canSetDynamicFilterPreview = component.canSetDynamicFilterPreview,
|
||||
currentScreen = stack.items.lastOrNull()?.configuration,
|
||||
onNavigate = component::navigateTo
|
||||
) {
|
||||
ScreenSelector(component)
|
||||
|
||||
RootDialogs(component)
|
||||
|
||||
FileControllerEventsHandler(component)
|
||||
}
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.IntentSender
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.IntentSenderRequest
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.listSaver
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import com.t8rin.imagetoolbox.core.data.saving.FileControllerEvent
|
||||
import com.t8rin.imagetoolbox.core.data.saving.FileControllerEventEmitter
|
||||
import com.t8rin.imagetoolbox.core.resources.Icons
|
||||
import com.t8rin.imagetoolbox.core.resources.R
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.Delete
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost
|
||||
import com.t8rin.imagetoolbox.core.utils.appContext
|
||||
|
||||
@Composable
|
||||
internal fun FileControllerEventsHandler(
|
||||
eventEmitter: FileControllerEventEmitter
|
||||
) {
|
||||
var activeRequestId by rememberSaveable { mutableStateOf<Long?>(null) }
|
||||
var pendingRequests by rememberSaveable(stateSaver = deleteRequestsSaver) {
|
||||
mutableStateOf(emptyList())
|
||||
}
|
||||
val launcher = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.StartIntentSenderForResult()
|
||||
) { result ->
|
||||
activeRequestId?.let { requestId ->
|
||||
eventEmitter.onDeleteOriginalsPermissionResult(
|
||||
requestId = requestId,
|
||||
granted = result.resultCode == Activity.RESULT_OK
|
||||
)
|
||||
}
|
||||
activeRequestId = null
|
||||
}
|
||||
|
||||
LaunchedEffect(eventEmitter) {
|
||||
eventEmitter.events.collect { event ->
|
||||
when (event) {
|
||||
is FileControllerEvent.RequestDeleteOriginalsPermission -> {
|
||||
pendingRequests = pendingRequests + event
|
||||
}
|
||||
|
||||
is FileControllerEvent.OriginalFilesDeleteResult -> {
|
||||
val message = when {
|
||||
event.failed == 0 -> appContext.getString(
|
||||
R.string.original_files_deleted,
|
||||
event.deleted
|
||||
)
|
||||
|
||||
event.deleted == 0 -> appContext.getString(
|
||||
R.string.original_files_delete_failed,
|
||||
event.failed
|
||||
)
|
||||
|
||||
else -> appContext.getString(
|
||||
R.string.original_files_delete_result,
|
||||
event.deleted,
|
||||
event.failed
|
||||
)
|
||||
}
|
||||
AppToastHost.showToast(
|
||||
message = message,
|
||||
icon = Icons.Outlined.Delete
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(activeRequestId, pendingRequests, launcher) {
|
||||
if (activeRequestId == null) {
|
||||
pendingRequests.firstOrNull()?.let { event ->
|
||||
pendingRequests = pendingRequests.drop(1)
|
||||
activeRequestId = event.requestId
|
||||
launcher.launch(
|
||||
IntentSenderRequest.Builder(event.intentSender).build()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val deleteRequestsSaver = listSaver(
|
||||
save = { requests ->
|
||||
requests.flatMap { request ->
|
||||
listOf(request.requestId, request.intentSender, request.count)
|
||||
}
|
||||
},
|
||||
restore = { values ->
|
||||
values.chunked(3).map { request ->
|
||||
FileControllerEvent.RequestDeleteOriginalsPermission(
|
||||
requestId = request[0] as Long,
|
||||
intentSender = request[1] as IntentSender,
|
||||
count = request[2] as Int
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalEditPresetsController
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.Clipboard
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.ReviewHandler
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.sheets.ProcessImagesPreferenceSheet
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.sheets.UpdateSheet
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.AppExitDialog
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.EditPresetsSheet
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.FirstLaunchSetupDialog
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.GithubReviewDialog
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.PermissionDialog
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs.TelegramGroupDialog
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.utils.HandleLookForUpdates
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.utils.SuccessRestoreBackupToastHandler
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent
|
||||
import com.t8rin.imagetoolbox.feature.settings.presentation.components.additional.DonateDialog
|
||||
|
||||
@Composable
|
||||
internal fun RootDialogs(component: RootComponent) {
|
||||
val editPresetsController = LocalEditPresetsController.current
|
||||
|
||||
AppExitDialog(component)
|
||||
|
||||
EditPresetsSheet(
|
||||
visible = editPresetsController.isVisible,
|
||||
onDismiss = editPresetsController::close,
|
||||
onUpdatePresets = component::setPresets
|
||||
)
|
||||
|
||||
ProcessImagesPreferenceSheet(
|
||||
uris = component.uris ?: emptyList(),
|
||||
extraDataType = component.extraDataType,
|
||||
visible = component.showSelectDialog,
|
||||
onDismiss = component::hideSelectDialog,
|
||||
onNavigate = { screen ->
|
||||
component.navigateTo(screen)
|
||||
Clipboard.clear()
|
||||
}
|
||||
)
|
||||
|
||||
UpdateSheet(
|
||||
tag = component.tag,
|
||||
changelog = component.changelog,
|
||||
visible = component.showUpdateDialog,
|
||||
onDismiss = component::cancelledUpdate
|
||||
)
|
||||
|
||||
FirstLaunchSetupDialog(
|
||||
toggleShowUpdateDialog = component::toggleShowUpdateDialog,
|
||||
toggleAllowBetas = component::toggleAllowBetas,
|
||||
adjustPerformance = component::adjustPerformance
|
||||
)
|
||||
|
||||
DonateDialog(
|
||||
onRegisterDonateDialogOpen = component::registerDonateDialogOpen,
|
||||
onNotShowDonateDialogAgain = component::notShowDonateDialogAgain
|
||||
)
|
||||
|
||||
PermissionDialog()
|
||||
|
||||
GithubReviewDialog(
|
||||
visible = component.showGithubReviewDialog,
|
||||
onDismiss = component::hideReviewDialog,
|
||||
onNotShowAgain = ReviewHandler.current::notShowReviewAgain,
|
||||
isNotShowAgainButtonVisible = ReviewHandler.current.showNotShowAgainButton
|
||||
)
|
||||
|
||||
TelegramGroupDialog(
|
||||
visible = component.showTelegramGroupDialog,
|
||||
onDismiss = component::hideTelegramGroupDialog,
|
||||
onRedirected = component::registerTelegramGroupOpen
|
||||
)
|
||||
|
||||
SuccessRestoreBackupToastHandler(component)
|
||||
|
||||
HandleLookForUpdates(component)
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.arkivanov.decompose.extensions.compose.stack.Children
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.animation.toolboxPredictiveBackAnimation
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.provider.LocalCurrentScreen
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.utils.ResetThemeOnGoBack
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.utils.ScreenBasedMaxBrightnessEnforcement
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent
|
||||
|
||||
@Composable
|
||||
internal fun ScreenSelector(
|
||||
component: RootComponent
|
||||
) {
|
||||
ResetThemeOnGoBack(component)
|
||||
|
||||
val childStack by component.childStack.subscribeAsState()
|
||||
val currentScreen = LocalCurrentScreen.current
|
||||
|
||||
SettingsBackdropWrapper(
|
||||
currentScreen = currentScreen,
|
||||
concealBackdropFlow = component.concealBackdropFlow,
|
||||
settingsComponent = component.settingsComponent,
|
||||
children = {
|
||||
Children(
|
||||
stack = childStack,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
animation = remember(component) {
|
||||
toolboxPredictiveBackAnimation(
|
||||
backHandler = component.backHandler,
|
||||
onBack = component::navigateBack
|
||||
)
|
||||
},
|
||||
content = { child ->
|
||||
child.instance.Content()
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
ScreenBasedMaxBrightnessEnforcement(currentScreen)
|
||||
}
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components
|
||||
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.navigationBars
|
||||
import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
|
||||
import androidx.compose.material.BackdropScaffold
|
||||
import androidx.compose.material.BackdropValue
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.rememberBackdropScaffoldState
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.drawWithContent
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.t8rin.gesture.detectPointerTransformGestures
|
||||
import com.t8rin.imagetoolbox.core.settings.domain.model.FastSettingsSide
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.animation.FancyTransitionEasing
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.PredictiveBackObserver
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.provider.LocalScreenSize
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalSheetDragHandle
|
||||
import com.t8rin.imagetoolbox.feature.settings.presentation.SettingsContent
|
||||
import com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
|
||||
@Composable
|
||||
internal fun SettingsBackdropWrapper(
|
||||
currentScreen: Screen?,
|
||||
concealBackdropFlow: Flow<Boolean>,
|
||||
settingsComponent: SettingsComponent,
|
||||
children: @Composable () -> Unit
|
||||
) {
|
||||
val scaffoldState = rememberBackdropScaffoldState(
|
||||
initialValue = BackdropValue.Concealed,
|
||||
animationSpec = tween(
|
||||
durationMillis = 400,
|
||||
easing = FancyTransitionEasing
|
||||
)
|
||||
)
|
||||
val canExpandSettings = ((currentScreen?.id ?: -1) >= 0)
|
||||
.and(settingsComponent.settingsState.fastSettingsSide != FastSettingsSide.None)
|
||||
|
||||
var predictiveBackProgress by remember {
|
||||
mutableFloatStateOf(0f)
|
||||
}
|
||||
val animatedPredictiveBackProgress by animateFloatAsState(predictiveBackProgress)
|
||||
|
||||
val clean = {
|
||||
predictiveBackProgress = 0f
|
||||
}
|
||||
|
||||
LaunchedEffect(canExpandSettings) {
|
||||
if (!canExpandSettings) {
|
||||
clean()
|
||||
scaffoldState.conceal()
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(concealBackdropFlow) {
|
||||
concealBackdropFlow
|
||||
.debounce(200)
|
||||
.collectLatest {
|
||||
if (it) {
|
||||
clean()
|
||||
scaffoldState.conceal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val isTargetRevealed = scaffoldState.targetValue == BackdropValue.Revealed
|
||||
val gridState = rememberLazyStaggeredGridState()
|
||||
|
||||
BackdropScaffold(
|
||||
scaffoldState = scaffoldState,
|
||||
appBar = {},
|
||||
frontLayerContent = {
|
||||
val alpha by animateFloatAsState(
|
||||
if (isTargetRevealed) 1f else 0f
|
||||
)
|
||||
val color = MaterialTheme.colorScheme.surfaceContainerHigh.copy(alpha / 2f)
|
||||
var isWantOpenSettings by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.drawWithContent {
|
||||
drawContent()
|
||||
drawRect(color)
|
||||
}
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.pointerInput(isWantOpenSettings) {
|
||||
detectPointerTransformGestures(
|
||||
consume = false,
|
||||
onGestureEnd = {},
|
||||
onGestureStart = {
|
||||
isWantOpenSettings = false
|
||||
},
|
||||
onGesture = { _, _, _, _, _, _ -> }
|
||||
)
|
||||
},
|
||||
content = {
|
||||
children()
|
||||
|
||||
if (isTargetRevealed || scaffoldState.isRevealed) {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = Color.Transparent
|
||||
) {}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
SettingsOpenButton(
|
||||
isWantOpenSettings = isWantOpenSettings,
|
||||
onStateChange = { isWantOpenSettings = it },
|
||||
scaffoldState = scaffoldState,
|
||||
canExpandSettings = canExpandSettings
|
||||
)
|
||||
|
||||
val progress = scaffoldState.progress(
|
||||
from = BackdropValue.Revealed,
|
||||
to = BackdropValue.Concealed
|
||||
) * 20f
|
||||
|
||||
EnhancedModalSheetDragHandle(
|
||||
color = Color.Transparent,
|
||||
drawStroke = false,
|
||||
bendAngle = (-15f * (1f - progress)).coerceAtMost(0f),
|
||||
modifier = Modifier.alpha(alpha)
|
||||
)
|
||||
}
|
||||
},
|
||||
backLayerContent = {
|
||||
if (canExpandSettings && (scaffoldState.isRevealed || isTargetRevealed)) {
|
||||
PredictiveBackObserver(
|
||||
onProgress = {
|
||||
predictiveBackProgress = it * 1.3f
|
||||
},
|
||||
onClean = { isCompleted ->
|
||||
if (isCompleted) scaffoldState.conceal()
|
||||
clean()
|
||||
},
|
||||
enabled = isTargetRevealed
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(LocalScreenSize.current.height)
|
||||
.alpha(1f - animatedPredictiveBackProgress)
|
||||
) {
|
||||
SettingsContent(
|
||||
component = settingsComponent,
|
||||
gridState = gridState
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
peekHeight = 0.dp,
|
||||
headerHeight = 48.dp + WindowInsets.navigationBars.asPaddingValues()
|
||||
.calculateBottomPadding(),
|
||||
persistentAppBar = false,
|
||||
frontLayerElevation = 0.dp,
|
||||
backLayerBackgroundColor = MaterialTheme.colorScheme.surface,
|
||||
frontLayerBackgroundColor = MaterialTheme.colorScheme.surface,
|
||||
frontLayerScrimColor = Color.Transparent,
|
||||
frontLayerShape = RectangleShape,
|
||||
gesturesEnabled = scaffoldState.isRevealed
|
||||
)
|
||||
}
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.Spring
|
||||
import androidx.compose.animation.core.VisibilityThreshold
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.core.spring
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.scaleIn
|
||||
import androidx.compose.animation.scaleOut
|
||||
import androidx.compose.foundation.indication
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.calculateEndPadding
|
||||
import androidx.compose.foundation.layout.calculateStartPadding
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material.BackdropScaffoldState
|
||||
import androidx.compose.material.Icon
|
||||
import com.t8rin.imagetoolbox.core.resources.Icons
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.Settings
|
||||
import com.t8rin.imagetoolbox.core.settings.domain.model.FastSettingsSide
|
||||
import com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState
|
||||
import com.t8rin.imagetoolbox.core.ui.theme.blend
|
||||
import com.t8rin.imagetoolbox.core.ui.theme.takeColorFromScheme
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.animation.springySpec
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.rememberRipple
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.hapticsClickable
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.modifier.AutoCornersShape
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.modifier.animateShape
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.modifier.container
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
internal fun BoxScope.SettingsOpenButton(
|
||||
isWantOpenSettings: Boolean,
|
||||
onStateChange: (Boolean) -> Unit,
|
||||
scaffoldState: BackdropScaffoldState,
|
||||
canExpandSettings: Boolean
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
val fastSettingsSide = LocalSettingsState.current.fastSettingsSide
|
||||
val alignment = if (fastSettingsSide == FastSettingsSide.CenterStart) {
|
||||
Alignment.CenterStart
|
||||
} else {
|
||||
Alignment.CenterEnd
|
||||
}
|
||||
|
||||
val direction = LocalLayoutDirection.current
|
||||
val paddingValues = WindowInsets.safeDrawing.asPaddingValues()
|
||||
val (startPadding, endPadding) = remember(paddingValues, direction) {
|
||||
derivedStateOf {
|
||||
paddingValues.calculateStartPadding(direction) to paddingValues.calculateEndPadding(
|
||||
direction
|
||||
)
|
||||
}
|
||||
}.value
|
||||
|
||||
val expandedPart = if (isWantOpenSettings) 12.dp else 42.dp
|
||||
val cornerRadius = expandedPart.coerceAtLeast(4.dp)
|
||||
|
||||
val shape = animateShape(
|
||||
targetValue = key(cornerRadius) {
|
||||
if (fastSettingsSide == FastSettingsSide.CenterStart) {
|
||||
if (startPadding == 0.dp) {
|
||||
AutoCornersShape(
|
||||
topEnd = cornerRadius,
|
||||
bottomEnd = cornerRadius
|
||||
)
|
||||
} else {
|
||||
AutoCornersShape(cornerRadius)
|
||||
}
|
||||
} else {
|
||||
if (endPadding == 0.dp) {
|
||||
AutoCornersShape(
|
||||
topStart = cornerRadius,
|
||||
bottomStart = cornerRadius
|
||||
)
|
||||
} else {
|
||||
AutoCornersShape(cornerRadius)
|
||||
}
|
||||
}
|
||||
},
|
||||
animationSpec = spring(
|
||||
dampingRatio = 0.5f,
|
||||
stiffness = Spring.StiffnessLow
|
||||
)
|
||||
)
|
||||
|
||||
val height by animateDpAsState(
|
||||
targetValue = if (isWantOpenSettings) 64.dp else 104.dp
|
||||
)
|
||||
val width by animateDpAsState(
|
||||
targetValue = if (isWantOpenSettings) 48.dp else 24.dp,
|
||||
animationSpec = springySpec()
|
||||
)
|
||||
val xOffset by animateDpAsState(
|
||||
targetValue = if (!canExpandSettings) {
|
||||
if (fastSettingsSide == FastSettingsSide.CenterStart) {
|
||||
-width
|
||||
} else {
|
||||
width
|
||||
}
|
||||
} else {
|
||||
0.dp
|
||||
},
|
||||
animationSpec = spring(
|
||||
visibilityThreshold = Dp.VisibilityThreshold,
|
||||
dampingRatio = Spring.DampingRatioMediumBouncy,
|
||||
stiffness = Spring.StiffnessLow
|
||||
)
|
||||
)
|
||||
val alpha by animateFloatAsState(
|
||||
targetValue = if (canExpandSettings) 1f else 0f,
|
||||
animationSpec = tween(650)
|
||||
)
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
|
||||
Surface(
|
||||
color = Color.Transparent,
|
||||
modifier = Modifier
|
||||
.align(alignment)
|
||||
.padding(
|
||||
start = startPadding,
|
||||
end = endPadding
|
||||
)
|
||||
.size(
|
||||
height = height,
|
||||
width = width
|
||||
)
|
||||
.hapticsClickable(
|
||||
enabled = canExpandSettings,
|
||||
indication = null,
|
||||
interactionSource = interactionSource
|
||||
) {
|
||||
if (isWantOpenSettings) {
|
||||
scope.launch {
|
||||
scaffoldState.reveal()
|
||||
onStateChange(false)
|
||||
}
|
||||
} else {
|
||||
onStateChange(true)
|
||||
}
|
||||
}
|
||||
.alpha(alpha)
|
||||
.offset {
|
||||
IntOffset(
|
||||
x = xOffset.roundToPx(),
|
||||
y = 0
|
||||
)
|
||||
}
|
||||
) {
|
||||
Box {
|
||||
val width by animateDpAsState(
|
||||
targetValue = if (isWantOpenSettings) 48.dp else 4.dp,
|
||||
animationSpec = spring(
|
||||
dampingRatio = 0.35f,
|
||||
stiffness = Spring.StiffnessLow
|
||||
)
|
||||
)
|
||||
|
||||
val containerColor = takeColorFromScheme {
|
||||
tertiary.blend(primary, 0.65f)
|
||||
}
|
||||
|
||||
val contentColor = takeColorFromScheme {
|
||||
onTertiary.blend(onPrimary, 0.8f)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(alignment)
|
||||
.width(width)
|
||||
.height(64.dp)
|
||||
.container(
|
||||
shape = shape,
|
||||
resultPadding = 0.dp,
|
||||
color = containerColor
|
||||
)
|
||||
.indication(
|
||||
interactionSource = interactionSource,
|
||||
indication = rememberRipple(contentColor = contentColor)
|
||||
),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = isWantOpenSettings,
|
||||
enter = fadeIn() + scaleIn(
|
||||
animationSpec = spring(
|
||||
dampingRatio = 0.35f,
|
||||
stiffness = Spring.StiffnessLow
|
||||
)
|
||||
),
|
||||
exit = fadeOut() + scaleOut()
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.Settings,
|
||||
contentDescription = null,
|
||||
tint = contentColor
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs
|
||||
|
||||
import android.os.Build
|
||||
import androidx.activity.compose.BackHandler
|
||||
import com.t8rin.imagetoolbox.core.resources.Icons
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import com.t8rin.imagetoolbox.core.resources.R
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.DoorBack
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.provider.LocalCurrentScreen
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent
|
||||
|
||||
|
||||
@Composable
|
||||
internal fun AppExitDialog(component: RootComponent) {
|
||||
val currentScreen = LocalCurrentScreen.current
|
||||
|
||||
if (currentScreen is Screen.Main) {
|
||||
val context = LocalComponentActivity.current
|
||||
|
||||
var showExitDialog by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
val tiramisu = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
|
||||
BackHandler(enabled = !tiramisu) {
|
||||
if (component.shouldShowDialog) showExitDialog = true
|
||||
else context.finishAffinity()
|
||||
}
|
||||
|
||||
AppExitDialogImpl(
|
||||
onDismiss = { showExitDialog = false },
|
||||
visible = showExitDialog && !tiramisu
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AppExitDialogImpl(
|
||||
onDismiss: () -> Unit,
|
||||
visible: Boolean
|
||||
) {
|
||||
val activity = LocalComponentActivity.current
|
||||
|
||||
EnhancedAlertDialog(
|
||||
visible = visible,
|
||||
onDismissRequest = onDismiss,
|
||||
dismissButton = {
|
||||
EnhancedButton(
|
||||
containerColor = MaterialTheme.colorScheme.secondaryContainer,
|
||||
onClick = activity::finishAffinity
|
||||
) {
|
||||
Text(stringResource(R.string.close))
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
EnhancedButton(onClick = onDismiss) {
|
||||
Text(stringResource(R.string.stay))
|
||||
}
|
||||
},
|
||||
title = { Text(stringResource(R.string.app_closing)) },
|
||||
text = {
|
||||
Text(
|
||||
stringResource(R.string.app_closing_sub),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
},
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.DoorBack,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import com.t8rin.imagetoolbox.core.resources.Icons
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.text.isDigitsOnly
|
||||
import com.t8rin.imagetoolbox.core.resources.R
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.AddCircle
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.LabelPercent
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.PhotoSizeSelectSmall
|
||||
import com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState
|
||||
import com.t8rin.imagetoolbox.core.ui.theme.outlineVariant
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedChip
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedModalBottomSheet
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.text.AutoSizeText
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.text.TitleItem
|
||||
|
||||
@Composable
|
||||
internal fun EditPresetsSheet(
|
||||
visible: Boolean,
|
||||
onDismiss: () -> Unit,
|
||||
onUpdatePresets: (List<Int>) -> Unit
|
||||
) {
|
||||
val settingsState = LocalSettingsState.current
|
||||
EnhancedModalBottomSheet(
|
||||
visible = visible,
|
||||
onDismiss = {
|
||||
if (!it) onDismiss()
|
||||
},
|
||||
title = {
|
||||
TitleItem(
|
||||
text = stringResource(R.string.presets),
|
||||
icon = Icons.Rounded.LabelPercent
|
||||
)
|
||||
},
|
||||
sheetContent = {
|
||||
val data = settingsState.presets
|
||||
Box {
|
||||
AnimatedContent(
|
||||
targetState = data,
|
||||
transitionSpec = { fadeIn() togetherWith fadeOut() },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.enhancedVerticalScroll(rememberScrollState())
|
||||
) { list ->
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
FlowRow(
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
8.dp,
|
||||
Alignment.CenterHorizontally
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically)
|
||||
) {
|
||||
list.forEach {
|
||||
EnhancedChip(
|
||||
onClick = {
|
||||
onUpdatePresets(list - it)
|
||||
},
|
||||
selected = false,
|
||||
selectedColor = MaterialTheme.colorScheme.primary,
|
||||
shape = MaterialTheme.shapes.medium
|
||||
) {
|
||||
AutoSizeText(it.toString())
|
||||
}
|
||||
}
|
||||
EnhancedChip(
|
||||
onClick = {
|
||||
expanded = true
|
||||
},
|
||||
selected = false,
|
||||
selectedColor = MaterialTheme.colorScheme.primary,
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
label = {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.AddCircle,
|
||||
contentDescription = stringResource(R.string.add)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var value by remember(expanded) { mutableStateOf("") }
|
||||
EnhancedAlertDialog(
|
||||
visible = expanded,
|
||||
onDismissRequest = { expanded = false },
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.PhotoSizeSelectSmall,
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(stringResource(R.string.presets))
|
||||
},
|
||||
text = {
|
||||
OutlinedTextField(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
shape = ShapeDefaults.default,
|
||||
value = value,
|
||||
textStyle = MaterialTheme.typography.titleMedium.copy(
|
||||
textAlign = TextAlign.Center
|
||||
),
|
||||
maxLines = 1,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Number
|
||||
),
|
||||
onValueChange = {
|
||||
if (it.isDigitsOnly()) {
|
||||
value = it.toIntOrNull()?.coerceAtMost(500)?.toString()
|
||||
?: ""
|
||||
}
|
||||
},
|
||||
placeholder = {
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(R.string.enter_percent),
|
||||
style = MaterialTheme.typography.titleMedium.copy(
|
||||
textAlign = TextAlign.Center
|
||||
),
|
||||
color = LocalContentColor.current.copy(0.5f)
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
EnhancedButton(
|
||||
containerColor = MaterialTheme.colorScheme.secondaryContainer,
|
||||
onClick = {
|
||||
onUpdatePresets(
|
||||
list + (value.toIntOrNull() ?: 0)
|
||||
)
|
||||
expanded = false
|
||||
},
|
||||
enabled = value.isNotEmpty()
|
||||
) {
|
||||
Text(stringResource(R.string.add))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
EnhancedButton(
|
||||
onClick = onDismiss,
|
||||
borderColor = MaterialTheme.colorScheme.outlineVariant(),
|
||||
containerColor = MaterialTheme.colorScheme.secondaryContainer,
|
||||
) {
|
||||
AutoSizeText(stringResource(R.string.close))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ProvideTextStyle
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.t8rin.imagetoolbox.core.domain.model.PerformanceClass
|
||||
import com.t8rin.imagetoolbox.core.domain.utils.Flavor
|
||||
import com.t8rin.imagetoolbox.core.resources.Icons
|
||||
import com.t8rin.imagetoolbox.core.resources.R
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.Beta
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.MobileArrowDown
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.ReleaseAlert
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.Webhook
|
||||
import com.t8rin.imagetoolbox.core.settings.presentation.model.isFirstLaunch
|
||||
import com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.isInstalledFromPlayStore
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.performanceClass
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.enhancedVerticalScroll
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.modifier.ShapeDefaults
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.modifier.fadingEdges
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceItem
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.preferences.PreferenceRowSwitch
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.saver.OneTimeEffect
|
||||
import com.t8rin.imagetoolbox.core.utils.appContext
|
||||
|
||||
@Composable
|
||||
internal fun FirstLaunchSetupDialog(
|
||||
toggleAllowBetas: () -> Unit,
|
||||
toggleShowUpdateDialog: () -> Unit,
|
||||
adjustPerformance: (PerformanceClass) -> Unit
|
||||
) {
|
||||
val settingsState = LocalSettingsState.current
|
||||
var updateOnFirstOpen by rememberSaveable {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
OneTimeEffect {
|
||||
updateOnFirstOpen = settingsState.isFirstLaunch(false)
|
||||
adjustPerformance(appContext.performanceClass)
|
||||
}
|
||||
|
||||
EnhancedAlertDialog(
|
||||
visible = updateOnFirstOpen,
|
||||
onDismissRequest = {},
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.MobileArrowDown,
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(stringResource(R.string.updates))
|
||||
},
|
||||
text = {
|
||||
val state = rememberScrollState()
|
||||
ProvideTextStyle(value = LocalTextStyle.current.copy(textAlign = TextAlign.Left)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fadingEdges(
|
||||
isVertical = true,
|
||||
scrollableState = state,
|
||||
scrollFactor = 1.1f
|
||||
)
|
||||
.enhancedVerticalScroll(state)
|
||||
.padding(2.dp)
|
||||
) {
|
||||
if (Flavor.isFoss()) {
|
||||
PreferenceItem(
|
||||
title = stringResource(id = R.string.attention),
|
||||
subtitle = stringResource(R.string.foss_update_checker_warning),
|
||||
startIcon = Icons.Rounded.Webhook,
|
||||
shape = ShapeDefaults.default,
|
||||
modifier = Modifier.padding(bottom = 8.dp),
|
||||
containerColor = MaterialTheme.colorScheme.surfaceContainerHighest
|
||||
)
|
||||
}
|
||||
PreferenceRowSwitch(
|
||||
shape = if (!appContext.isInstalledFromPlayStore()) {
|
||||
ShapeDefaults.top
|
||||
} else ShapeDefaults.default,
|
||||
modifier = Modifier,
|
||||
title = stringResource(R.string.check_updates),
|
||||
subtitle = stringResource(R.string.check_updates_sub),
|
||||
checked = settingsState.showUpdateDialogOnStartup,
|
||||
onClick = {
|
||||
toggleShowUpdateDialog()
|
||||
},
|
||||
startIcon = Icons.Rounded.ReleaseAlert
|
||||
)
|
||||
if (!appContext.isInstalledFromPlayStore()) {
|
||||
Spacer(Modifier.height(4.dp))
|
||||
PreferenceRowSwitch(
|
||||
modifier = Modifier,
|
||||
shape = ShapeDefaults.bottom,
|
||||
title = stringResource(R.string.allow_betas),
|
||||
subtitle = stringResource(R.string.allow_betas_sub),
|
||||
checked = settingsState.allowBetas,
|
||||
onClick = {
|
||||
toggleAllowBetas()
|
||||
},
|
||||
startIcon = Icons.Rounded.Beta
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
EnhancedButton(
|
||||
onClick = { updateOnFirstOpen = false }
|
||||
) {
|
||||
Text(stringResource(id = R.string.ok))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs
|
||||
|
||||
import com.t8rin.imagetoolbox.core.resources.Icons
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.t8rin.imagetoolbox.core.domain.APP_GITHUB_LINK
|
||||
import com.t8rin.imagetoolbox.core.resources.R
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.Star
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton
|
||||
|
||||
@Composable
|
||||
internal fun GithubReviewDialog(
|
||||
visible: Boolean,
|
||||
onDismiss: () -> Unit,
|
||||
isNotShowAgainButtonVisible: Boolean,
|
||||
onNotShowAgain: () -> Unit
|
||||
) {
|
||||
val linkHandler = LocalUriHandler.current
|
||||
EnhancedAlertDialog(
|
||||
visible = visible,
|
||||
onDismissRequest = onDismiss,
|
||||
confirmButton = {
|
||||
EnhancedButton(
|
||||
onClick = {
|
||||
linkHandler.openUri(APP_GITHUB_LINK)
|
||||
}
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.rate))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
EnhancedButton(
|
||||
containerColor = MaterialTheme.colorScheme.secondaryContainer,
|
||||
onClick = {
|
||||
if (isNotShowAgainButtonVisible) onNotShowAgain()
|
||||
|
||||
onDismiss()
|
||||
}
|
||||
) {
|
||||
Text(stringResource(id = R.string.close))
|
||||
}
|
||||
},
|
||||
title = {
|
||||
Text(stringResource(R.string.rate_app))
|
||||
},
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.Star,
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(R.string.rate_app_sub))
|
||||
}
|
||||
)
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs
|
||||
|
||||
import android.Manifest
|
||||
import android.os.Build
|
||||
import com.t8rin.imagetoolbox.core.resources.Icons
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.core.app.ActivityCompat
|
||||
import com.t8rin.imagetoolbox.core.resources.R
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.Storage
|
||||
import com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.needToShowStoragePermissionRequest
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.ContextUtils.requestStoragePermission
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.permission.PermissionUtils.hasPermissionAllowed
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.provider.rememberCurrentLifecycleEvent
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@Composable
|
||||
internal fun PermissionDialog() {
|
||||
val context = LocalComponentActivity.current
|
||||
val settingsState = LocalSettingsState.current
|
||||
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
|
||||
val currentLifecycleEvent = rememberCurrentLifecycleEvent()
|
||||
LaunchedEffect(
|
||||
showDialog,
|
||||
context,
|
||||
settingsState,
|
||||
currentLifecycleEvent
|
||||
) {
|
||||
showDialog = context.needToShowStoragePermissionRequest() == true
|
||||
while (showDialog) {
|
||||
showDialog = context.needToShowStoragePermissionRequest() == true
|
||||
delay(100)
|
||||
}
|
||||
}
|
||||
|
||||
var requestedOnce by rememberSaveable {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !requestedOnce) {
|
||||
val notAllowed = listOf(
|
||||
Manifest.permission.ACCESS_MEDIA_LOCATION,
|
||||
Manifest.permission.POST_NOTIFICATIONS
|
||||
).filter { !context.hasPermissionAllowed(it) }
|
||||
|
||||
if (notAllowed.isNotEmpty()) {
|
||||
ActivityCompat.requestPermissions(
|
||||
context,
|
||||
buildList {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
add(Manifest.permission.READ_MEDIA_IMAGES)
|
||||
}
|
||||
addAll(notAllowed)
|
||||
}.toTypedArray(),
|
||||
0
|
||||
)
|
||||
}
|
||||
requestedOnce = true
|
||||
}
|
||||
}
|
||||
|
||||
EnhancedAlertDialog(
|
||||
visible = showDialog,
|
||||
onDismissRequest = { },
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.Storage,
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
title = { Text(stringResource(R.string.permission)) },
|
||||
text = {
|
||||
Text(stringResource(R.string.permission_sub))
|
||||
},
|
||||
confirmButton = {
|
||||
EnhancedButton(
|
||||
onClick = {
|
||||
context.requestStoragePermission()
|
||||
}
|
||||
) {
|
||||
Text(stringResource(id = R.string.grant))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.dialogs
|
||||
|
||||
import com.t8rin.imagetoolbox.core.resources.Icons
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.t8rin.imagetoolbox.core.domain.TELEGRAM_CHANNEL_LINK
|
||||
import com.t8rin.imagetoolbox.core.domain.TELEGRAM_GROUP_LINK
|
||||
import com.t8rin.imagetoolbox.core.resources.R
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.Cancel
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.Telegram
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedAlertDialog
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedButton
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.enhanced.EnhancedIconButton
|
||||
|
||||
@Composable
|
||||
fun TelegramGroupDialog(
|
||||
visible: Boolean,
|
||||
onDismiss: () -> Unit,
|
||||
onRedirected: () -> Unit
|
||||
) {
|
||||
val linkHandler = LocalUriHandler.current
|
||||
EnhancedAlertDialog(
|
||||
visible = visible,
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.Telegram,
|
||||
contentDescription = "Telegram"
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(stringResource(R.string.image_toolbox_in_telegram))
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(R.string.image_toolbox_in_telegram_sub))
|
||||
},
|
||||
confirmButton = {
|
||||
EnhancedButton(
|
||||
onClick = {
|
||||
onRedirected()
|
||||
linkHandler.openUri(TELEGRAM_GROUP_LINK)
|
||||
}
|
||||
) {
|
||||
Text(stringResource(R.string.group))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
EnhancedIconButton(
|
||||
onClick = {
|
||||
onRedirected()
|
||||
},
|
||||
containerColor = MaterialTheme.colorScheme.errorContainer,
|
||||
contentColor = MaterialTheme.colorScheme.onErrorContainer
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Rounded.Cancel,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
EnhancedButton(
|
||||
onClick = {
|
||||
onRedirected()
|
||||
linkHandler.openUri(TELEGRAM_CHANNEL_LINK)
|
||||
},
|
||||
containerColor = MaterialTheme.colorScheme.tertiaryContainer
|
||||
) {
|
||||
Text(stringResource(R.string.ci_channel))
|
||||
}
|
||||
},
|
||||
onDismissRequest = onDismiss
|
||||
)
|
||||
}
|
||||
+985
@@ -0,0 +1,985 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.navigation
|
||||
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import com.t8rin.imagetoolbox.collage_maker.presentation.screenLogic.CollageMakerComponent
|
||||
import com.t8rin.imagetoolbox.color_library.presentation.screenLogic.ColorLibraryComponent
|
||||
import com.t8rin.imagetoolbox.color_tools.presentation.screenLogic.ColorToolsComponent
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen
|
||||
import com.t8rin.imagetoolbox.feature.ai_tools.presentation.screenLogic.AiToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.apng_tools.presentation.screenLogic.ApngToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.ascii_art.presentation.screenLogic.AsciiArtComponent
|
||||
import com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui.screenLogic.AudioCoverExtractorComponent
|
||||
import com.t8rin.imagetoolbox.feature.base64_tools.presentation.screenLogic.Base64ToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.batchrename.presentation.screenLogic.BatchRenameComponent
|
||||
import com.t8rin.imagetoolbox.feature.checksum_tools.presentation.screenLogic.ChecksumToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.cipher.presentation.screenLogic.CipherComponent
|
||||
import com.t8rin.imagetoolbox.feature.compare.presentation.screenLogic.CompareComponent
|
||||
import com.t8rin.imagetoolbox.feature.crop.presentation.screenLogic.CropComponent
|
||||
import com.t8rin.imagetoolbox.feature.delete_exif.presentation.screenLogic.DeleteExifComponent
|
||||
import com.t8rin.imagetoolbox.feature.document_scanner.presentation.screenLogic.DocumentScannerComponent
|
||||
import com.t8rin.imagetoolbox.feature.draw.presentation.screenLogic.DrawComponent
|
||||
import com.t8rin.imagetoolbox.feature.duplicate_finder.presentation.screenLogic.DuplicateFinderComponent
|
||||
import com.t8rin.imagetoolbox.feature.easter_egg.presentation.screenLogic.EasterEggComponent
|
||||
import com.t8rin.imagetoolbox.feature.edit_exif.presentation.screenLogic.EditExifComponent
|
||||
import com.t8rin.imagetoolbox.feature.erase_background.presentation.screenLogic.EraseBackgroundComponent
|
||||
import com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic.FiltersComponent
|
||||
import com.t8rin.imagetoolbox.feature.format_conversion.presentation.screenLogic.FormatConversionComponent
|
||||
import com.t8rin.imagetoolbox.feature.gif_tools.presentation.screenLogic.GifToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent
|
||||
import com.t8rin.imagetoolbox.feature.help.presentation.screenLogic.HelpComponent
|
||||
import com.t8rin.imagetoolbox.feature.image_preview.presentation.screenLogic.ImagePreviewComponent
|
||||
import com.t8rin.imagetoolbox.feature.image_stacking.presentation.screenLogic.ImageStackingComponent
|
||||
import com.t8rin.imagetoolbox.feature.image_stitch.presentation.screenLogic.ImageStitchingComponent
|
||||
import com.t8rin.imagetoolbox.feature.jxl_tools.presentation.screenLogic.JxlToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.libraries_info.presentation.screenLogic.LibrariesInfoComponent
|
||||
import com.t8rin.imagetoolbox.feature.limits_resize.presentation.screenLogic.LimitsResizeComponent
|
||||
import com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent
|
||||
import com.t8rin.imagetoolbox.feature.main.presentation.screenLogic.MainComponent
|
||||
import com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent
|
||||
import com.t8rin.imagetoolbox.feature.mesh_gradients.presentation.screenLogic.MeshGradientsComponent
|
||||
import com.t8rin.imagetoolbox.feature.palette_tools.presentation.screenLogic.PaletteToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.compress.screenLogic.CompressPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop.screenLogic.CropPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_images.screenLogic.ExtractImagesPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_pages.screenLogic.ExtractPagesPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.flatten.screenLogic.FlattenPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.grayscale.screenLogic.GrayscalePdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.images_to_pdf.screenLogic.ImagesToPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.merge.screenLogic.MergePdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata.screenLogic.MetadataPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.ocr.screenLogic.OCRPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers.screenLogic.PageNumbersPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.preview.screenLogic.PreviewPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.print.screenLogic.PrintPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.protect.screenLogic.ProtectPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.screenLogic.RearrangePdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.screenLogic.RemoveAnnotationsPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages.screenLogic.RemovePagesPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.repair.screenLogic.RepairPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.screenLogic.RootPdfToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate.screenLogic.RotatePdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.screenLogic.SignaturePdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.split.screenLogic.SplitPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.unlock.screenLogic.UnlockPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark.screenLogic.WatermarkPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.zip_convert.screenLogic.ZipConvertPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pick_color.presentation.screenLogic.PickColorFromImageComponent
|
||||
import com.t8rin.imagetoolbox.feature.recognize.text.presentation.screenLogic.RecognizeTextComponent
|
||||
import com.t8rin.imagetoolbox.feature.resize_convert.presentation.screenLogic.ResizeAndConvertComponent
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.AiTools
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ApngTools
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.AppLogs
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.AsciiArt
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.AudioCoverExtractor
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Base64Tools
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.BatchRename
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ChecksumTools
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Cipher
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.CollageMaker
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ColorLibrary
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ColorTools
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Compare
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.CompressPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Crop
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.CropPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.DeleteExif
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.DocumentScanner
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Draw
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.DuplicateFinder
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.EasterEgg
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.EditExif
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.EraseBackground
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ExtractImagesPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ExtractPagesPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Filter
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.FlattenPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.FormatConversion
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.GifTools
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.GradientMaker
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.GrayscalePdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Help
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImageCutter
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImagePreview
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImageSplitting
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImageStacking
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImageStitching
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ImagesToPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.JxlTools
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.LibrariesInfo
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.LibraryDetails
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.LimitResize
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.LoadNetImage
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Main
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.MarkupLayers
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.MergePdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.MeshGradients
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.MetadataPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.NoiseGeneration
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.OCRPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.PageNumbersPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.PaletteTools
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.PickColorFromImage
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.PreviewPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.PrintPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ProtectPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RearrangePdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RecognizeText
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RemoveAnnotationsPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RemovePagesPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RepairPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ResizeAndConvert
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RootPdfTools
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.RotatePdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ScanQrCode
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Settings
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ShaderStudio
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.SignaturePdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.SingleEdit
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.SplitPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.SvgMaker
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.TextureGeneration
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.UnlockPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.UsageStatistics
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.WallpapersExport
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.WatermarkPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Watermarking
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.WebpTools
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.WeightResize
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.Zip
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild.ZipConvertPdfTool
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent
|
||||
import com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.screenLogic.ScanQrCodeComponent
|
||||
import com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent
|
||||
import com.t8rin.imagetoolbox.feature.shader_studio.presentation.screenLogic.ShaderStudioComponent
|
||||
import com.t8rin.imagetoolbox.feature.single_edit.presentation.screenLogic.SingleEditComponent
|
||||
import com.t8rin.imagetoolbox.feature.svg_maker.presentation.screenLogic.SvgMakerComponent
|
||||
import com.t8rin.imagetoolbox.feature.usage_statistics.presentation.screenLogic.UsageStatisticsComponent
|
||||
import com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.screenLogic.WallpapersExportComponent
|
||||
import com.t8rin.imagetoolbox.feature.watermarking.presentation.screenLogic.WatermarkingComponent
|
||||
import com.t8rin.imagetoolbox.feature.webp_tools.presentation.screenLogic.WebpToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.weight_resize.presentation.screenLogic.WeightResizeComponent
|
||||
import com.t8rin.imagetoolbox.feature.zip.presentation.screenLogic.ZipComponent
|
||||
import com.t8rin.imagetoolbox.image_cutting.presentation.screenLogic.ImageCutterComponent
|
||||
import com.t8rin.imagetoolbox.image_splitting.presentation.screenLogic.ImageSplitterComponent
|
||||
import com.t8rin.imagetoolbox.library_details.presentation.screenLogic.LibraryDetailsComponent
|
||||
import com.t8rin.imagetoolbox.noise_generation.presentation.screenLogic.NoiseGenerationComponent
|
||||
import com.t8rin.imagetoolbox.presentation.app_logs.screenLogic.AppLogsComponent
|
||||
import com.t8rin.imagetoolbox.texture_generation.presentation.screenLogic.TextureGenerationComponent
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class ChildProvider @Inject constructor(
|
||||
private val apngToolsComponentFactory: ApngToolsComponent.Factory,
|
||||
private val cipherComponentFactory: CipherComponent.Factory,
|
||||
private val collageMakerComponentFactory: CollageMakerComponent.Factory,
|
||||
private val compareComponentFactory: CompareComponent.Factory,
|
||||
private val cropComponentFactory: CropComponent.Factory,
|
||||
private val deleteExifComponentFactory: DeleteExifComponent.Factory,
|
||||
private val documentScannerComponentFactory: DocumentScannerComponent.Factory,
|
||||
private val drawComponentFactory: DrawComponent.Factory,
|
||||
private val duplicateFinderComponentFactory: DuplicateFinderComponent.Factory,
|
||||
private val eraseBackgroundComponentFactory: EraseBackgroundComponent.Factory,
|
||||
private val filtersComponentFactory: FiltersComponent.Factory,
|
||||
private val formatConversionComponentFactory: FormatConversionComponent.Factory,
|
||||
private val paletteToolsComponentFactory: PaletteToolsComponent.Factory,
|
||||
private val gifToolsComponentFactory: GifToolsComponent.Factory,
|
||||
private val gradientMakerComponentFactory: GradientMakerComponent.Factory,
|
||||
private val imagePreviewComponentFactory: ImagePreviewComponent.Factory,
|
||||
private val imageSplittingComponentFactory: ImageSplitterComponent.Factory,
|
||||
private val imageStackingComponentFactory: ImageStackingComponent.Factory,
|
||||
private val imageStitchingComponentFactory: ImageStitchingComponent.Factory,
|
||||
private val jxlToolsComponentFactory: JxlToolsComponent.Factory,
|
||||
private val limitResizeComponentFactory: LimitsResizeComponent.Factory,
|
||||
private val loadNetImageComponentFactory: LoadNetImageComponent.Factory,
|
||||
private val noiseGenerationComponentFactory: NoiseGenerationComponent.Factory,
|
||||
private val textureGenerationComponentFactory: TextureGenerationComponent.Factory,
|
||||
private val rootPdfToolsComponentFactory: RootPdfToolsComponent.Factory,
|
||||
private val pickColorFromImageComponentFactory: PickColorFromImageComponent.Factory,
|
||||
private val recognizeTextComponentFactory: RecognizeTextComponent.Factory,
|
||||
private val resizeAndConvertComponentFactory: ResizeAndConvertComponent.Factory,
|
||||
private val scanQrCodeComponentFactory: ScanQrCodeComponent.Factory,
|
||||
private val settingsComponentFactory: SettingsComponent.Factory,
|
||||
private val shaderStudioComponentFactory: ShaderStudioComponent.Factory,
|
||||
private val singleEditComponentFactory: SingleEditComponent.Factory,
|
||||
private val svgMakerComponentFactory: SvgMakerComponent.Factory,
|
||||
private val watermarkingComponentFactory: WatermarkingComponent.Factory,
|
||||
private val webpToolsComponentFactory: WebpToolsComponent.Factory,
|
||||
private val weightResizeComponentFactory: WeightResizeComponent.Factory,
|
||||
private val zipComponentFactory: ZipComponent.Factory,
|
||||
private val easterEggComponentFactory: EasterEggComponent.Factory,
|
||||
private val colorToolsComponentFactory: ColorToolsComponent.Factory,
|
||||
private val librariesInfoComponentFactory: LibrariesInfoComponent.Factory,
|
||||
private val appLogsComponentFactory: AppLogsComponent.Factory,
|
||||
private val usageStatisticsComponentFactory: UsageStatisticsComponent.Factory,
|
||||
private val mainComponentFactory: MainComponent.Factory,
|
||||
private val markupLayersComponentFactory: MarkupLayersComponent.Factory,
|
||||
private val base64ToolsComponentFactory: Base64ToolsComponent.Factory,
|
||||
private val checksumToolsComponentFactory: ChecksumToolsComponent.Factory,
|
||||
private val meshGradientsComponentFactory: MeshGradientsComponent.Factory,
|
||||
private val editExifComponentFactory: EditExifComponent.Factory,
|
||||
private val imageCutterComponentFactory: ImageCutterComponent.Factory,
|
||||
private val audioCoverExtractorComponentFactory: AudioCoverExtractorComponent.Factory,
|
||||
private val libraryDetailsComponentFactory: LibraryDetailsComponent.Factory,
|
||||
private val wallpapersExportComponentFactory: WallpapersExportComponent.Factory,
|
||||
private val asciiArtComponentFactory: AsciiArtComponent.Factory,
|
||||
private val aiToolsComponentFactory: AiToolsComponent.Factory,
|
||||
private val colorLibraryComponentFactory: ColorLibraryComponent.Factory,
|
||||
private val mergePdfToolComponentFactory: MergePdfToolComponent.Factory,
|
||||
private val splitPdfToolComponentFactory: SplitPdfToolComponent.Factory,
|
||||
private val rotatePdfToolComponentFactory: RotatePdfToolComponent.Factory,
|
||||
private val rearrangePdfToolComponentFactory: RearrangePdfToolComponent.Factory,
|
||||
private val pageNumbersPdfToolComponentFactory: PageNumbersPdfToolComponent.Factory,
|
||||
private val ocrPdfToolComponentFactory: OCRPdfToolComponent.Factory,
|
||||
private val watermarkPdfToolComponentFactory: WatermarkPdfToolComponent.Factory,
|
||||
private val signaturePdfToolComponentFactory: SignaturePdfToolComponent.Factory,
|
||||
private val protectPdfToolComponentFactory: ProtectPdfToolComponent.Factory,
|
||||
private val unlockPdfToolComponentFactory: UnlockPdfToolComponent.Factory,
|
||||
private val compressPdfToolComponentFactory: CompressPdfToolComponent.Factory,
|
||||
private val grayscalePdfToolComponentFactory: GrayscalePdfToolComponent.Factory,
|
||||
private val repairPdfToolComponentFactory: RepairPdfToolComponent.Factory,
|
||||
private val metadataPdfToolComponentFactory: MetadataPdfToolComponent.Factory,
|
||||
private val removePagesPdfToolComponentFactory: RemovePagesPdfToolComponent.Factory,
|
||||
private val cropPdfToolComponentFactory: CropPdfToolComponent.Factory,
|
||||
private val flattenPdfToolComponentFactory: FlattenPdfToolComponent.Factory,
|
||||
private val extractImagesPdfToolComponentFactory: ExtractImagesPdfToolComponent.Factory,
|
||||
private val zipConvertPdfToolComponentFactory: ZipConvertPdfToolComponent.Factory,
|
||||
private val printPdfToolComponentFactory: PrintPdfToolComponent.Factory,
|
||||
private val previewPdfToolComponentFactory: PreviewPdfToolComponent.Factory,
|
||||
private val imagesToPdfToolComponentFactory: ImagesToPdfToolComponent.Factory,
|
||||
private val extractPagesPdfToolComponentFactory: ExtractPagesPdfToolComponent.Factory,
|
||||
private val removeAnnotationsPdfToolComponentFactory: RemoveAnnotationsPdfToolComponent.Factory,
|
||||
private val helpComponentFactory: HelpComponent.Factory,
|
||||
private val batchRenameComponentFactory: BatchRenameComponent.Factory,
|
||||
) {
|
||||
fun RootComponent.createChild(
|
||||
config: Screen,
|
||||
componentContext: ComponentContext
|
||||
): NavigationChild = when (config) {
|
||||
Screen.ColorTools -> ColorTools(
|
||||
colorToolsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
Screen.EasterEgg -> EasterEgg(
|
||||
easterEggComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
Screen.Main -> Main(
|
||||
mainComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onTryGetUpdate = ::tryGetUpdate,
|
||||
onGetClipList = ::updateUris,
|
||||
onNavigate = ::navigateToNew,
|
||||
isUpdateAvailable = isUpdateAvailable
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.ApngTools -> ApngTools(
|
||||
apngToolsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialType = config.type,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.Cipher -> Cipher(
|
||||
cipherComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.CollageMaker -> CollageMaker(
|
||||
collageMakerComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.Compare -> Compare(
|
||||
compareComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialComparableUris = config.uris
|
||||
?.takeIf { it.size == 2 }
|
||||
?.let { it[0] to it[1] },
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.Crop -> Crop(
|
||||
cropComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.DeleteExif -> DeleteExif(
|
||||
deleteExifComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.DuplicateFinder -> DuplicateFinder(
|
||||
duplicateFinderComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
Screen.DocumentScanner -> DocumentScanner(
|
||||
documentScannerComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.Draw -> Draw(
|
||||
drawComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.EraseBackground -> EraseBackground(
|
||||
eraseBackgroundComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.Filter -> Filter(
|
||||
filtersComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialType = config.type,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.FormatConversion -> FormatConversion(
|
||||
formatConversionComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PaletteTools -> PaletteTools(
|
||||
paletteToolsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.GifTools -> GifTools(
|
||||
gifToolsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialType = config.type,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.GradientMaker -> GradientMaker(
|
||||
gradientMakerComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.ImagePreview -> ImagePreview(
|
||||
imagePreviewComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.ImageSplitting -> ImageSplitting(
|
||||
imageSplittingComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uri,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.ImageStacking -> ImageStacking(
|
||||
imageStackingComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.ImageStitching -> ImageStitching(
|
||||
imageStitchingComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.JxlTools -> JxlTools(
|
||||
jxlToolsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialType = config.type,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.LimitResize -> LimitResize(
|
||||
limitResizeComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.LoadNetImage -> LoadNetImage(
|
||||
loadNetImageComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUrl = config.url,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Screen.NoiseGeneration -> NoiseGeneration(
|
||||
noiseGenerationComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo,
|
||||
)
|
||||
)
|
||||
|
||||
Screen.TextureGeneration -> TextureGeneration(
|
||||
textureGenerationComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo,
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools -> RootPdfTools(
|
||||
rootPdfToolsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PickColorFromImage -> PickColorFromImage(
|
||||
pickColorFromImageComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.RecognizeText -> RecognizeText(
|
||||
recognizeTextComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialType = config.type,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.ResizeAndConvert -> ResizeAndConvert(
|
||||
resizeAndConvertComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.ScanQrCode -> ScanQrCode(
|
||||
scanQrCodeComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialQrCodeContent = config.qrCodeContent,
|
||||
uriToAnalyze = config.uriToAnalyze,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.Settings -> Settings(
|
||||
settingsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onTryGetUpdate = ::tryGetUpdate,
|
||||
onNavigate = ::navigateToNew,
|
||||
isUpdateAvailable = isUpdateAvailable,
|
||||
onGoBack = ::navigateBack,
|
||||
initialSearchQuery = config.searchQuery,
|
||||
targetSetting = config.targetSetting
|
||||
)
|
||||
)
|
||||
|
||||
Screen.ShaderStudio -> ShaderStudio(
|
||||
shaderStudioComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.Help -> Help(
|
||||
helpComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialCategory = config.categoryName,
|
||||
initialTipId = config.tipId,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.SingleEdit -> SingleEdit(
|
||||
singleEditComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onNavigate = ::navigateTo,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.SvgMaker -> SvgMaker(
|
||||
svgMakerComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.Watermarking -> Watermarking(
|
||||
watermarkingComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.WebpTools -> WebpTools(
|
||||
webpToolsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialType = config.type,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.WeightResize -> WeightResize(
|
||||
weightResizeComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.Zip -> Zip(
|
||||
zipComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
Screen.LibrariesInfo -> LibrariesInfo(
|
||||
librariesInfoComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
Screen.AppLogs -> AppLogs(
|
||||
appLogsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
Screen.UsageStatistics -> UsageStatistics(
|
||||
usageStatisticsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.MarkupLayers -> MarkupLayers(
|
||||
markupLayersComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.Base64Tools -> Base64Tools(
|
||||
base64ToolsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.ChecksumTools -> ChecksumTools(
|
||||
checksumToolsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.MeshGradients -> MeshGradients(
|
||||
meshGradientsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.EditExif -> EditExif(
|
||||
editExifComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.ImageCutter -> ImageCutter(
|
||||
imageCutterComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.AudioCoverExtractor -> AudioCoverExtractor(
|
||||
audioCoverExtractorComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.LibraryDetails -> LibraryDetails(
|
||||
libraryDetailsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
libraryName = config.name,
|
||||
libraryDescription = config.htmlDescription,
|
||||
libraryLink = config.link
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.WallpapersExport -> WallpapersExport(
|
||||
wallpapersExportComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.AsciiArt -> AsciiArt(
|
||||
asciiArtComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUri = config.uri,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.AiTools -> AiTools(
|
||||
aiToolsComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::navigateTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.ColorLibrary -> ColorLibrary(
|
||||
colorLibraryComponentFactory(
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Merge -> MergePdfTool(
|
||||
mergePdfToolComponentFactory(
|
||||
initialUris = config.uris,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Split -> SplitPdfTool(
|
||||
splitPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Rotate -> RotatePdfTool(
|
||||
rotatePdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Rearrange -> RearrangePdfTool(
|
||||
rearrangePdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.PageNumbers -> PageNumbersPdfTool(
|
||||
pageNumbersPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.OCR -> OCRPdfTool(
|
||||
ocrPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Watermark -> WatermarkPdfTool(
|
||||
watermarkPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Signature -> SignaturePdfTool(
|
||||
signaturePdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Protect -> ProtectPdfTool(
|
||||
protectPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Unlock -> UnlockPdfTool(
|
||||
unlockPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Compress -> CompressPdfTool(
|
||||
compressPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Grayscale -> GrayscalePdfTool(
|
||||
grayscalePdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Repair -> RepairPdfTool(
|
||||
repairPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Metadata -> MetadataPdfTool(
|
||||
metadataPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.RemovePages -> RemovePagesPdfTool(
|
||||
removePagesPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Crop -> CropPdfTool(
|
||||
cropPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Flatten -> FlattenPdfTool(
|
||||
flattenPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.ExtractImages -> ExtractImagesPdfTool(
|
||||
extractImagesPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.ZipConvert -> ZipConvertPdfTool(
|
||||
zipConvertPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Print -> PrintPdfTool(
|
||||
printPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.Preview -> PreviewPdfTool(
|
||||
previewPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.ImagesToPdf -> ImagesToPdfTool(
|
||||
imagesToPdfToolComponentFactory(
|
||||
initialUris = config.uris,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.ExtractPages -> ExtractPagesPdfTool(
|
||||
extractPagesPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.PdfTools.RemoveAnnotations -> RemoveAnnotationsPdfTool(
|
||||
removeAnnotationsPdfToolComponentFactory(
|
||||
initialUri = config.uri,
|
||||
componentContext = componentContext,
|
||||
onGoBack = ::navigateBack,
|
||||
onNavigate = ::replaceTo
|
||||
)
|
||||
)
|
||||
|
||||
is Screen.BatchRename -> BatchRename(
|
||||
batchRenameComponentFactory(
|
||||
componentContext = componentContext,
|
||||
initialUris = config.uris,
|
||||
onGoBack = ::navigateBack
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
+600
@@ -0,0 +1,600 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.navigation
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.t8rin.imagetoolbox.collage_maker.presentation.CollageMakerContent
|
||||
import com.t8rin.imagetoolbox.collage_maker.presentation.screenLogic.CollageMakerComponent
|
||||
import com.t8rin.imagetoolbox.color_library.presentation.ColorLibraryContent
|
||||
import com.t8rin.imagetoolbox.color_library.presentation.screenLogic.ColorLibraryComponent
|
||||
import com.t8rin.imagetoolbox.color_tools.presentation.ColorToolsContent
|
||||
import com.t8rin.imagetoolbox.color_tools.presentation.screenLogic.ColorToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.ai_tools.presentation.AiToolsContent
|
||||
import com.t8rin.imagetoolbox.feature.ai_tools.presentation.screenLogic.AiToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.apng_tools.presentation.ApngToolsContent
|
||||
import com.t8rin.imagetoolbox.feature.apng_tools.presentation.screenLogic.ApngToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.ascii_art.presentation.AsciiArtContent
|
||||
import com.t8rin.imagetoolbox.feature.ascii_art.presentation.screenLogic.AsciiArtComponent
|
||||
import com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui.AudioCoverExtractorContent
|
||||
import com.t8rin.imagetoolbox.feature.audio_cover_extractor.ui.screenLogic.AudioCoverExtractorComponent
|
||||
import com.t8rin.imagetoolbox.feature.base64_tools.presentation.Base64ToolsContent
|
||||
import com.t8rin.imagetoolbox.feature.base64_tools.presentation.screenLogic.Base64ToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.batchrename.presentation.BatchRenameContent
|
||||
import com.t8rin.imagetoolbox.feature.batchrename.presentation.screenLogic.BatchRenameComponent
|
||||
import com.t8rin.imagetoolbox.feature.checksum_tools.presentation.ChecksumToolsContent
|
||||
import com.t8rin.imagetoolbox.feature.checksum_tools.presentation.screenLogic.ChecksumToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.cipher.presentation.CipherContent
|
||||
import com.t8rin.imagetoolbox.feature.cipher.presentation.screenLogic.CipherComponent
|
||||
import com.t8rin.imagetoolbox.feature.compare.presentation.CompareContent
|
||||
import com.t8rin.imagetoolbox.feature.compare.presentation.screenLogic.CompareComponent
|
||||
import com.t8rin.imagetoolbox.feature.crop.presentation.CropContent
|
||||
import com.t8rin.imagetoolbox.feature.crop.presentation.screenLogic.CropComponent
|
||||
import com.t8rin.imagetoolbox.feature.delete_exif.presentation.DeleteExifContent
|
||||
import com.t8rin.imagetoolbox.feature.delete_exif.presentation.screenLogic.DeleteExifComponent
|
||||
import com.t8rin.imagetoolbox.feature.document_scanner.presentation.DocumentScannerContent
|
||||
import com.t8rin.imagetoolbox.feature.document_scanner.presentation.screenLogic.DocumentScannerComponent
|
||||
import com.t8rin.imagetoolbox.feature.draw.presentation.DrawContent
|
||||
import com.t8rin.imagetoolbox.feature.draw.presentation.screenLogic.DrawComponent
|
||||
import com.t8rin.imagetoolbox.feature.duplicate_finder.presentation.DuplicateFinderContent
|
||||
import com.t8rin.imagetoolbox.feature.duplicate_finder.presentation.screenLogic.DuplicateFinderComponent
|
||||
import com.t8rin.imagetoolbox.feature.easter_egg.presentation.EasterEggContent
|
||||
import com.t8rin.imagetoolbox.feature.easter_egg.presentation.screenLogic.EasterEggComponent
|
||||
import com.t8rin.imagetoolbox.feature.edit_exif.presentation.EditExifContent
|
||||
import com.t8rin.imagetoolbox.feature.edit_exif.presentation.screenLogic.EditExifComponent
|
||||
import com.t8rin.imagetoolbox.feature.erase_background.presentation.EraseBackgroundContent
|
||||
import com.t8rin.imagetoolbox.feature.erase_background.presentation.screenLogic.EraseBackgroundComponent
|
||||
import com.t8rin.imagetoolbox.feature.filters.presentation.FiltersContent
|
||||
import com.t8rin.imagetoolbox.feature.filters.presentation.screenLogic.FiltersComponent
|
||||
import com.t8rin.imagetoolbox.feature.format_conversion.presentation.FormatConversionContent
|
||||
import com.t8rin.imagetoolbox.feature.format_conversion.presentation.screenLogic.FormatConversionComponent
|
||||
import com.t8rin.imagetoolbox.feature.gif_tools.presentation.GifToolsContent
|
||||
import com.t8rin.imagetoolbox.feature.gif_tools.presentation.screenLogic.GifToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.gradient_maker.presentation.GradientMakerContent
|
||||
import com.t8rin.imagetoolbox.feature.gradient_maker.presentation.screenLogic.GradientMakerComponent
|
||||
import com.t8rin.imagetoolbox.feature.help.presentation.HelpContent
|
||||
import com.t8rin.imagetoolbox.feature.help.presentation.screenLogic.HelpComponent
|
||||
import com.t8rin.imagetoolbox.feature.image_preview.presentation.ImagePreviewContent
|
||||
import com.t8rin.imagetoolbox.feature.image_preview.presentation.screenLogic.ImagePreviewComponent
|
||||
import com.t8rin.imagetoolbox.feature.image_stacking.presentation.ImageStackingContent
|
||||
import com.t8rin.imagetoolbox.feature.image_stacking.presentation.screenLogic.ImageStackingComponent
|
||||
import com.t8rin.imagetoolbox.feature.image_stitch.presentation.ImageStitchingContent
|
||||
import com.t8rin.imagetoolbox.feature.image_stitch.presentation.screenLogic.ImageStitchingComponent
|
||||
import com.t8rin.imagetoolbox.feature.jxl_tools.presentation.JxlToolsContent
|
||||
import com.t8rin.imagetoolbox.feature.jxl_tools.presentation.screenLogic.JxlToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.libraries_info.presentation.LibrariesInfoContent
|
||||
import com.t8rin.imagetoolbox.feature.libraries_info.presentation.screenLogic.LibrariesInfoComponent
|
||||
import com.t8rin.imagetoolbox.feature.limits_resize.presentation.LimitsResizeContent
|
||||
import com.t8rin.imagetoolbox.feature.limits_resize.presentation.screenLogic.LimitsResizeComponent
|
||||
import com.t8rin.imagetoolbox.feature.load_net_image.presentation.LoadNetImageContent
|
||||
import com.t8rin.imagetoolbox.feature.load_net_image.presentation.screenLogic.LoadNetImageComponent
|
||||
import com.t8rin.imagetoolbox.feature.main.presentation.MainContent
|
||||
import com.t8rin.imagetoolbox.feature.main.presentation.screenLogic.MainComponent
|
||||
import com.t8rin.imagetoolbox.feature.markup_layers.presentation.MarkupLayersContent
|
||||
import com.t8rin.imagetoolbox.feature.markup_layers.presentation.screenLogic.MarkupLayersComponent
|
||||
import com.t8rin.imagetoolbox.feature.mesh_gradients.presentation.MeshGradientsContent
|
||||
import com.t8rin.imagetoolbox.feature.mesh_gradients.presentation.screenLogic.MeshGradientsComponent
|
||||
import com.t8rin.imagetoolbox.feature.palette_tools.presentation.PaletteToolsContent
|
||||
import com.t8rin.imagetoolbox.feature.palette_tools.presentation.screenLogic.PaletteToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.compress.CompressPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.compress.screenLogic.CompressPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop.CropPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.crop.screenLogic.CropPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_images.ExtractImagesPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_images.screenLogic.ExtractImagesPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_pages.ExtractPagesPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.extract_pages.screenLogic.ExtractPagesPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.flatten.FlattenPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.flatten.screenLogic.FlattenPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.grayscale.GrayscalePdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.grayscale.screenLogic.GrayscalePdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.images_to_pdf.ImagesToPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.images_to_pdf.screenLogic.ImagesToPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.merge.MergePdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.merge.screenLogic.MergePdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata.MetadataPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.metadata.screenLogic.MetadataPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.ocr.OCRPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.ocr.screenLogic.OCRPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers.PageNumbersPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.page_numbers.screenLogic.PageNumbersPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.preview.PreviewPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.preview.screenLogic.PreviewPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.print.PrintPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.print.screenLogic.PrintPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.protect.ProtectPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.protect.screenLogic.ProtectPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.RearrangePdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rearrange.screenLogic.RearrangePdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.RemoveAnnotationsPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_annotations.screenLogic.RemoveAnnotationsPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages.RemovePagesPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.remove_pages.screenLogic.RemovePagesPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.repair.RepairPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.repair.screenLogic.RepairPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.RootPdfToolsContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.root.screenLogic.RootPdfToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate.RotatePdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.rotate.screenLogic.RotatePdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.SignaturePdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.signature.screenLogic.SignaturePdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.split.SplitPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.split.screenLogic.SplitPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.unlock.UnlockPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.unlock.screenLogic.UnlockPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark.WatermarkPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.watermark.screenLogic.WatermarkPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.zip_convert.ZipConvertPdfToolContent
|
||||
import com.t8rin.imagetoolbox.feature.pdf_tools.presentation.zip_convert.screenLogic.ZipConvertPdfToolComponent
|
||||
import com.t8rin.imagetoolbox.feature.pick_color.presentation.PickColorFromImageContent
|
||||
import com.t8rin.imagetoolbox.feature.pick_color.presentation.screenLogic.PickColorFromImageComponent
|
||||
import com.t8rin.imagetoolbox.feature.recognize.text.presentation.RecognizeTextContent
|
||||
import com.t8rin.imagetoolbox.feature.recognize.text.presentation.screenLogic.RecognizeTextComponent
|
||||
import com.t8rin.imagetoolbox.feature.resize_convert.presentation.ResizeAndConvertContent
|
||||
import com.t8rin.imagetoolbox.feature.resize_convert.presentation.screenLogic.ResizeAndConvertComponent
|
||||
import com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.ScanQrCodeContent
|
||||
import com.t8rin.imagetoolbox.feature.scan_qr_code.presentation.screenLogic.ScanQrCodeComponent
|
||||
import com.t8rin.imagetoolbox.feature.settings.presentation.SettingsContent
|
||||
import com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent
|
||||
import com.t8rin.imagetoolbox.feature.shader_studio.presentation.ShaderStudioContent
|
||||
import com.t8rin.imagetoolbox.feature.shader_studio.presentation.screenLogic.ShaderStudioComponent
|
||||
import com.t8rin.imagetoolbox.feature.single_edit.presentation.SingleEditContent
|
||||
import com.t8rin.imagetoolbox.feature.single_edit.presentation.screenLogic.SingleEditComponent
|
||||
import com.t8rin.imagetoolbox.feature.svg_maker.presentation.SvgMakerContent
|
||||
import com.t8rin.imagetoolbox.feature.svg_maker.presentation.screenLogic.SvgMakerComponent
|
||||
import com.t8rin.imagetoolbox.feature.usage_statistics.presentation.UsageStatisticsContent
|
||||
import com.t8rin.imagetoolbox.feature.usage_statistics.presentation.screenLogic.UsageStatisticsComponent
|
||||
import com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.WallpapersExportContent
|
||||
import com.t8rin.imagetoolbox.feature.wallpapers_export.presentation.screenLogic.WallpapersExportComponent
|
||||
import com.t8rin.imagetoolbox.feature.watermarking.presentation.WatermarkingContent
|
||||
import com.t8rin.imagetoolbox.feature.watermarking.presentation.screenLogic.WatermarkingComponent
|
||||
import com.t8rin.imagetoolbox.feature.webp_tools.presentation.WebpToolsContent
|
||||
import com.t8rin.imagetoolbox.feature.webp_tools.presentation.screenLogic.WebpToolsComponent
|
||||
import com.t8rin.imagetoolbox.feature.weight_resize.presentation.WeightResizeContent
|
||||
import com.t8rin.imagetoolbox.feature.weight_resize.presentation.screenLogic.WeightResizeComponent
|
||||
import com.t8rin.imagetoolbox.feature.zip.presentation.ZipContent
|
||||
import com.t8rin.imagetoolbox.feature.zip.presentation.screenLogic.ZipComponent
|
||||
import com.t8rin.imagetoolbox.image_cutting.presentation.ImageCutterContent
|
||||
import com.t8rin.imagetoolbox.image_cutting.presentation.screenLogic.ImageCutterComponent
|
||||
import com.t8rin.imagetoolbox.image_splitting.presentation.ImageSplitterContent
|
||||
import com.t8rin.imagetoolbox.image_splitting.presentation.screenLogic.ImageSplitterComponent
|
||||
import com.t8rin.imagetoolbox.library_details.presentation.LibraryDetailsContent
|
||||
import com.t8rin.imagetoolbox.library_details.presentation.screenLogic.LibraryDetailsComponent
|
||||
import com.t8rin.imagetoolbox.noise_generation.presentation.NoiseGenerationContent
|
||||
import com.t8rin.imagetoolbox.noise_generation.presentation.screenLogic.NoiseGenerationComponent
|
||||
import com.t8rin.imagetoolbox.presentation.app_logs.AppLogsContent
|
||||
import com.t8rin.imagetoolbox.presentation.app_logs.screenLogic.AppLogsComponent
|
||||
import com.t8rin.imagetoolbox.texture_generation.presentation.TextureGenerationContent
|
||||
import com.t8rin.imagetoolbox.texture_generation.presentation.screenLogic.TextureGenerationComponent
|
||||
|
||||
|
||||
internal sealed interface NavigationChild {
|
||||
|
||||
@Composable
|
||||
fun Content()
|
||||
|
||||
|
||||
class ApngTools(private val component: ApngToolsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ApngToolsContent(component)
|
||||
}
|
||||
|
||||
class Cipher(private val component: CipherComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = CipherContent(component)
|
||||
}
|
||||
|
||||
class CollageMaker(private val component: CollageMakerComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = CollageMakerContent(component)
|
||||
}
|
||||
|
||||
class ColorTools(private val component: ColorToolsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ColorToolsContent(component)
|
||||
}
|
||||
|
||||
class Compare(private val component: CompareComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = CompareContent(component)
|
||||
}
|
||||
|
||||
class Crop(private val component: CropComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = CropContent(component)
|
||||
}
|
||||
|
||||
class DeleteExif(private val component: DeleteExifComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = DeleteExifContent(component)
|
||||
}
|
||||
|
||||
class BatchRename(private val component: BatchRenameComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = BatchRenameContent(component)
|
||||
}
|
||||
|
||||
class DocumentScanner(private val component: DocumentScannerComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = DocumentScannerContent(component)
|
||||
}
|
||||
|
||||
class Draw(private val component: DrawComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = DrawContent(component)
|
||||
}
|
||||
|
||||
class DuplicateFinder(private val component: DuplicateFinderComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = DuplicateFinderContent(component)
|
||||
}
|
||||
|
||||
class EasterEgg(private val component: EasterEggComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = EasterEggContent(component)
|
||||
}
|
||||
|
||||
class EraseBackground(private val component: EraseBackgroundComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = EraseBackgroundContent(component)
|
||||
}
|
||||
|
||||
class Filter(private val component: FiltersComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = FiltersContent(component)
|
||||
}
|
||||
|
||||
class FormatConversion(private val component: FormatConversionComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = FormatConversionContent(component)
|
||||
}
|
||||
|
||||
class PaletteTools(private val component: PaletteToolsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = PaletteToolsContent(component)
|
||||
}
|
||||
|
||||
class GifTools(private val component: GifToolsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = GifToolsContent(component)
|
||||
}
|
||||
|
||||
class GradientMaker(private val component: GradientMakerComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = GradientMakerContent(component)
|
||||
}
|
||||
|
||||
class ImagePreview(private val component: ImagePreviewComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ImagePreviewContent(component)
|
||||
}
|
||||
|
||||
class ImageSplitting(private val component: ImageSplitterComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ImageSplitterContent(component)
|
||||
}
|
||||
|
||||
class ImageStacking(private val component: ImageStackingComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ImageStackingContent(component)
|
||||
}
|
||||
|
||||
class ImageStitching(private val component: ImageStitchingComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ImageStitchingContent(component)
|
||||
}
|
||||
|
||||
class JxlTools(private val component: JxlToolsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = JxlToolsContent(component)
|
||||
}
|
||||
|
||||
class LimitResize(private val component: LimitsResizeComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = LimitsResizeContent(component)
|
||||
}
|
||||
|
||||
class LoadNetImage(private val component: LoadNetImageComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = LoadNetImageContent(component)
|
||||
}
|
||||
|
||||
class Main(private val component: MainComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = MainContent(component)
|
||||
}
|
||||
|
||||
class NoiseGeneration(private val component: NoiseGenerationComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = NoiseGenerationContent(component)
|
||||
}
|
||||
|
||||
class TextureGeneration(private val component: TextureGenerationComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = TextureGenerationContent(component)
|
||||
}
|
||||
|
||||
class RootPdfTools(private val component: RootPdfToolsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = RootPdfToolsContent(component)
|
||||
}
|
||||
|
||||
class PickColorFromImage(private val component: PickColorFromImageComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = PickColorFromImageContent(component)
|
||||
}
|
||||
|
||||
class RecognizeText(private val component: RecognizeTextComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = RecognizeTextContent(component)
|
||||
}
|
||||
|
||||
class ResizeAndConvert(private val component: ResizeAndConvertComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ResizeAndConvertContent(component)
|
||||
}
|
||||
|
||||
class ScanQrCode(private val component: ScanQrCodeComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ScanQrCodeContent(component)
|
||||
}
|
||||
|
||||
class Settings(private val component: SettingsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = SettingsContent(component)
|
||||
}
|
||||
|
||||
class ShaderStudio(private val component: ShaderStudioComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ShaderStudioContent(component)
|
||||
}
|
||||
|
||||
class Help(private val component: HelpComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = HelpContent(component)
|
||||
}
|
||||
|
||||
class SingleEdit(private val component: SingleEditComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = SingleEditContent(component)
|
||||
}
|
||||
|
||||
class SvgMaker(private val component: SvgMakerComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = SvgMakerContent(component)
|
||||
}
|
||||
|
||||
class Watermarking(private val component: WatermarkingComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = WatermarkingContent(component)
|
||||
}
|
||||
|
||||
class WebpTools(private val component: WebpToolsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = WebpToolsContent(component)
|
||||
}
|
||||
|
||||
class WeightResize(private val component: WeightResizeComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = WeightResizeContent(component)
|
||||
}
|
||||
|
||||
class Zip(private val component: ZipComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ZipContent(component)
|
||||
}
|
||||
|
||||
class LibrariesInfo(private val component: LibrariesInfoComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = LibrariesInfoContent(component)
|
||||
}
|
||||
|
||||
class AppLogs(private val component: AppLogsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = AppLogsContent(component)
|
||||
}
|
||||
|
||||
class UsageStatistics(private val component: UsageStatisticsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = UsageStatisticsContent(component)
|
||||
}
|
||||
|
||||
class MarkupLayers(private val component: MarkupLayersComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = MarkupLayersContent(component)
|
||||
}
|
||||
|
||||
class Base64Tools(private val component: Base64ToolsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = Base64ToolsContent(component)
|
||||
}
|
||||
|
||||
class ChecksumTools(private val component: ChecksumToolsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ChecksumToolsContent(component)
|
||||
}
|
||||
|
||||
class MeshGradients(private val component: MeshGradientsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = MeshGradientsContent(component)
|
||||
}
|
||||
|
||||
class EditExif(private val component: EditExifComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = EditExifContent(component)
|
||||
}
|
||||
|
||||
class ImageCutter(private val component: ImageCutterComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ImageCutterContent(component)
|
||||
}
|
||||
|
||||
class AudioCoverExtractor(
|
||||
private val component: AudioCoverExtractorComponent
|
||||
) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = AudioCoverExtractorContent(component)
|
||||
}
|
||||
|
||||
class LibraryDetails(private val component: LibraryDetailsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = LibraryDetailsContent(component)
|
||||
}
|
||||
|
||||
class WallpapersExport(private val component: WallpapersExportComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = WallpapersExportContent(component)
|
||||
}
|
||||
|
||||
class AsciiArt(private val component: AsciiArtComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = AsciiArtContent(component)
|
||||
}
|
||||
|
||||
class AiTools(private val component: AiToolsComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = AiToolsContent(component)
|
||||
}
|
||||
|
||||
class ColorLibrary(private val component: ColorLibraryComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ColorLibraryContent(component)
|
||||
}
|
||||
|
||||
class MergePdfTool(private val component: MergePdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = MergePdfToolContent(component)
|
||||
}
|
||||
|
||||
class SplitPdfTool(private val component: SplitPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = SplitPdfToolContent(component)
|
||||
}
|
||||
|
||||
class RotatePdfTool(private val component: RotatePdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = RotatePdfToolContent(component)
|
||||
}
|
||||
|
||||
class RearrangePdfTool(private val component: RearrangePdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = RearrangePdfToolContent(component)
|
||||
}
|
||||
|
||||
class PageNumbersPdfTool(private val component: PageNumbersPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = PageNumbersPdfToolContent(component)
|
||||
}
|
||||
|
||||
class OCRPdfTool(private val component: OCRPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = OCRPdfToolContent(component)
|
||||
}
|
||||
|
||||
class WatermarkPdfTool(private val component: WatermarkPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = WatermarkPdfToolContent(component)
|
||||
}
|
||||
|
||||
class SignaturePdfTool(private val component: SignaturePdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = SignaturePdfToolContent(component)
|
||||
}
|
||||
|
||||
class ProtectPdfTool(private val component: ProtectPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ProtectPdfToolContent(component)
|
||||
}
|
||||
|
||||
class UnlockPdfTool(private val component: UnlockPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = UnlockPdfToolContent(component)
|
||||
}
|
||||
|
||||
class CompressPdfTool(private val component: CompressPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = CompressPdfToolContent(component)
|
||||
}
|
||||
|
||||
class GrayscalePdfTool(private val component: GrayscalePdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = GrayscalePdfToolContent(component)
|
||||
}
|
||||
|
||||
class RepairPdfTool(private val component: RepairPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = RepairPdfToolContent(component)
|
||||
}
|
||||
|
||||
class MetadataPdfTool(private val component: MetadataPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = MetadataPdfToolContent(component)
|
||||
}
|
||||
|
||||
class RemovePagesPdfTool(private val component: RemovePagesPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = RemovePagesPdfToolContent(component)
|
||||
}
|
||||
|
||||
class CropPdfTool(private val component: CropPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = CropPdfToolContent(component)
|
||||
}
|
||||
|
||||
class FlattenPdfTool(private val component: FlattenPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = FlattenPdfToolContent(component)
|
||||
}
|
||||
|
||||
class ExtractImagesPdfTool(private val component: ExtractImagesPdfToolComponent) :
|
||||
NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ExtractImagesPdfToolContent(component)
|
||||
}
|
||||
|
||||
class ZipConvertPdfTool(private val component: ZipConvertPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ZipConvertPdfToolContent(component)
|
||||
}
|
||||
|
||||
class PrintPdfTool(private val component: PrintPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = PrintPdfToolContent(component)
|
||||
}
|
||||
|
||||
class PreviewPdfTool(private val component: PreviewPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = PreviewPdfToolContent(component)
|
||||
}
|
||||
|
||||
class ImagesToPdfTool(private val component: ImagesToPdfToolComponent) : NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ImagesToPdfToolContent(component)
|
||||
}
|
||||
|
||||
class ExtractPagesPdfTool(private val component: ExtractPagesPdfToolComponent) :
|
||||
NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = ExtractPagesPdfToolContent(component)
|
||||
}
|
||||
|
||||
class RemoveAnnotationsPdfTool(private val component: RemoveAnnotationsPdfToolComponent) :
|
||||
NavigationChild {
|
||||
@Composable
|
||||
override fun Content() = RemoveAnnotationsPdfToolContent(component)
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.utils
|
||||
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen
|
||||
|
||||
fun interface BackEventObserver {
|
||||
fun onBack(closedScreen: Screen?)
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.utils
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import com.t8rin.dynamic.theme.LocalDynamicThemeState
|
||||
import com.t8rin.imagetoolbox.core.settings.presentation.provider.rememberAppColorTuple
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent
|
||||
|
||||
@Composable
|
||||
internal fun ResetThemeOnGoBack(
|
||||
component: RootComponent
|
||||
) {
|
||||
val appColorTuple = rememberAppColorTuple()
|
||||
val themeState = LocalDynamicThemeState.current
|
||||
|
||||
DisposableEffect(component, themeState, appColorTuple) {
|
||||
val observer = BackEventObserver {
|
||||
themeState.updateColorTuple(appColorTuple)
|
||||
}
|
||||
|
||||
component.addBackEventsObserver(observer)
|
||||
|
||||
onDispose {
|
||||
component.removeBackEventsObserver(observer)
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.utils
|
||||
|
||||
import android.view.WindowManager
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.ui.util.fastAny
|
||||
import com.t8rin.imagetoolbox.core.settings.presentation.provider.LocalSettingsState
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity
|
||||
|
||||
@Composable
|
||||
internal fun ScreenBasedMaxBrightnessEnforcement(
|
||||
currentScreen: Screen?
|
||||
) {
|
||||
val context = LocalComponentActivity.current
|
||||
|
||||
val listToForceBrightness = LocalSettingsState.current.screenListWithMaxBrightnessEnforcement
|
||||
|
||||
DisposableEffect(currentScreen) {
|
||||
if (listToForceBrightness.fastAny { it == currentScreen?.id }) {
|
||||
context.window.apply {
|
||||
attributes.apply {
|
||||
screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL
|
||||
}
|
||||
addFlags(WindowManager.LayoutParams.SCREEN_BRIGHTNESS_CHANGED)
|
||||
}
|
||||
}
|
||||
onDispose {
|
||||
context.window.apply {
|
||||
attributes.apply {
|
||||
screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
|
||||
}
|
||||
addFlags(WindowManager.LayoutParams.SCREEN_BRIGHTNESS_CHANGED)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.utils
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import com.arkivanov.decompose.extensions.compose.subscribeAsState
|
||||
import com.arkivanov.decompose.router.stack.ChildStack
|
||||
import com.arkivanov.decompose.value.Value
|
||||
import com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState
|
||||
import com.t8rin.imagetoolbox.core.settings.presentation.model.UiSettingsState
|
||||
import com.t8rin.imagetoolbox.core.settings.presentation.model.toUiState
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@Composable
|
||||
internal fun RootComponent.uiSettingsState(): UiSettingsState = settingsState.toUiState(
|
||||
randomEmojiKey = childStack.randomEmojiKey()
|
||||
)
|
||||
|
||||
@Composable
|
||||
internal fun HandleLookForUpdates(component: RootComponent) {
|
||||
if (component.settingsState.shouldTryGetUpdate) {
|
||||
LaunchedEffect(Unit) {
|
||||
delay(500)
|
||||
component.tryGetUpdate(
|
||||
onNoUpdates = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val SettingsState.shouldTryGetUpdate: Boolean
|
||||
get() = appOpenCount >= 2 && showUpdateDialogOnStartup
|
||||
|
||||
@Composable
|
||||
private fun Value<ChildStack<Screen, *>>.randomEmojiKey(): Any {
|
||||
val randomEmojiKey = remember {
|
||||
mutableIntStateOf(0)
|
||||
}
|
||||
|
||||
val currentDestination = subscribeAsState().value.items
|
||||
LaunchedEffect(currentDestination) {
|
||||
delay(200L) // Delay for transition
|
||||
randomEmojiKey.intValue++
|
||||
}
|
||||
|
||||
return randomEmojiKey.intValue
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.components.utils
|
||||
|
||||
import com.t8rin.imagetoolbox.core.resources.Icons
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import com.t8rin.imagetoolbox.core.resources.R
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.Save
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.provider.LocalComponentActivity
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.screenLogic.RootComponent
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
internal fun SuccessRestoreBackupToastHandler(component: RootComponent) {
|
||||
val context = LocalComponentActivity.current
|
||||
LaunchedEffect(component) {
|
||||
component.backupRestoredEvents.collectLatest { restored ->
|
||||
if (restored) {
|
||||
launch {
|
||||
AppToastHost.showConfetti()
|
||||
//Wait for confetti to appear, then trigger font scale adjustment
|
||||
delay(300L)
|
||||
context.recreate()
|
||||
}
|
||||
AppToastHost.showToast(
|
||||
message = context.getString(R.string.settings_restored),
|
||||
icon = Icons.Rounded.Save
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+498
@@ -0,0 +1,498 @@
|
||||
/*
|
||||
* ImageToolbox is an image editor for android
|
||||
* Copyright (c) 2026 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>.
|
||||
*/
|
||||
|
||||
package com.t8rin.imagetoolbox.feature.root.presentation.screenLogic
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.arkivanov.decompose.ComponentContext
|
||||
import com.arkivanov.decompose.childContext
|
||||
import com.arkivanov.decompose.router.stack.ChildStack
|
||||
import com.arkivanov.decompose.router.stack.StackNavigation
|
||||
import com.arkivanov.decompose.router.stack.childStack
|
||||
import com.arkivanov.decompose.router.stack.items
|
||||
import com.arkivanov.decompose.router.stack.navigate
|
||||
import com.arkivanov.decompose.router.stack.pop
|
||||
import com.arkivanov.decompose.router.stack.pushNew
|
||||
import com.arkivanov.decompose.value.MutableValue
|
||||
import com.arkivanov.decompose.value.Value
|
||||
import com.t8rin.imagetoolbox.core.data.saving.FileControllerEventEmitter
|
||||
import com.t8rin.imagetoolbox.core.domain.APP_CHANGELOG
|
||||
import com.t8rin.imagetoolbox.core.domain.coroutines.DispatchersHolder
|
||||
import com.t8rin.imagetoolbox.core.domain.history.AppHistoryRepository
|
||||
import com.t8rin.imagetoolbox.core.domain.model.ExtraDataType
|
||||
import com.t8rin.imagetoolbox.core.domain.model.ImageModel
|
||||
import com.t8rin.imagetoolbox.core.domain.model.PerformanceClass
|
||||
import com.t8rin.imagetoolbox.core.domain.remote.AnalyticsManager
|
||||
import com.t8rin.imagetoolbox.core.domain.resource.ResourceManager
|
||||
import com.t8rin.imagetoolbox.core.domain.saving.FileController
|
||||
import com.t8rin.imagetoolbox.core.domain.utils.smartJob
|
||||
import com.t8rin.imagetoolbox.core.filters.domain.FilterParamsInteractor
|
||||
import com.t8rin.imagetoolbox.core.resources.Icons
|
||||
import com.t8rin.imagetoolbox.core.resources.R
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.AutoFixHigh
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.DownloadOff
|
||||
import com.t8rin.imagetoolbox.core.resources.icons.Error
|
||||
import com.t8rin.imagetoolbox.core.settings.domain.AutoCacheCleanupUseCase
|
||||
import com.t8rin.imagetoolbox.core.settings.domain.SettingsManager
|
||||
import com.t8rin.imagetoolbox.core.settings.domain.model.SettingsState
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.BaseComponent
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.AppToastHost
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.helper.handleDeeplinks
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.navigation.Screen
|
||||
import com.t8rin.imagetoolbox.core.ui.utils.state.update
|
||||
import com.t8rin.imagetoolbox.core.ui.widget.other.ToastDuration
|
||||
import com.t8rin.imagetoolbox.core.utils.isNeedUpdate
|
||||
import com.t8rin.imagetoolbox.core.utils.makeLog
|
||||
import com.t8rin.imagetoolbox.core.utils.parseChangelog
|
||||
import com.t8rin.imagetoolbox.core.utils.toImageModel
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.ChildProvider
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.navigation.NavigationChild
|
||||
import com.t8rin.imagetoolbox.feature.root.presentation.components.utils.BackEventObserver
|
||||
import com.t8rin.imagetoolbox.feature.settings.presentation.screenLogic.SettingsComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.bodyAsChannel
|
||||
import io.ktor.utils.io.jvm.javaio.toInputStream
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class RootComponent @AssistedInject internal constructor(
|
||||
@Assisted componentContext: ComponentContext,
|
||||
private val settingsManager: SettingsManager,
|
||||
private val childProvider: ChildProvider,
|
||||
private val analyticsManager: AnalyticsManager,
|
||||
private val client: HttpClient,
|
||||
private val filterParamsInteractor: FilterParamsInteractor,
|
||||
private val fileController: FileController,
|
||||
private val appHistoryRepository: AppHistoryRepository,
|
||||
private val autoCacheCleanupUseCase: AutoCacheCleanupUseCase,
|
||||
dispatchersHolder: DispatchersHolder,
|
||||
settingsComponentFactory: SettingsComponent.Factory,
|
||||
resourceManager: ResourceManager,
|
||||
fileControllerEventEmitter: FileControllerEventEmitter
|
||||
) : BaseComponent(dispatchersHolder, componentContext),
|
||||
ResourceManager by resourceManager,
|
||||
FileControllerEventEmitter by fileControllerEventEmitter {
|
||||
|
||||
private var updatesJob: Job? by smartJob()
|
||||
|
||||
private val _backupRestoredEvents: Channel<Boolean> = Channel(Channel.BUFFERED)
|
||||
val backupRestoredEvents: Flow<Boolean> = _backupRestoredEvents.receiveAsFlow()
|
||||
|
||||
private val _isUpdateAvailable: MutableValue<Boolean> = MutableValue(false)
|
||||
val isUpdateAvailable: Value<Boolean> = _isUpdateAvailable
|
||||
|
||||
private val _concealBackdropChannel: Channel<Boolean> = Channel(Channel.BUFFERED)
|
||||
val concealBackdropFlow: Flow<Boolean> = _concealBackdropChannel.receiveAsFlow()
|
||||
|
||||
val settingsComponent = settingsComponentFactory(
|
||||
componentContext = childContext("rootSettings"),
|
||||
onTryGetUpdate = ::tryGetUpdate,
|
||||
onNavigate = ::navigateTo,
|
||||
isUpdateAvailable = isUpdateAvailable,
|
||||
onGoBack = {
|
||||
_concealBackdropChannel.trySend(true)
|
||||
},
|
||||
initialSearchQuery = ""
|
||||
)
|
||||
|
||||
private val _settingsState = mutableStateOf(SettingsState.Default)
|
||||
val settingsState: SettingsState by _settingsState
|
||||
|
||||
private val navController = StackNavigation<Screen>()
|
||||
|
||||
internal val childStack: Value<ChildStack<Screen, NavigationChild>> by lazy {
|
||||
childStack(
|
||||
source = navController,
|
||||
initialConfiguration = Screen.Main,
|
||||
serializer = Screen.serializer(),
|
||||
handleBackButton = true,
|
||||
childFactory = { screen, context ->
|
||||
with(childProvider) {
|
||||
createChild(
|
||||
config = screen,
|
||||
componentContext = context
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private val _uris = mutableStateOf<List<Uri>?>(null)
|
||||
val uris by _uris
|
||||
|
||||
private val _extraDataType = mutableStateOf<ExtraDataType?>(null)
|
||||
val extraDataType: ExtraDataType? by _extraDataType
|
||||
|
||||
private val _showSelectDialog = mutableStateOf(false)
|
||||
val showSelectDialog by _showSelectDialog
|
||||
|
||||
private val _showUpdateDialog = mutableStateOf(false)
|
||||
val showUpdateDialog by _showUpdateDialog
|
||||
|
||||
private val _isUpdateCancelled = mutableStateOf(false)
|
||||
|
||||
private val _shouldShowExitDialog = mutableStateOf(true)
|
||||
val shouldShowDialog by _shouldShowExitDialog
|
||||
|
||||
private val _showGithubReviewDialog = mutableStateOf(false)
|
||||
val showGithubReviewDialog by _showGithubReviewDialog
|
||||
|
||||
private val _showTelegramGroupDialog = mutableStateOf(false)
|
||||
val showTelegramGroupDialog by _showTelegramGroupDialog
|
||||
|
||||
private val _tag = mutableStateOf("")
|
||||
val tag by _tag
|
||||
|
||||
private val _changelog = mutableStateOf("")
|
||||
val changelog by _changelog
|
||||
|
||||
private val _filterPreviewModel: MutableState<ImageModel> =
|
||||
mutableStateOf(R.drawable.filter_preview_source.toImageModel())
|
||||
val filterPreviewModel by _filterPreviewModel
|
||||
|
||||
private val _canSetDynamicFilterPreview: MutableState<Boolean> =
|
||||
mutableStateOf(false)
|
||||
val canSetDynamicFilterPreview by _canSetDynamicFilterPreview
|
||||
|
||||
init {
|
||||
runBlocking {
|
||||
_settingsState.value = settingsManager.getSettingsState().also {
|
||||
autoCacheCleanupUseCase.clearCacheIfNeeded(it)
|
||||
}
|
||||
}
|
||||
settingsManager
|
||||
.settingsState
|
||||
.onEach { state ->
|
||||
_showTelegramGroupDialog.update {
|
||||
state.appOpenCount % 6 == 0 && state.appOpenCount != 0 && !state.isTelegramGroupOpened
|
||||
}
|
||||
_settingsState.value = state
|
||||
}
|
||||
.launchIn(componentScope)
|
||||
|
||||
if (settingsState.screenList.size != Screen.entries.size) {
|
||||
componentScope.launch {
|
||||
val currentList = settingsState.screenList
|
||||
val neededList = Screen.entries.filter { it.id !in currentList }.map { it.id }
|
||||
settingsManager.setScreenOrder(
|
||||
(currentList + neededList).joinToString("/")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
filterParamsInteractor
|
||||
.getFilterPreviewModel().onEach { data ->
|
||||
_filterPreviewModel.update { data }
|
||||
}.launchIn(componentScope)
|
||||
|
||||
filterParamsInteractor
|
||||
.getCanSetDynamicFilterPreview().onEach { value ->
|
||||
_canSetDynamicFilterPreview.update { value }
|
||||
}.launchIn(componentScope)
|
||||
}
|
||||
|
||||
fun toggleShowUpdateDialog() {
|
||||
componentScope.launch {
|
||||
settingsManager.toggleShowUpdateDialogOnStartup()
|
||||
}
|
||||
}
|
||||
|
||||
fun setPresets(newPresets: List<Int>) {
|
||||
componentScope.launch {
|
||||
settingsManager.setPresets(newPresets)
|
||||
}
|
||||
}
|
||||
|
||||
fun cancelledUpdate(showAgain: Boolean = false) {
|
||||
if (!showAgain) _isUpdateCancelled.value = true
|
||||
_showUpdateDialog.value = false
|
||||
}
|
||||
|
||||
fun tryGetUpdate(
|
||||
isNewRequest: Boolean = false,
|
||||
onNoUpdates: (() -> Unit)? = {
|
||||
AppToastHost.showToast(
|
||||
icon = Icons.Rounded.DownloadOff,
|
||||
message = getString(R.string.no_updates)
|
||||
)
|
||||
}
|
||||
) {
|
||||
if (settingsState.appOpenCount < 2 && !isNewRequest) return
|
||||
val isInstalledFromMarket = settingsManager.isInstalledFromPlayStore()
|
||||
|
||||
val showDialog = settingsState.showUpdateDialogOnStartup
|
||||
if (isInstalledFromMarket) {
|
||||
if (showDialog) {
|
||||
_showUpdateDialog.value = isNewRequest
|
||||
}
|
||||
} else {
|
||||
if (!_isUpdateCancelled.value || isNewRequest) {
|
||||
updatesJob = componentScope.launch {
|
||||
checkForUpdates(
|
||||
showDialog = showDialog,
|
||||
onNoUpdates = onNoUpdates ?: {}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun checkForUpdates(
|
||||
showDialog: Boolean,
|
||||
onNoUpdates: () -> Unit
|
||||
) = withContext(defaultDispatcher) {
|
||||
"start updates check".makeLog("checkForUpdates")
|
||||
runCatching {
|
||||
val (tag, changelog) = client
|
||||
.get(APP_CHANGELOG).bodyAsChannel().toInputStream()
|
||||
.use { it.parseChangelog() }
|
||||
|
||||
_tag.update { tag }
|
||||
_changelog.update { changelog }
|
||||
|
||||
val isNeedUpdate = isNeedUpdate(
|
||||
updateName = tag,
|
||||
allowBetas = settingsState.allowBetas
|
||||
).makeLog("checkForUpdates") { "isNeedUpdate = $it" }
|
||||
|
||||
if (isNeedUpdate) {
|
||||
_isUpdateAvailable.value = true
|
||||
_showUpdateDialog.value = showDialog
|
||||
} else {
|
||||
onNoUpdates()
|
||||
}
|
||||
}.onFailure {
|
||||
it.makeLog("checkForUpdates")
|
||||
onNoUpdates()
|
||||
}
|
||||
}
|
||||
|
||||
fun hideSelectDialog() {
|
||||
_showSelectDialog.value = false
|
||||
_uris.update { null }
|
||||
}
|
||||
|
||||
fun updateUris(uris: List<Uri>) {
|
||||
_uris.value = uris
|
||||
|
||||
if (uris.isNotEmpty() || extraDataType != null) {
|
||||
_showSelectDialog.value = true
|
||||
}
|
||||
}
|
||||
|
||||
fun updateExtraDataType(type: ExtraDataType?) {
|
||||
type.makeLog("updateExtraDataType")
|
||||
|
||||
if (type is ExtraDataType.Backup) {
|
||||
componentScope.launch {
|
||||
settingsManager.restoreFromBackupFile(
|
||||
backupFileUri = type.uri.trim(),
|
||||
onSuccess = {
|
||||
_backupRestoredEvents.trySend(true)
|
||||
},
|
||||
onFailure = { throwable ->
|
||||
AppToastHost.showToast(
|
||||
message = getString(
|
||||
R.string.smth_went_wrong,
|
||||
throwable.localizedMessage ?: ""
|
||||
),
|
||||
icon = Icons.Outlined.Error,
|
||||
duration = ToastDuration.Long
|
||||
)
|
||||
_backupRestoredEvents.trySend(false)
|
||||
}
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (type is ExtraDataType.Template) {
|
||||
componentScope.launch {
|
||||
val content = fileController.readBytes(type.uri).toString(Charsets.UTF_8)
|
||||
|
||||
if (filterParamsInteractor.isValidTemplateFilter(content)) {
|
||||
filterParamsInteractor.addTemplateFilterFromString(
|
||||
string = content,
|
||||
onSuccess = { filterName, filtersCount ->
|
||||
AppToastHost.showToast(
|
||||
message = getString(
|
||||
R.string.added_filter_template,
|
||||
filterName,
|
||||
filtersCount
|
||||
),
|
||||
icon = Icons.Outlined.AutoFixHigh
|
||||
)
|
||||
},
|
||||
onFailure = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
_extraDataType.update { null }
|
||||
_extraDataType.update { type }
|
||||
}
|
||||
|
||||
fun cancelShowingExitDialog() {
|
||||
_shouldShowExitDialog.update { false }
|
||||
}
|
||||
|
||||
fun toggleAllowBetas() {
|
||||
componentScope.launch {
|
||||
settingsManager.toggleAllowBetas()
|
||||
}
|
||||
}
|
||||
|
||||
fun onWantGithubReview() {
|
||||
_showGithubReviewDialog.update { true }
|
||||
}
|
||||
|
||||
fun hideReviewDialog() {
|
||||
_showGithubReviewDialog.update { false }
|
||||
}
|
||||
|
||||
fun hideTelegramGroupDialog() {
|
||||
_showTelegramGroupDialog.update { false }
|
||||
}
|
||||
|
||||
fun adjustPerformance(performanceClass: PerformanceClass) {
|
||||
componentScope.launch {
|
||||
settingsManager.adjustPerformance(performanceClass)
|
||||
}
|
||||
}
|
||||
|
||||
fun registerDonateDialogOpen() {
|
||||
componentScope.launch {
|
||||
settingsManager.registerDonateDialogOpen()
|
||||
}
|
||||
}
|
||||
|
||||
fun notShowDonateDialogAgain() {
|
||||
componentScope.launch {
|
||||
settingsManager.setNotShowDonateDialogAgain()
|
||||
}
|
||||
}
|
||||
|
||||
fun registerTelegramGroupOpen() {
|
||||
componentScope.launch {
|
||||
settingsManager.registerTelegramGroupOpen()
|
||||
}
|
||||
}
|
||||
|
||||
fun navigateTo(screen: Screen) {
|
||||
componentScope.launch {
|
||||
delay(100)
|
||||
screen.saveToHistory().simpleName.makeLog("Navigator")
|
||||
.also(analyticsManager::registerScreenOpen)
|
||||
navController.pushNew(screen)
|
||||
hideSelectDialog()
|
||||
}
|
||||
}
|
||||
|
||||
fun replaceTo(screen: Screen) {
|
||||
componentScope.launch {
|
||||
delay(100)
|
||||
screen.saveToHistory().simpleName.makeLog("Navigator")
|
||||
.also(analyticsManager::registerScreenOpen)
|
||||
navController.navigate(
|
||||
transformer = { stack ->
|
||||
stack.dropLastWhile { it !is Screen.PdfTools && it !is Screen.Main } + screen
|
||||
}
|
||||
)
|
||||
hideSelectDialog()
|
||||
}
|
||||
}
|
||||
|
||||
fun navigateToNew(screen: Screen) {
|
||||
if (childStack.items.lastOrNull()?.configuration != Screen.Main) {
|
||||
navigateBack()
|
||||
}
|
||||
screen.saveToHistory().simpleName.makeLog("Navigator")
|
||||
.also(analyticsManager::registerScreenOpen)
|
||||
navController.pushNew(screen)
|
||||
}
|
||||
|
||||
private val backEventsObservers: MutableList<BackEventObserver> = mutableListOf()
|
||||
|
||||
fun navigateBack() {
|
||||
val closedScreen = childStack.items.lastOrNull()?.configuration
|
||||
backEventsObservers.forEach { observer ->
|
||||
observer.onBack(closedScreen)
|
||||
}
|
||||
hideSelectDialog()
|
||||
"Pop ${closedScreen?.simpleName}".makeLog("Navigator")
|
||||
navController.pop()
|
||||
}
|
||||
|
||||
fun addBackEventsObserver(
|
||||
observer: BackEventObserver
|
||||
) {
|
||||
backEventsObservers.add(observer)
|
||||
}
|
||||
|
||||
fun removeBackEventsObserver(
|
||||
observer: BackEventObserver
|
||||
) {
|
||||
backEventsObservers.remove(observer)
|
||||
}
|
||||
|
||||
fun handleDeeplinks(intent: Intent?) {
|
||||
intent.handleDeeplinks(
|
||||
onStart = ::hideSelectDialog,
|
||||
onHasExtraDataType = ::updateExtraDataType,
|
||||
onColdStart = ::cancelShowingExitDialog,
|
||||
onGetUris = ::updateUris,
|
||||
onNavigate = ::navigateTo,
|
||||
isHasUris = !uris.isNullOrEmpty(),
|
||||
onWantGithubReview = ::onWantGithubReview,
|
||||
isOpenEditInsteadOfPreview = settingsState.openEditInsteadOfPreview
|
||||
)
|
||||
}
|
||||
|
||||
private fun Screen.saveToHistory() = apply {
|
||||
if (id < 0) return@apply
|
||||
|
||||
componentScope.launch {
|
||||
appHistoryRepository.pushLastTool(id)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@AssistedFactory
|
||||
fun interface Factory {
|
||||
operator fun invoke(
|
||||
componentContext: ComponentContext
|
||||
): RootComponent
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user