Skip to content

Commit c8f5e2d

Browse files
authored
Onboarding animation fix (#340)
* Updated onboarding animation & refactored some composables * Resolved PR comments & refactored some ui elements * Resolved rebase conflicts & updated onboarding animation + donate screen ui * Updated onboarding animation * Updated onboarding animation
1 parent 177a572 commit c8f5e2d

File tree

6 files changed

+113
-58
lines changed

6 files changed

+113
-58
lines changed

presentation/src/main/java/com/shifthackz/aisdv1/presentation/modal/embedding/EmbeddingScreen.kt

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.shifthackz.aisdv1.presentation.modal.embedding
22

3-
import androidx.compose.foundation.background
4-
import androidx.compose.foundation.border
53
import androidx.compose.foundation.clickable
64
import androidx.compose.foundation.layout.Arrangement
75
import androidx.compose.foundation.layout.Box
@@ -34,7 +32,10 @@ import androidx.compose.runtime.setValue
3432
import androidx.compose.ui.Alignment
3533
import androidx.compose.ui.Modifier
3634
import androidx.compose.ui.draw.clip
35+
import androidx.compose.ui.draw.drawBehind
36+
import androidx.compose.ui.geometry.CornerRadius
3737
import androidx.compose.ui.graphics.Color
38+
import androidx.compose.ui.graphics.drawscope.Stroke
3839
import androidx.compose.ui.layout.onSizeChanged
3940
import androidx.compose.ui.platform.LocalDensity
4041
import androidx.compose.ui.res.painterResource
@@ -45,13 +46,13 @@ import androidx.compose.ui.unit.sp
4546
import androidx.compose.ui.window.Dialog
4647
import androidx.compose.ui.window.DialogProperties
4748
import com.shifthackz.aisdv1.core.extensions.shimmer
48-
import com.shifthackz.android.core.mvi.MviComponent
4949
import com.shifthackz.aisdv1.domain.entity.ServerSource
5050
import com.shifthackz.aisdv1.presentation.modal.extras.ExtrasEffect
5151
import com.shifthackz.aisdv1.presentation.model.ErrorState
5252
import com.shifthackz.aisdv1.presentation.widget.error.ErrorComposable
5353
import com.shifthackz.aisdv1.presentation.widget.source.getName
5454
import com.shifthackz.aisdv1.presentation.widget.toolbar.ModalDialogToolbar
55+
import com.shifthackz.android.core.mvi.MviComponent
5556
import org.koin.androidx.compose.koinViewModel
5657
import com.shifthackz.aisdv1.core.localization.R as LocalizationR
5758
import com.shifthackz.aisdv1.presentation.R as PresentationR
@@ -144,22 +145,33 @@ private fun ScreenContent(
144145
if (!state.loading && state.embeddings.isNotEmpty()) {
145146
Row(
146147
modifier = modifier
147-
.padding(horizontal = 12.dp)
148148
.fillMaxWidth()
149149
.height(intrinsicSize = IntrinsicSize.Max)
150-
.clip(RoundedCornerShape(16.dp))
151-
.background(color = bgColor)
152150
.onSizeChanged {
153151
if (it.height > dividerHeight) dividerHeight = it.height
154-
},
152+
}
153+
.drawBehind {
154+
drawRoundRect(
155+
color = bgColor,
156+
cornerRadius = CornerRadius(16.dp.toPx())
157+
)
158+
}
159+
.padding(horizontal = 12.dp),
155160
) {
161+
val selectorBgColor =
162+
if (state.selector) MaterialTheme.colorScheme.primary else Color.Transparent
156163
Box(
157164
modifier = Modifier
158165
.fillMaxWidth()
159166
.height(with(LocalDensity.current) { dividerHeight.toDp() })
160167
.weight(1f)
161168
.clip(RoundedCornerShape(16.dp))
162-
.background(color = if (state.selector) MaterialTheme.colorScheme.primary else Color.Transparent)
169+
.drawBehind {
170+
drawRoundRect(
171+
color = selectorBgColor,
172+
cornerRadius = CornerRadius(16.dp.toPx())
173+
)
174+
}
163175
.clickable { processIntent(EmbeddingIntent.ChangeSelector(true)) },
164176
contentAlignment = Alignment.Center,
165177
) {
@@ -175,7 +187,12 @@ private fun ScreenContent(
175187
.fillMaxWidth()
176188
.weight(1f)
177189
.clip(RoundedCornerShape(16.dp))
178-
.background(color = if (!state.selector) MaterialTheme.colorScheme.primary else Color.Transparent)
190+
.drawBehind {
191+
drawRoundRect(
192+
color = selectorBgColor,
193+
cornerRadius = CornerRadius(16.dp.toPx())
194+
)
195+
}
179196
.clickable { processIntent(EmbeddingIntent.ChangeSelector(false)) },
180197
contentAlignment = Alignment.Center,
181198
) {
@@ -272,17 +289,25 @@ private fun EmbeddingItemComposable(
272289
onItemToggle: (EmbeddingItemUi) -> Unit,
273290
) {
274291
val isApplied = (selector && item.isInPrompt) || (!selector && item.isInNegativePrompt)
292+
val bgColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)
293+
val borderColor = MaterialTheme.colorScheme.primary
275294
Row(
276295
modifier = Modifier
277296
.padding(horizontal = 12.dp, vertical = 6.dp)
278297
.fillMaxWidth()
279298
.clip(RoundedCornerShape(16.dp))
280-
.background(color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f))
281-
.border(
282-
width = 2.dp,
283-
color = if (isApplied) MaterialTheme.colorScheme.primary else Color.Transparent,
284-
shape = RoundedCornerShape(16.dp),
285-
)
299+
.drawBehind {
300+
drawRoundRect(
301+
color = bgColor,
302+
cornerRadius = CornerRadius(16.dp.toPx()),
303+
)
304+
if (!isApplied) return@drawBehind
305+
drawRoundRect(
306+
color = borderColor,
307+
style = Stroke(2.dp.toPx()),
308+
cornerRadius = CornerRadius(16.dp.toPx()),
309+
)
310+
}
286311
.clickable { onItemToggle(item) }
287312
.padding(vertical = 8.dp, horizontal = 12.dp),
288313
verticalAlignment = Alignment.CenterVertically,

presentation/src/main/java/com/shifthackz/aisdv1/presentation/modal/extras/ExtrasScreen.kt

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.shifthackz.aisdv1.presentation.modal.extras
22

3-
import androidx.compose.foundation.background
4-
import androidx.compose.foundation.border
53
import androidx.compose.foundation.clickable
64
import androidx.compose.foundation.layout.Arrangement
75
import androidx.compose.foundation.layout.Box
@@ -33,7 +31,9 @@ import androidx.compose.runtime.Composable
3331
import androidx.compose.ui.Alignment
3432
import androidx.compose.ui.Modifier
3533
import androidx.compose.ui.draw.clip
36-
import androidx.compose.ui.graphics.Color
34+
import androidx.compose.ui.draw.drawBehind
35+
import androidx.compose.ui.geometry.CornerRadius
36+
import androidx.compose.ui.graphics.drawscope.Stroke
3737
import androidx.compose.ui.res.stringResource
3838
import androidx.compose.ui.text.style.TextAlign
3939
import androidx.compose.ui.text.style.TextOverflow
@@ -42,13 +42,13 @@ import androidx.compose.ui.unit.sp
4242
import androidx.compose.ui.window.Dialog
4343
import androidx.compose.ui.window.DialogProperties
4444
import com.shifthackz.aisdv1.core.extensions.shimmer
45-
import com.shifthackz.android.core.mvi.MviComponent
4645
import com.shifthackz.aisdv1.domain.entity.ServerSource
4746
import com.shifthackz.aisdv1.presentation.model.ErrorState
4847
import com.shifthackz.aisdv1.presentation.model.ExtraType
4948
import com.shifthackz.aisdv1.presentation.widget.error.ErrorComposable
5049
import com.shifthackz.aisdv1.presentation.widget.source.getName
5150
import com.shifthackz.aisdv1.presentation.widget.toolbar.ModalDialogToolbar
51+
import com.shifthackz.android.core.mvi.MviComponent
5252
import org.koin.androidx.compose.koinViewModel
5353
import com.shifthackz.aisdv1.core.localization.R as LocalizationR
5454

@@ -174,8 +174,8 @@ private fun ScreenContent(
174174
) { index ->
175175
ExtrasItemComposable(
176176
item = state.loras[index],
177-
onLoraSelected = {
178-
processIntent(ExtrasIntent.ToggleItem(it))
177+
onLoraSelected = { item ->
178+
processIntent(ExtrasIntent.ToggleItem(item))
179179
},
180180
)
181181
}
@@ -204,6 +204,7 @@ private fun ExtrasEmptyState(type: ExtraType, source: ServerSource) {
204204
ServerSource.SWARM_UI -> "../Models/Lora"
205205
else -> ""
206206
}
207+
207208
ExtraType.HyperNet -> when (source) {
208209
ServerSource.AUTOMATIC1111 -> "../models/hypernetworks"
209210
ServerSource.SWARM_UI -> ""
@@ -234,16 +235,24 @@ private fun ExtrasItemComposable(
234235
item: ExtraItemUi,
235236
onLoraSelected: (ExtraItemUi) -> Unit,
236237
) {
238+
val bgColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)
239+
val borderColor = MaterialTheme.colorScheme.primary
237240
Row(
238241
modifier = modifier
239242
.fillMaxWidth()
240243
.clip(RoundedCornerShape(16.dp))
241-
.background(color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f))
242-
.border(
243-
width = 2.dp,
244-
color = if (item.isApplied) MaterialTheme.colorScheme.primary else Color.Transparent,
245-
shape = RoundedCornerShape(16.dp),
246-
)
244+
.drawBehind {
245+
drawRoundRect(
246+
color = bgColor,
247+
cornerRadius = CornerRadius(16.dp.toPx()),
248+
)
249+
if (!item.isApplied) return@drawBehind
250+
drawRoundRect(
251+
color = borderColor,
252+
style = Stroke(2.dp.toPx()),
253+
cornerRadius = CornerRadius(16.dp.toPx()),
254+
)
255+
}
247256
.clickable { onLoraSelected(item) }
248257
.padding(16.dp),
249258
verticalAlignment = Alignment.CenterVertically,

presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/donate/DonateScreen.kt

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package com.shifthackz.aisdv1.presentation.screen.donate
55
import androidx.compose.animation.AnimatedContent
66
import androidx.compose.foundation.Canvas
77
import androidx.compose.foundation.Image
8-
import androidx.compose.foundation.background
98
import androidx.compose.foundation.layout.Arrangement
109
import androidx.compose.foundation.layout.Box
1110
import androidx.compose.foundation.layout.Column
@@ -37,6 +36,8 @@ import androidx.compose.runtime.Composable
3736
import androidx.compose.ui.Alignment
3837
import androidx.compose.ui.Modifier
3938
import androidx.compose.ui.draw.clip
39+
import androidx.compose.ui.draw.drawBehind
40+
import androidx.compose.ui.geometry.CornerRadius
4041
import androidx.compose.ui.graphics.Brush
4142
import androidx.compose.ui.graphics.Color
4243
import androidx.compose.ui.layout.ContentScale
@@ -48,9 +49,9 @@ import androidx.compose.ui.tooling.preview.Preview
4849
import androidx.compose.ui.unit.dp
4950
import androidx.compose.ui.unit.sp
5051
import com.shifthackz.aisdv1.core.common.extensions.openUrl
51-
import com.shifthackz.android.core.mvi.MviComponent
5252
import com.shifthackz.aisdv1.domain.entity.Supporter
5353
import com.shifthackz.aisdv1.presentation.widget.item.SupporterItem
54+
import com.shifthackz.android.core.mvi.MviComponent
5455
import org.koin.androidx.compose.koinViewModel
5556
import java.util.Date
5657
import com.shifthackz.aisdv1.core.localization.R as LocalizationR
@@ -104,12 +105,18 @@ private fun DonateScreenContent(
104105
topStart = 24.dp,
105106
topEnd = 24.dp,
106107
)
108+
val bottomBgColor = MaterialTheme.colorScheme.surface
107109
Column(
108110
modifier = Modifier
109111
.navigationBarsPadding()
110112
.fillMaxWidth()
111-
.background(MaterialTheme.colorScheme.surface, shape)
112113
.clip(shape)
114+
.drawBehind {
115+
drawRoundRect(
116+
color = bottomBgColor,
117+
cornerRadius = CornerRadius(24.dp.toPx()),
118+
)
119+
}
113120
.padding(horizontal = 16.dp)
114121
) {
115122
Row(
@@ -200,12 +207,19 @@ private fun DonateScreenContent(
200207
MaterialTheme.colorScheme.surfaceTint.copy(alpha = 0.8f)
201208
SupporterItem(
202209
modifier = Modifier
203-
.padding(horizontal = 12.dp)
204-
.padding(top = if (index == 0) 8.dp else 4.dp)
205-
.padding(bottom = 4.dp)
206210
.fillMaxWidth()
207-
.background(bgColor, shape)
208-
.clip(shape),
211+
.padding(
212+
top = if (index == 0) 8.dp else 4.dp,
213+
bottom = 4.dp,
214+
)
215+
.padding(horizontal = 12.dp)
216+
.clip(shape)
217+
.drawBehind {
218+
drawRoundRect(
219+
color = bgColor,
220+
cornerRadius = CornerRadius(12.dp.toPx()),
221+
)
222+
},
209223
supporter = supporter,
210224
)
211225
}

presentation/src/main/java/com/shifthackz/aisdv1/presentation/screen/onboarding/OnBoardingScreen.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.shifthackz.aisdv1.presentation.screen.onboarding
22

33
import androidx.activity.compose.BackHandler
44
import androidx.compose.animation.core.animateFloatAsState
5-
import androidx.compose.foundation.background
65
import androidx.compose.foundation.layout.Arrangement
76
import androidx.compose.foundation.layout.Box
87
import androidx.compose.foundation.layout.Column
@@ -16,7 +15,6 @@ import androidx.compose.foundation.layout.padding
1615
import androidx.compose.foundation.layout.size
1716
import androidx.compose.foundation.pager.HorizontalPager
1817
import androidx.compose.foundation.pager.rememberPagerState
19-
import androidx.compose.foundation.shape.CircleShape
2018
import androidx.compose.foundation.shape.RoundedCornerShape
2119
import androidx.compose.material.icons.Icons
2220
import androidx.compose.material.icons.filled.Check
@@ -36,14 +34,15 @@ import androidx.compose.ui.Alignment
3634
import androidx.compose.ui.Modifier
3735
import androidx.compose.ui.draw.alpha
3836
import androidx.compose.ui.draw.clip
37+
import androidx.compose.ui.draw.drawBehind
3938
import androidx.compose.ui.draw.rotate
4039
import androidx.compose.ui.unit.dp
41-
import com.shifthackz.android.core.mvi.MviComponent
4240
import com.shifthackz.aisdv1.presentation.model.LaunchSource
4341
import com.shifthackz.aisdv1.presentation.screen.onboarding.page.FormPageContent
4442
import com.shifthackz.aisdv1.presentation.screen.onboarding.page.LocalDiffusionPageContent
4543
import com.shifthackz.aisdv1.presentation.screen.onboarding.page.LookAndFeelPageContent
4644
import com.shifthackz.aisdv1.presentation.screen.onboarding.page.ProviderPageContent
45+
import com.shifthackz.android.core.mvi.MviComponent
4746
import kotlinx.coroutines.Job
4847
import kotlinx.coroutines.launch
4948

@@ -78,6 +77,7 @@ private fun OnBoardingScreenContent(
7877

7978
fun scrollToPage(page: Int) {
8079
if (scrollAnimationJob != null) return
80+
if (pagerState.isScrollInProgress) return
8181
scrollAnimationJob = scope.launch {
8282
pagerState.animateScrollToPage(
8383
page = page,
@@ -86,7 +86,7 @@ private fun OnBoardingScreenContent(
8686
}.apply { invokeOnCompletion { scrollAnimationJob = null } }
8787
}
8888

89-
BackHandler(pagerState.currentPage > 0) {
89+
BackHandler(pagerState.currentPage > 0 || pagerState.isScrollInProgress) {
9090
scrollToPage(pagerState.currentPage - 1)
9191
}
9292

@@ -127,7 +127,7 @@ private fun OnBoardingScreenContent(
127127
onClick = {
128128
if (pagerState.currentPage > 0) {
129129
scrollToPage(pagerState.currentPage - 1)
130-
} else if (pagerState.currentPage == 0 && launchSource == LaunchSource.SETTINGS) {
130+
} else if (pagerState.currentPage == 0 && launchSource == LaunchSource.SETTINGS && !pagerState.isScrollInProgress) {
131131
processIntent(OnBoardingIntent.Navigate)
132132
}
133133
},
@@ -151,7 +151,9 @@ private fun OnBoardingScreenContent(
151151
Box(
152152
modifier = Modifier
153153
.size(8.dp)
154-
.background(color, CircleShape)
154+
.drawBehind {
155+
drawCircle(color = color)
156+
}
155157
)
156158
}
157159
}
@@ -161,7 +163,7 @@ private fun OnBoardingScreenContent(
161163
shape = RoundedCornerShape(12.dp),
162164
contentPadding = PaddingValues(0.dp),
163165
onClick = {
164-
if (pagerState.currentPage == OnBoardingPage.entries.size - 1) {
166+
if (pagerState.currentPage == OnBoardingPage.entries.size - 1 && !pagerState.isScrollInProgress) {
165167
processIntent(OnBoardingIntent.Navigate)
166168
} else {
167169
scrollToPage(pagerState.currentPage + 1)

0 commit comments

Comments
 (0)