Skip to content

Commit 8a11865

Browse files
authored
Merge pull request #510 from imashnake0/profile-screen-fixes
Profile Screen -> Closed Testing Feedback
2 parents d8d469d + c2bc9dd commit 8a11865

File tree

2 files changed

+132
-77
lines changed

2 files changed

+132
-77
lines changed

profile/src/main/kotlin/com/imashnake/animite/profile/ProfileScreen.kt

Lines changed: 130 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import androidx.compose.foundation.layout.padding
2727
import androidx.compose.foundation.layout.size
2828
import androidx.compose.foundation.layout.systemBars
2929
import androidx.compose.foundation.layout.union
30+
import androidx.compose.foundation.layout.wrapContentSize
3031
import androidx.compose.foundation.pager.HorizontalPager
3132
import androidx.compose.foundation.pager.rememberPagerState
3233
import androidx.compose.foundation.shape.CircleShape
@@ -42,6 +43,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
4243
import androidx.compose.material3.Icon
4344
import androidx.compose.material3.MaterialTheme
4445
import androidx.compose.material3.MenuDefaults
46+
import androidx.compose.material3.PrimaryScrollableTabRow
4547
import androidx.compose.material3.PrimaryTabRow
4648
import androidx.compose.material3.Surface
4749
import androidx.compose.material3.Tab
@@ -82,7 +84,6 @@ import com.imashnake.animite.core.extensions.crossfadeModel
8284
import com.imashnake.animite.core.extensions.horizontalOnly
8385
import com.imashnake.animite.core.extensions.maxHeight
8486
import com.imashnake.animite.core.extensions.plus
85-
import com.imashnake.animite.core.ui.FallbackMessage
8687
import com.imashnake.animite.core.ui.LocalPaddings
8788
import com.imashnake.animite.core.ui.NestedScrollableContent
8889
import com.imashnake.animite.core.ui.ProgressIndicatorScreen
@@ -96,7 +97,6 @@ import com.imashnake.animite.settings.SettingsPage
9697
import kotlinx.coroutines.launch
9798
import me.saket.cascade.CascadeDropdownMenu
9899
import me.saket.cascade.rememberCascadeState
99-
import com.imashnake.animite.core.R as coreR
100100
import com.imashnake.animite.navigation.R as navigationR
101101

102102
private const val DROP_DOWN_ITEMS_COUNT = 2
@@ -155,9 +155,16 @@ fun ProfileScreen(
155155
contentDescription = "Avatar",
156156
modifier = Modifier
157157
.align(Alignment.BottomStart)
158-
.padding(start = LocalPaddings.current.medium)
158+
.padding(start = LocalPaddings.current.large)
159159
.padding(allPaddingValues.horizontalOnly)
160-
.size(100.dp),
160+
.wrapContentSize()
161+
.maxHeight(100.dp)
162+
.clip(
163+
RoundedCornerShape(
164+
topStart = LocalPaddings.current.small,
165+
topEnd = LocalPaddings.current.small,
166+
)
167+
),
161168
)
162169
SettingsAndMore(
163170
onNavigateToSettings = onNavigateToSettings,
@@ -184,16 +191,6 @@ fun ProfileScreen(
184191
style = MaterialTheme.typography.titleLarge,
185192
overflow = TextOverflow.Ellipsis,
186193
)
187-
UserDescription(
188-
description = description,
189-
modifier = Modifier.maxHeight(
190-
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT) {
191-
dimensionResource(R.dimen.user_about_height)
192-
} else {
193-
dimensionResource(R.dimen.user_about_height_landscape)
194-
}
195-
)
196-
)
197194
}
198195
UserTabs(
199196
user = this@run,
@@ -211,7 +208,16 @@ fun ProfileScreen(
211208
}
212209
else -> ProgressIndicatorScreen(Modifier.padding(allPaddingValues))
213210
}
214-
else -> Login(Modifier.padding(allPaddingValues))
211+
else -> {
212+
SettingsIcon(
213+
onNavigateToSettings = onNavigateToSettings,
214+
modifier = Modifier
215+
.align(Alignment.TopEnd)
216+
.padding(LocalPaddings.current.large)
217+
.padding(allPaddingValues.copy(bottom = 0.dp)),
218+
)
219+
Login(Modifier.padding(allPaddingValues))
220+
}
215221
}
216222

