Skip to content

Commit 3b28758

Browse files
authored
Server setup redesign (#137)
* Server setup redesign * Remove stub navigation * Update translations / UI * Update models * Implement keyboard hide effect
1 parent 5f5874e commit 3b28758

File tree

33 files changed

+1806
-999
lines changed

33 files changed

+1806
-999
lines changed

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ android {
2525

2626
buildConfigField "String", "HORDE_AI_SIGN_UP_URL", "\"https://stablehorde.net/register\""
2727
buildConfigField "String", "HUGGING_FACE_INFO_URL", "\"https://huggingface.co/docs/api-inference/index\""
28+
buildConfigField "String", "OPEN_AI_INFO_URL", "\"https://platform.openai.com/api-keys\""
2829
buildConfigField "String", "UPDATE_API_URL", "\"https://sdai.moroz.cc\""
2930
buildConfigField "String", "DEMO_MODE_API_URL", "\"https://sdai.moroz.cc\""
3031
buildConfigField "String", "POLICY_URL", "\"https://sdai.moroz.cc/policy.html\""

app/src/main/java/com/shifthackz/aisdv1/app/di/ProvidersModule.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ val providersModule = module {
9393
override val hordeUrl: String = BuildConfig.HORDE_AI_URL
9494
override val hordeSignUpUrl: String = BuildConfig.HORDE_AI_SIGN_UP_URL
9595
override val huggingFaceUrl: String = BuildConfig.HUGGING_FACE_INFO_URL
96+
override val openAiInfoUrl: String = BuildConfig.OPEN_AI_INFO_URL
9697
override val privacyPolicyUrl: String = BuildConfig.POLICY_URL
9798
override val gitHubSourceUrl: String = BuildConfig.GITHUB_SOURCE_URL
9899
override val setupInstructionsUrl: String = BuildConfig.SETUP_INSTRUCTIONS_URL

core/common/src/main/java/com/shifthackz/aisdv1/core/common/links/LinksProvider.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ interface LinksProvider {
44
val hordeUrl: String
55
val hordeSignUpUrl: String
66
val huggingFaceUrl: String
7+
val openAiInfoUrl: String
78
val privacyPolicyUrl: String
89
val gitHubSourceUrl: String
910
val setupInstructionsUrl: String

core/ui/src/main/java/com/shifthackz/aisdv1/core/ui/MviContract.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
package com.shifthackz.aisdv1.core.ui
44

55
interface MviState
6+
interface MviIntent
67
interface MviEffect
78

89
object EmptyState : MviState
10+
object EmptyIntent : MviIntent
911
object EmptyEffect : MviEffect

core/ui/src/main/java/com/shifthackz/aisdv1/core/ui/MviExtensions.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,44 @@
22

33
package com.shifthackz.aisdv1.core.ui
44

5+
import androidx.compose.material3.MaterialTheme
56
import androidx.compose.runtime.Composable
67
import androidx.compose.ui.graphics.Color
8+
import androidx.compose.ui.graphics.luminance
79
import androidx.lifecycle.compose.collectAsStateWithLifecycle
810
import com.shifthackz.aisdv1.core.viewmodel.MviViewModel
11+
import com.shifthackz.aisdv1.core.viewmodel.MviViewModel2
12+
13+
@Composable
14+
fun <S : MviState, I: MviIntent, E : MviEffect> MviComposable2(
15+
viewModel: MviViewModel2<S, I, E>,
16+
effectHandler: (E) -> Unit = {},
17+
statusBarColor: Color = MaterialTheme.colorScheme.background,
18+
statusBarDarkIcons: Boolean = statusBarColor.luminance() > 0.5f,
19+
navigationBarColor: Color = MaterialTheme.colorScheme.background,
20+
content: @Composable (S) -> Unit,
21+
) = object : MviScreen2<S, I, E>(viewModel) {
22+
23+
@Composable
24+
override fun statusBarColor(): Color = statusBarColor
25+
26+
@Composable
27+
override fun statusBarDarkIcons(): Boolean = statusBarDarkIcons
28+
29+
@Composable
30+
override fun navigationBarColor(): Color = navigationBarColor
31+
32+
@Composable
33+
override fun Content() {
34+
val state = viewModel.state.collectAsStateWithLifecycle().value
35+
content(state)
36+
}
37+
38+
override fun processEffect(effect: E) {
39+
effectHandler(effect)
40+
}
41+
}.Build()
42+
943

1044
@Composable
1145
fun <S : MviState, E : MviEffect> MviComposable(
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
@file:Suppress("MemberVisibilityCanBePrivate")
2+
3+
package com.shifthackz.aisdv1.core.ui
4+
5+
import androidx.compose.runtime.Composable
6+
import androidx.compose.runtime.LaunchedEffect
7+
import com.shifthackz.aisdv1.core.viewmodel.MviViewModel
8+
import com.shifthackz.aisdv1.core.viewmodel.MviViewModel2
9+
10+
abstract class MviScreen2<S : MviState, I : MviIntent, E : MviEffect>(
11+
private val viewModel: MviViewModel2<S, I, E>,
12+
) : Screen() {
13+
14+
@Composable
15+
override fun Build() {
16+
LaunchedEffect(KEY_EFFECTS_PROCESSOR) {
17+
viewModel.effectStream.collect(::processEffect)
18+
}
19+
ApplySystemUiColors()
20+
Content()
21+
}
22+
23+
protected open fun processEffect(effect: E) = Unit
24+
25+
companion object {
26+
private const val KEY_EFFECTS_PROCESSOR = "key_effects_processor"
27+
}
28+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@file:Suppress("unused")
2+
3+
package com.shifthackz.aisdv1.core.viewmodel
4+
5+
import com.shifthackz.aisdv1.core.contract.RxDisposableContract
6+
import com.shifthackz.aisdv1.core.ui.MviEffect
7+
import com.shifthackz.aisdv1.core.ui.MviIntent
8+
import com.shifthackz.aisdv1.core.ui.MviState
9+
import io.reactivex.rxjava3.disposables.CompositeDisposable
10+
11+
abstract class MviRxViewModel2<S : MviState, I : MviIntent, E : MviEffect> : MviViewModel2<S, I, E>(),
12+
RxDisposableContract {
13+
14+
override val compositeDisposable = CompositeDisposable()
15+
16+
override fun onCleared() {
17+
super.onCleared()
18+
compositeDisposable.clear()
19+
}
20+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
@file:Suppress("MemberVisibilityCanBePrivate", "unused")
2+
3+
package com.shifthackz.aisdv1.core.viewmodel
4+
5+
import android.util.Log
6+
import androidx.lifecycle.ViewModel
7+
import androidx.lifecycle.viewModelScope
8+
import com.shifthackz.aisdv1.core.common.log.debugLog
9+
import com.shifthackz.aisdv1.core.ui.BuildConfig
10+
import com.shifthackz.aisdv1.core.ui.MviEffect
11+
import com.shifthackz.aisdv1.core.ui.MviIntent
12+
import com.shifthackz.aisdv1.core.ui.MviState
13+
import kotlinx.coroutines.CoroutineExceptionHandler
14+
import kotlinx.coroutines.Dispatchers
15+
import kotlinx.coroutines.channels.Channel
16+
import kotlinx.coroutines.flow.Flow
17+
import kotlinx.coroutines.flow.MutableStateFlow
18+
import kotlinx.coroutines.flow.StateFlow
19+
import kotlinx.coroutines.flow.asStateFlow
20+
import kotlinx.coroutines.flow.receiveAsFlow
21+
import kotlinx.coroutines.flow.update
22+
import kotlinx.coroutines.launch
23+
24+
abstract class MviViewModel2<S : MviState, I : MviIntent, E : MviEffect> : ViewModel() {
25+
26+
private val mutableState: MutableStateFlow<S> by lazy { MutableStateFlow(emptyState) }
27+
private val effectChannel: Channel<E> = Channel()
28+
29+
private val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
30+
throwable.printStackTrace()
31+
}
32+
33+
protected val currentState: S
34+
get() = state.value
35+
36+
val state: StateFlow<S> by lazy { mutableState.asStateFlow() }
37+
val effectStream: Flow<E> = effectChannel.receiveAsFlow()
38+
39+
abstract val emptyState: S
40+
41+
abstract fun handleIntent(intent: I)
42+
43+
open fun updateState(mutation: (S) -> S) = mutableState.update {
44+
if (BuildConfig.DEBUG) debugLog("NEW STATE : $state")
45+
mutation(it)
46+
}
47+
48+
fun emitEffect(effect: E) {
49+
viewModelScope.launch(Dispatchers.Main.immediate + exceptionHandler) {
50+
effectChannel.send(effect)
51+
}
52+
}
53+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,6 @@ class PreferenceManagerImpl(
154154
private const val KEY_HUGGING_FACE_MODEL_KEY = "key_hugging_face_model_key"
155155
private const val KEY_LOCAL_NN_API = "key_local_nn_api"
156156
private const val KEY_LOCAL_MODEL_ID = "key_local_model_id"
157-
private const val KEY_FORCE_SETUP_AFTER_UPDATE = "force_upd_setup_v0.x.x-v0.5.3"
157+
private const val KEY_FORCE_SETUP_AFTER_UPDATE = "force_upd_setup_v0.x.x-v0.5.8"
158158
}
159159
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.shifthackz.aisdv1.domain.entity
2+
3+
enum class FeatureTag {
4+
Txt2Img,
5+
Img2Img,
6+
Lora,
7+
TextualInversion,
8+
HyperNetworks,
9+
Batch,
10+
MultipleModels,
11+
Offline,
12+
}

0 commit comments

Comments
 (0)