Skip to content

Commit

Permalink
improve input fields design on new post page
Browse files Browse the repository at this point in the history
  • Loading branch information
daniebeler committed Feb 22, 2025
1 parent 7900ce0 commit da8de8d
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 129 deletions.
6 changes: 4 additions & 2 deletions app/src/commonMain/kotlin/com/daniebeler/pfpixelix/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,11 @@ private fun NavGraphBuilder.navigationGraph(
}

composable(Destinations.Search.route) { navBackStackEntry ->
val initialPage = navBackStackEntry.arguments?.getString("initialPage")
val initialPage = navBackStackEntry.arguments?.read {
if (contains("initialPage")) getInt("initialPage") else 0
}
initialPage?.let {
ExploreComposable(navController, it.toIntOrNull() ?: 0)
ExploreComposable(navController, initialPage)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import pixelix.app.generated.resources.nobody_follows_you_yet
@Composable
fun FollowersComposable(
navController: NavController,
viewModel: FollowersViewModel
viewModel: FollowersViewModel = injectViewModel(key = "followers-viewmodel-key") { followersViewModel }
) {
val lazyListState = rememberLazyListState()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import pixelix.app.generated.resources.the_profiles_you_follow_will_appear_here
@Composable
fun FollowingComposable(
navController: NavController,
viewModel: FollowersViewModel
viewModel: FollowersViewModel = injectViewModel(key = "followers-viewmodel-key") { followersViewModel }
) {
val lazyListState = rememberLazyListState()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import androidx.compose.material.icons.outlined.ArrowDownward
import androidx.compose.material.icons.outlined.ArrowRight
import androidx.compose.material.icons.outlined.ArrowUpward
import androidx.compose.material.icons.outlined.Check
import androidx.compose.material.icons.outlined.Warning
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Card
Expand Down Expand Up @@ -72,6 +73,9 @@ import com.daniebeler.pfpixelix.common.Constants.AUDIENCE_FOLLOWERS_ONLY
import com.daniebeler.pfpixelix.common.Constants.AUDIENCE_PUBLIC
import com.daniebeler.pfpixelix.common.Constants.AUDIENCE_UNLISTED
import com.daniebeler.pfpixelix.di.injectViewModel
import com.daniebeler.pfpixelix.ui.composables.settings.preferences.basic.SettingPrefUtil
import com.daniebeler.pfpixelix.ui.composables.settings.preferences.basic.SwitchIntPref
import com.daniebeler.pfpixelix.ui.composables.settings.preferences.prefs.FocusModePrefUtil
import com.daniebeler.pfpixelix.ui.composables.states.ErrorComposable
import com.daniebeler.pfpixelix.ui.composables.states.LoadingComposable
import com.daniebeler.pfpixelix.ui.composables.textfield_location.TextFieldLocationsComposable
Expand All @@ -94,14 +98,17 @@ import pixelix.app.generated.resources.add_outline
import pixelix.app.generated.resources.alt_text
import pixelix.app.generated.resources.audience
import pixelix.app.generated.resources.audience_public
import pixelix.app.generated.resources.browsers_outline
import pixelix.app.generated.resources.cancel
import pixelix.app.generated.resources.caption
import pixelix.app.generated.resources.content_warning_or_spoiler_text
import pixelix.app.generated.resources.focus_mode
import pixelix.app.generated.resources.followers_only
import pixelix.app.generated.resources.location
import pixelix.app.generated.resources.new_post
import pixelix.app.generated.resources.release
import pixelix.app.generated.resources.sensitive_nsfw_media
import pixelix.app.generated.resources.square_outline
import pixelix.app.generated.resources.trash_outline
import pixelix.app.generated.resources.unlisted

Expand Down Expand Up @@ -135,8 +142,7 @@ fun NewPostComposable(
CenterAlignedTopAppBar(title = {
Text(text = stringResource(Res.string.new_post), fontWeight = FontWeight.Bold)
}, actions = {
Button(
onClick = { showReleaseAlert = true },
Button(onClick = { showReleaseAlert = true },
enabled = (viewModel.images.isNotEmpty() && viewModel.images.none { it.isLoading })
) {
Text(text = stringResource(Res.string.release))
Expand All @@ -159,111 +165,92 @@ fun NewPostComposable(
{ index -> viewModel.moveMediaAttachmentDown(index) },
{ index -> viewModel.deleteMedia(index) },
{ kmpUri: KmpUri -> viewModel.addImage(kmpUri, context) })

Column(Modifier.padding(12.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) {
Spacer(modifier = Modifier.height(20.dp))
TextFieldMentionsComposable(
submit = {},
text = viewModel.caption,
changeText = { text -> viewModel.caption = text },
labelStringId = Res.string.caption,
modifier = Modifier.fillMaxWidth(),
imeAction = ImeAction.Default,
suggestionsBoxColor = MaterialTheme.colorScheme.surfaceContainer,
submitButton = null
NewPostTextField(
value = viewModel.caption,
onChange = { viewModel.caption = it },
label = stringResource(Res.string.caption)
)
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Text(text = stringResource(Res.string.sensitive_nsfw_media))
Switch(checked = viewModel.sensitive,
onCheckedChange = { viewModel.sensitive = it })
}
NewPostPref(leadingIcon = Res.drawable.browsers_outline,
title = stringResource(Res.string.sensitive_nsfw_media),
trailingContent = {
Switch(checked = viewModel.sensitive,
onCheckedChange = { viewModel.sensitive = it })
})
if (viewModel.sensitive) {
TextField(
NewPostTextField(
value = viewModel.sensitiveText,
onValueChange = { viewModel.sensitiveText = it },
modifier = Modifier.fillMaxWidth(),
label = { Text(stringResource(Res.string.content_warning_or_spoiler_text)) },
shape = RoundedCornerShape(16.dp),
colors = TextFieldDefaults.colors(
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent,
focusedContainerColor = MaterialTheme.colorScheme.surfaceContainer,
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceContainer
)
onChange = { viewModel.sensitiveText = it },
label = stringResource(Res.string.content_warning_or_spoiler_text)
)
}
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Text(text = stringResource(Res.string.audience))
Box {
OutlinedButton(onClick = { expanded = !expanded }) {
val buttonText: String = when (viewModel.audience) {
AUDIENCE_PUBLIC -> {
stringResource(Res.string.audience_public)
}
NewPostPref(leadingIcon = Res.drawable.browsers_outline,
title = stringResource(Res.string.audience),
trailingContent = {
Box {
OutlinedButton(onClick = { expanded = !expanded }) {
val buttonText: String = when (viewModel.audience) {
AUDIENCE_PUBLIC -> {
stringResource(Res.string.audience_public)
}

AUDIENCE_UNLISTED -> {
stringResource(Res.string.unlisted)
}
AUDIENCE_UNLISTED -> {
stringResource(Res.string.unlisted)
}

AUDIENCE_FOLLOWERS_ONLY -> {
stringResource(Res.string.followers_only)
}
AUDIENCE_FOLLOWERS_ONLY -> {
stringResource(Res.string.followers_only)
}

else -> {
""
else -> {
""
}
}
Text(text = buttonText)
}
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }) {
DropdownMenuItem(text = { Text(stringResource(Res.string.audience_public)) },
onClick = { viewModel.audience = AUDIENCE_PUBLIC },
trailingIcon = {
if (viewModel.audience == AUDIENCE_PUBLIC) {
Icon(
imageVector = Icons.Outlined.Check,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
}
})
DropdownMenuItem(text = { Text(stringResource(Res.string.unlisted)) },
onClick = { viewModel.audience = AUDIENCE_UNLISTED },
trailingIcon = {
if (viewModel.audience == AUDIENCE_UNLISTED) {
Icon(
imageVector = Icons.Outlined.Check,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
}
})
DropdownMenuItem(text = { Text(stringResource(Res.string.followers_only)) },
onClick = { viewModel.audience = AUDIENCE_FOLLOWERS_ONLY },
trailingIcon = {
if (viewModel.audience == AUDIENCE_FOLLOWERS_ONLY) {
Icon(
imageVector = Icons.Outlined.Check,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
}
})
}
Text(text = buttonText)
}
DropdownMenu(expanded = expanded,
onDismissRequest = { expanded = false }) {
DropdownMenuItem(text = { Text(stringResource(Res.string.audience_public)) },
onClick = { viewModel.audience = AUDIENCE_PUBLIC },
trailingIcon = {
if (viewModel.audience == AUDIENCE_PUBLIC) {
Icon(
imageVector = Icons.Outlined.Check,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
}
})
DropdownMenuItem(text = { Text(stringResource(Res.string.unlisted)) },
onClick = { viewModel.audience = AUDIENCE_UNLISTED },
trailingIcon = {
if (viewModel.audience == AUDIENCE_UNLISTED) {
Icon(
imageVector = Icons.Outlined.Check,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
}
})
DropdownMenuItem(text = { Text(stringResource(Res.string.followers_only)) },
onClick = { viewModel.audience = AUDIENCE_FOLLOWERS_ONLY },
trailingIcon = {
if (viewModel.audience == AUDIENCE_FOLLOWERS_ONLY) {
Icon(
imageVector = Icons.Outlined.Check,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
}
})
}


}
}
TextFieldLocationsComposable(
submit = { viewModel.setLocation(it) },
}
})
TextFieldLocationsComposable(submit = { viewModel.setLocation(it) },
submitPlace = {},
initialValue = null,
labelStringId = Res.string.location,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.daniebeler.pfpixelix.ui.composables.newpost

import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.vectorResource

@Composable
fun NewPostPref(
leadingIcon: DrawableResource,
title: String,
trailingContent: (@Composable () -> Unit)? = null,
shape: Shape = MaterialTheme.shapes.medium,
textColor: Color? = null,
content: @Composable ColumnScope.() -> Unit = {}
) {
val cardColors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(4.dp)
)
Card(
shape = shape,
colors = cardColors,
modifier = Modifier.animateContentSize(),
) {
Card(
shape = shape,
colors = cardColors,
modifier = Modifier.padding(horizontal = 12.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.defaultMinSize(minHeight = 54.dp)
) {
if (leadingIcon != null) {
Icon(vectorResource(leadingIcon), contentDescription = null)
}
Column(
modifier = Modifier
.weight(1f)
.padding(horizontal = 10.dp, vertical = 10.dp),
) {
Text(
text = title,
style = MaterialTheme.typography.titleSmall,
fontWeight = FontWeight.Medium,
color = textColor ?: Color.Unspecified
)
}
if (trailingContent != null) {
trailingContent()
}
}
}

content()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.daniebeler.pfpixelix.ui.composables.newpost

import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import pixelix.app.generated.resources.Res
import pixelix.app.generated.resources.content_warning_or_spoiler_text

@Composable
fun NewPostTextField(
value: String,
onChange: (value: String) -> Unit,
label: String
) {
TextField(
value = value,
onValueChange = onChange,
modifier = Modifier.fillMaxWidth(),
label = { Text(label) },
shape = MaterialTheme.shapes.medium,
colors = TextFieldDefaults.colors(
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent,
focusedContainerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(4.dp),
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(4.dp)
)
)
}
Loading

0 comments on commit da8de8d

Please sign in to comment.