217223
if (isLogOutDialogShown)
@@ -228,6 +234,7 @@ fun ProfileScreen(
228234
}
229235
}
230236

237+
// TODO: Properly parse the user description and add this back.
231238
@Composable
232239
private fun UserDescription(description: String?, modifier: Modifier = Modifier) {
233240
description?.let {
@@ -266,37 +273,13 @@ private fun SettingsAndMore(
266273
targetValue = if (expanded) 10 else 50,
267274
label = "corner_radius_animation",
268275
)
269-
val infiniteTransition = rememberInfiniteTransition(label = "settings_icon")
270-
val angle by infiniteTransition.animateFloat(
271-
initialValue = 0f,
272-
targetValue = 360f,
273-
animationSpec = infiniteRepeatable(
274-
animation = tween(10000, easing = LinearEasing),
275-
repeatMode = RepeatMode.Restart
276-
),
277-
label = "rotation"
278-
)
279276

280277
Row(
281278
horizontalArrangement = Arrangement.spacedBy(LocalPaddings.current.small),
282279
verticalAlignment = Alignment.CenterVertically,
283280
modifier = modifier.padding(LocalPaddings.current.large)
284281
) {
285-
Surface(
286-
color = MaterialTheme.colorScheme.surfaceContainer,
287-
shape = CircleShape
288-
) {
289-
Icon(
290-
imageVector = Icons.Rounded.Settings,
291-
contentDescription = stringResource(R.string.settings),
292-
tint = MaterialTheme.colorScheme.primary,
293-
modifier = Modifier
294-
.clickable { onNavigateToSettings(SettingsPage) }
295-
.padding(LocalPaddings.current.small)
296-
.size(LocalPaddings.current.medium)
297-
.graphicsLayer { rotationZ = angle }
298-
)
299-
}
282+
SettingsIcon(onNavigateToSettings = onNavigateToSettings)
300283

301284
Box {
302285
Surface(
@@ -367,6 +350,40 @@ private fun SettingsAndMore(
367350
}
368351
}
369352

353+
@Composable
354+
fun SettingsIcon(
355+
onNavigateToSettings: (SettingsPage) -> Unit,
356+
modifier: Modifier = Modifier
357+
) {
358+
val infiniteTransition = rememberInfiniteTransition(label = "settings_icon")
359+
val angle by infiniteTransition.animateFloat(
360+
initialValue = 0f,
361+
targetValue = 360f,
362+
animationSpec = infiniteRepeatable(
363+
animation = tween(10000, easing = LinearEasing),
364+
repeatMode = RepeatMode.Restart
365+
),
366+
label = "rotation"
367+
)
368+
369+
Surface(
370+
color = MaterialTheme.colorScheme.surfaceContainer,
371+
shape = CircleShape,
372+
modifier = modifier,
373+
) {
374+
Icon(
375+
imageVector = Icons.Rounded.Settings,
376+
contentDescription = stringResource(R.string.settings),
377+
tint = MaterialTheme.colorScheme.primary,
378+
modifier = Modifier
379+
.clickable { onNavigateToSettings(SettingsPage) }
380+
.padding(LocalPaddings.current.small)
381+
.size(LocalPaddings.current.medium)
382+
.graphicsLayer { rotationZ = angle }
383+
)
384+
}
385+
}
386+
370387
@Composable
371388
fun LogOutDialog(
372389
logOut: () -> Unit,
@@ -414,37 +431,80 @@ private fun UserTabs(
414431
val onBackground = MaterialTheme.colorScheme.onBackground
415432
val horizontalContentPadding = contentPadding.horizontalOnly
416433

434+
var scrollableTabs by remember { mutableStateOf(false) }
435+
417436
Column(modifier) {
418-
PrimaryTabRow(
419-
selectedTabIndex = pagerState.currentPage,
420-
containerColor = MaterialTheme.colorScheme.background,
421-
divider = {},
422-
modifier = Modifier.padding(horizontalContentPadding)
423-
) {
424-
titles.forEachIndexed { index, tab ->
425-
Tab(
426-
selected = pagerState.currentPage == index,
427-
onClick = {
428-
coroutineScope.launch { pagerState.animateScrollToPage(index) }
429-
},
430-
text = {
431-
Text(
432-
text = stringResource(tab.titleRes),
433-
overflow = TextOverflow.Ellipsis,
434-
style = MaterialTheme.typography.bodyMedium,
435-
color = onBackground.copy(
436-
alpha = if (pagerState.currentPage == index) 1f else 0.5f
437-
),
438-
maxLines = 1
439-
)
440-
},
441-
modifier = Modifier
442-
.padding(
443-
horizontal = LocalPaddings.current.ultraTiny,
444-
vertical = LocalPaddings.current.small
445-
)
446-
.clip(CircleShape)
447-
)
437+
if (!scrollableTabs) {
438+
PrimaryTabRow(
439+
selectedTabIndex = pagerState.currentPage,
440+
containerColor = MaterialTheme.colorScheme.background,
441+
divider = {},
442+
modifier = Modifier.padding(horizontalContentPadding)
443+
) {
444+
titles.forEachIndexed { index, tab ->
445+
Tab(
446+
selected = pagerState.currentPage == index,
447+
onClick = {
448+
coroutineScope.launch { pagerState.animateScrollToPage(index) }
449+
},
450+
text = {
451+
Text(
452+
text = stringResource(tab.titleRes),
453+
overflow = TextOverflow.Ellipsis,
454+
style = MaterialTheme.typography.bodyMedium,
455+
color = onBackground.copy(
456+
alpha = if (pagerState.currentPage == index) 1f else 0.5f
457+
),
458+
maxLines = 1,
459+
onTextLayout = { result ->
460+
if (result.hasVisualOverflow) {
461+
scrollableTabs = true
462+
}
463+
}
464+
)
465+
},
466+
modifier = Modifier
467+
.padding(
468+
horizontal = LocalPaddings.current.ultraTiny,
469+
vertical = LocalPaddings.current.small
470+
)
471+
.clip(CircleShape)
472+
)
473+
}
474+
}
475+
} else {
476+
PrimaryScrollableTabRow(
477+
selectedTabIndex = pagerState.currentPage,
478+
containerColor = MaterialTheme.colorScheme.background,
479+
edgePadding = LocalPaddings.current.small,
480+
divider = {},
481+
modifier = Modifier.padding(horizontalContentPadding)
482+
) {
483+
titles.forEachIndexed { index, tab ->
484+
Tab(
485+
selected = pagerState.currentPage == index,
486+
onClick = {
487+
coroutineScope.launch { pagerState.animateScrollToPage(index) }
488+
},
489+
text = {
490+
Text(
491+
text = stringResource(tab.titleRes),
492+
overflow = TextOverflow.Ellipsis,
493+
style = MaterialTheme.typography.bodyMedium,
494+
color = onBackground.copy(
495+
alpha = if (pagerState.currentPage == index) 1f else 0.5f
496+
),
497+
maxLines = 1,
498+
)
499+
},
500+
modifier = Modifier
501+
.padding(
502+
horizontal = LocalPaddings.current.ultraTiny,
503+
vertical = LocalPaddings.current.small
504+
)
505+
.clip(CircleShape)
506+
)
507+
}
448508
}
449509
}
450510
HorizontalPager(
@@ -492,12 +552,6 @@ private fun UserTabs(
492552
animatedVisibilityScope = animatedVisibilityScope,
493553
contentPadding = tabContentPadding,
494554
)
495-
else -> FallbackMessage(
496-
message = stringResource(coreR.string.coming_soon),
497-
modifier = Modifier
498-
.align(Alignment.Center)
499-
.padding(tabContentPadding)
500-
)
501555
}
502556
}
503557
}

profile/src/main/kotlin/com/imashnake/animite/profile/tabs/ProfileTab.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ enum class ProfileTab(@param:StringRes val titleRes: Int) {
88
ANIME(R.string.anime),
99
MANGA(R.string.manga),
1010
FAVOURITES(R.string.favourites),
11-
STATISTICS(R.string.statistics)
11+
// TODO: Add this back!
12+
// STATISTICS(R.string.statistics)
1213
}

0 commit comments

Comments
 (0)