Skip to content

Commit 451bff6

Browse files
authored
Generation form redesign (#44)
* Generation form redesign * Update
1 parent 43602df commit 451bff6

File tree

20 files changed

+258
-72
lines changed

20 files changed

+258
-72
lines changed

data/src/main/java/com/shifthackz/aisdv1/data/preference/PreferenceManagerImpl.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ class PreferenceManagerImpl(
5353
.apply()
5454
.also { onPreferencesChanged() }
5555

56+
override var formAdvancedOptionsAlwaysShow: Boolean
57+
get() = preferences.getBoolean(KEY_FORM_ALWAYS_SHOW_ADVANCED_OPTIONS, false)
58+
set(value) = preferences.edit()
59+
.putBoolean(KEY_FORM_ALWAYS_SHOW_ADVANCED_OPTIONS, value)
60+
.apply()
61+
.also { onPreferencesChanged() }
62+
5663
override fun observe(): Flowable<Settings> = preferencesChangedSubject
5764
.toFlowable(BackpressureStrategy.LATEST)
5865
.map {
@@ -62,6 +69,7 @@ class PreferenceManagerImpl(
6269
useSdAiCloud = useSdAiCloud,
6370
monitorConnectivity = monitorConnectivity,
6471
autoSaveAiResults = autoSaveAiResults,
72+
formAdvancedOptionsAlwaysShow = formAdvancedOptionsAlwaysShow,
6573
)
6674
}
6775

@@ -73,5 +81,6 @@ class PreferenceManagerImpl(
7381
private const val KEY_SD_AI_CLOUD_MODE = "key_sd_ai_cloud_mode"
7482
private const val KEY_MONITOR_CONNECTIVITY = "key_monitor_connectivity"
7583
private const val KEY_AI_AUTO_SAVE = "key_ai_auto_save"
84+
private const val KEY_FORM_ALWAYS_SHOW_ADVANCED_OPTIONS = "key_always_show_advanced_options"
7685
}
7786
}

domain/src/main/java/com/shifthackz/aisdv1/domain/entity/Settings.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ data class Settings(
66
val useSdAiCloud: Boolean,
77
val monitorConnectivity: Boolean,
88
val autoSaveAiResults: Boolean,
9+
val formAdvancedOptionsAlwaysShow: Boolean,
910
)

domain/src/main/java/com/shifthackz/aisdv1/domain/preference/PreferenceManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ interface PreferenceManager {
99
var useSdAiCloud: Boolean
1010
var monitorConnectivity: Boolean
1111
var autoSaveAiResults: Boolean
12+
var formAdvancedOptionsAlwaysShow: Boolean
1213

1314
fun observe(): Flowable<Settings>
1415
}

presentation/src/main/java/com/shifthackz/aisdv1/presentation/core/GenerationMviState.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import com.shifthackz.aisdv1.core.model.UiText
44
import com.shifthackz.aisdv1.core.ui.MviState
55

66
abstract class GenerationMviState : MviState {
7+
abstract val advancedToggleButtonVisible: Boolean
8+
abstract val advancedOptionsVisible: Boolean
79
abstract val prompt: String
810
abstract val negativePrompt: String
911
abstract val width: String
@@ -22,6 +24,8 @@ abstract class GenerationMviState : MviState {
2224
get() = widthValidationError != null || heightValidationError != null
2325

2426
open fun copyState(
27+
advancedToggleButtonVisible: Boolean = this.advancedToggleButtonVisible,
28+
advancedOptionsVisible: Boolean = this.advancedOptionsVisible,
2529
prompt: String = this.prompt,
2630
negativePrompt: String = this.negativePrompt,
2731
width: String = this.width,

presentation/src/main/java/com/shifthackz/aisdv1/presentation/core/GenerationMviViewModel.kt

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,43 @@ import com.shifthackz.aisdv1.core.common.schedulers.subscribeOnMainThread
1111
import com.shifthackz.aisdv1.core.ui.MviEffect
1212
import com.shifthackz.aisdv1.core.viewmodel.MviRxViewModel
1313
import com.shifthackz.aisdv1.domain.entity.StableDiffusionSampler
14+
import com.shifthackz.aisdv1.domain.preference.PreferenceManager
1415
import com.shifthackz.aisdv1.domain.usecase.coin.ObserveCoinsUseCase
1516
import com.shifthackz.aisdv1.domain.usecase.sdsampler.GetStableDiffusionSamplersUseCase
1617
import io.reactivex.rxjava3.kotlin.subscribeBy
1718

1819
abstract class GenerationMviViewModel<S : GenerationMviState, E : MviEffect>(
1920
buildInfoProvider: BuildInfoProvider,
21+
preferenceManager: PreferenceManager,
2022
observeCoinsUseCase: ObserveCoinsUseCase,
2123
getStableDiffusionSamplersUseCase: GetStableDiffusionSamplersUseCase,
2224
schedulersProvider: SchedulersProvider,
2325
) : MviRxViewModel<S, E>() {
2426

2527
init {
28+
!preferenceManager.observe()
29+
.subscribeOnMainThread(schedulersProvider)
30+
.subscribeBy(
31+
onError = ::errorLog,
32+
onComplete = EmptyLambda,
33+
onNext = { settings ->
34+
currentState
35+
.copyState(
36+
advancedToggleButtonVisible = !settings.formAdvancedOptionsAlwaysShow
37+
)
38+
.let { state ->
39+
if (!settings.formAdvancedOptionsAlwaysShow) state
40+
else state.copyState(advancedOptionsVisible = true)
41+
}
42+
.let(::setGenerationState)
43+
}
44+
)
45+
2646
!getStableDiffusionSamplersUseCase()
2747
.map { samplers -> samplers.map(StableDiffusionSampler::name) }
2848
.subscribeOnMainThread(schedulersProvider)
2949
.subscribeBy(
30-
onError = { t -> t.printStackTrace() },
50+
onError = ::errorLog,
3151
onSuccess = { samplers ->
3252
currentState
3353
.copyState(
@@ -53,7 +73,11 @@ abstract class GenerationMviViewModel<S : GenerationMviState, E : MviEffect>(
5373
}
5474
}
5575

56-
fun updatePrompt(value: String) = (currentState)
76+
fun toggleAdvancedOptions(value: Boolean) = currentState
77+
.copyState(advancedOptionsVisible = value)
78+
.let(::setGenerationState)
79+
80+
fun updatePrompt(value: String) = currentState
5781
.copyState(prompt = value)
5882
.let(::setGenerationState)
5983

presentation/src/main/java/com/shifthackz/aisdv1/presentation/features/AnalyticsEvents.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ data class AutoSaveAiResultsChanged(val value: Boolean) : AnalyticsEvent(
6060
name = "settings_auto_save_change",
6161
parameters = mapOf("enabled" to "$value"),
6262
)
63+
64+
data class FormAdvancedOptionsAlwaysShowChanged(val value: Boolean) : AnalyticsEvent(
65+
name = "settings_form_advanced_options_always_show_change",
66+
parameters = mapOf("enabled" to "$value"),
67+
)
6368
//endregion
6469

6570
//region GENERATION EVENTS

presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageContract.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ data class ImageToImageState(
1515
val imageBase64: String = "",
1616
val screenDialog: Dialog = Dialog.None,
1717
val denoisingStrength: Float = 0.75f,
18+
override val advancedToggleButtonVisible: Boolean = true,
19+
override val advancedOptionsVisible: Boolean = false,
1820
override val prompt: String = "",
1921
override val negativePrompt: String = "",
2022
override val width: String = 512.toString(),
@@ -48,6 +50,8 @@ data class ImageToImageState(
4850
}
4951

5052
override fun copyState(
53+
advancedToggleButtonVisible: Boolean,
54+
advancedOptionsVisible: Boolean,
5155
prompt: String,
5256
negativePrompt: String,
5357
width: String,
@@ -62,6 +66,8 @@ data class ImageToImageState(
6266
heightValidationError: UiText?,
6367
generateButtonEnabled: Boolean
6468
): GenerationMviState = copy(
69+
advancedToggleButtonVisible = advancedToggleButtonVisible,
70+
advancedOptionsVisible = advancedOptionsVisible,
6571
prompt = prompt,
6672
negativePrompt = negativePrompt,
6773
width = width,

presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageScreen.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.compose.foundation.*
66
import androidx.compose.foundation.layout.*
77
import androidx.compose.foundation.shape.RoundedCornerShape
88
import androidx.compose.material.icons.Icons
9+
import androidx.compose.material.icons.filled.AutoFixNormal
910
import androidx.compose.material.icons.filled.BrowseGallery
1011
import androidx.compose.material.icons.filled.Camera
1112
import androidx.compose.material.icons.filled.Delete
@@ -26,12 +27,12 @@ import com.shifthackz.aisdv1.domain.entity.AiGenerationResult
2627
import com.shifthackz.aisdv1.presentation.R
2728
import com.shifthackz.aisdv1.presentation.theme.sliderColors
2829
import com.shifthackz.aisdv1.presentation.utils.Constants
29-
import com.shifthackz.aisdv1.presentation.widget.GenerationInputForm
3030
import com.shifthackz.aisdv1.presentation.widget.coins.AvailableCoinsComposable
3131
import com.shifthackz.aisdv1.presentation.widget.dialog.ErrorDialog
3232
import com.shifthackz.aisdv1.presentation.widget.dialog.GenerationImageResultDialog
3333
import com.shifthackz.aisdv1.presentation.widget.dialog.NoSdAiCoinsDialog
3434
import com.shifthackz.aisdv1.presentation.widget.dialog.ProgressDialog
35+
import com.shifthackz.aisdv1.presentation.widget.input.GenerationInputForm
3536
import com.shz.imagepicker.imagepicker.ImagePickerCallback
3637
import org.koin.androidx.compose.koinViewModel
3738

@@ -51,6 +52,7 @@ class ImageToImageScreen(
5152
onTakePhoto = { takePhoto(viewModel::updateInputImage) },
5253
onClearPhoto = viewModel::clearInputImage,
5354
onDenoisingStrengthUpdated = viewModel::updateDenoisingStrength,
55+
onShowAdvancedOptionsToggle = viewModel::toggleAdvancedOptions,
5456
onPromptUpdated = viewModel::updatePrompt,
5557
onNegativePromptUpdated = viewModel::updateNegativePrompt,
5658
onWidthUpdated = viewModel::updateWidth,
@@ -79,6 +81,7 @@ private fun ScreenContent(
7981
onTakePhoto: () -> Unit = {},
8082
onClearPhoto: () -> Unit = {},
8183
onDenoisingStrengthUpdated: (Float) -> Unit,
84+
onShowAdvancedOptionsToggle: (Boolean) -> Unit = {},
8285
onPromptUpdated: (String) -> Unit = {},
8386
onNegativePromptUpdated: (String) -> Unit = {},
8487
onWidthUpdated: (String) -> Unit = {},
@@ -122,6 +125,7 @@ private fun ScreenContent(
122125
)
123126
GenerationInputForm(
124127
state = state,
128+
onShowAdvancedOptionsToggle = onShowAdvancedOptionsToggle,
125129
onPromptUpdated = onPromptUpdated,
126130
onNegativePromptUpdated = onNegativePromptUpdated,
127131
onWidthUpdated = onWidthUpdated,
@@ -168,7 +172,13 @@ private fun ScreenContent(
168172
onClick = onGenerateClicked,
169173
enabled = !state.hasValidationErrors && !state.imageState.isEmpty,
170174
) {
175+
Icon(
176+
modifier = Modifier.size(18.dp),
177+
imageVector = Icons.Default.AutoFixNormal,
178+
contentDescription = "Imagine",
179+
)
171180
Text(
181+
modifier = Modifier.padding(start = 8.dp),
172182
text = stringResource(id = R.string.action_generate)
173183
)
174184
}

presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/img2img/ImageToImageViewModel.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class ImageToImageViewModel(
3434
private val analytics: Analytics,
3535
) : GenerationMviViewModel<ImageToImageState, ImageToImageEffect>(
3636
buildInfoProvider,
37+
preferenceManager,
3738
observeCoinsUseCase,
3839
getStableDiffusionSamplersUseCase,
3940
schedulersProvider,

presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/settings/SettingsContract.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ sealed interface SettingsState : MviState {
1919
val sdModelSelected: String,
2020
val monitorConnectivity: Boolean,
2121
val autoSaveAiResults: Boolean,
22+
val formAdvancedOptionsAlwaysShow: Boolean,
2223
val appVersion: String,
2324
val showRewardedSdAiAd: Boolean,
2425
val showSdModelSelector: Boolean,

0 commit comments

Comments
 (0)