Optimizes the rendering of the side bar.
This commit is contained in:
@@ -74,12 +74,20 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.ConnectOrbotDialog
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Size10dp
|
import com.vitorpamplona.amethyst.ui.theme.Font18SP
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.IconRowModifier
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.IconRowTextModifier
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Size16dp
|
import com.vitorpamplona.amethyst.ui.theme.Size16dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
|
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size22Modifier
|
||||||
import com.vitorpamplona.amethyst.ui.theme.Size26Modifier
|
import com.vitorpamplona.amethyst.ui.theme.Size26Modifier
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.bannerModifier
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.drawerSpacing
|
||||||
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
||||||
import com.vitorpamplona.quartz.events.toImmutableListOfLists
|
import com.vitorpamplona.amethyst.ui.theme.profileContentHeaderModifier
|
||||||
|
import com.vitorpamplona.quartz.encoders.ATag
|
||||||
|
import com.vitorpamplona.quartz.encoders.HexKey
|
||||||
|
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -90,6 +98,15 @@ fun DrawerContent(
|
|||||||
openSheet: () -> Unit,
|
openSheet: () -> Unit,
|
||||||
accountViewModel: AccountViewModel
|
accountViewModel: AccountViewModel
|
||||||
) {
|
) {
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
val onClickUser = {
|
||||||
|
nav("User/${accountViewModel.userProfile().pubkeyHex}")
|
||||||
|
coroutineScope.launch {
|
||||||
|
drawerState.close()
|
||||||
|
}
|
||||||
|
Unit
|
||||||
|
}
|
||||||
|
|
||||||
val automaticallyShowProfilePicture = remember {
|
val automaticallyShowProfilePicture = remember {
|
||||||
accountViewModel.settings.showProfilePictures.value
|
accountViewModel.settings.showProfilePictures.value
|
||||||
}
|
}
|
||||||
@@ -100,27 +117,31 @@ fun DrawerContent(
|
|||||||
) {
|
) {
|
||||||
Column() {
|
Column() {
|
||||||
ProfileContent(
|
ProfileContent(
|
||||||
accountViewModel.account.userProfile(),
|
baseAccountUser = accountViewModel.account.userProfile(),
|
||||||
modifier = Modifier
|
modifier = profileContentHeaderModifier,
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(horizontal = 25.dp)
|
|
||||||
.padding(top = 70.dp),
|
|
||||||
drawerState,
|
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav
|
onClickUser
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Column(drawerSpacing) {
|
||||||
|
EditStatusBoxes(accountViewModel.account.userProfile(), accountViewModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
FollowingAndFollowerCounts(accountViewModel.account.userProfile(), onClickUser)
|
||||||
|
|
||||||
Divider(
|
Divider(
|
||||||
thickness = DividerThickness,
|
thickness = DividerThickness,
|
||||||
modifier = Modifier.padding(top = 20.dp)
|
modifier = Modifier.padding(top = 20.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
ListContent(
|
ListContent(
|
||||||
nav,
|
|
||||||
drawerState,
|
|
||||||
openSheet,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.weight(1f),
|
.weight(1f),
|
||||||
accountViewModel
|
drawerState,
|
||||||
|
openSheet,
|
||||||
|
accountViewModel,
|
||||||
|
nav
|
||||||
)
|
)
|
||||||
|
|
||||||
BottomContent(
|
BottomContent(
|
||||||
@@ -137,45 +158,48 @@ fun DrawerContent(
|
|||||||
fun ProfileContent(
|
fun ProfileContent(
|
||||||
baseAccountUser: User,
|
baseAccountUser: User,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
drawerState: DrawerState,
|
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit
|
onClickUser: () -> Unit
|
||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val userInfo by baseAccountUser.live().userMetadataInfo.observeAsState()
|
||||||
|
|
||||||
val accountUserState by baseAccountUser.live().metadata.observeAsState()
|
ProfileContentTemplate(
|
||||||
|
profilePubHex = baseAccountUser.pubkeyHex,
|
||||||
val profilePubHex = remember(accountUserState) { accountUserState?.user?.pubkeyHex } ?: return
|
profileBanner = userInfo?.banner,
|
||||||
|
profilePicture = userInfo?.profilePicture(),
|
||||||
val profileBanner = remember(accountUserState) { accountUserState?.user?.info?.banner?.ifBlank { null } }
|
bestDisplayName = userInfo?.bestDisplayName(),
|
||||||
val profilePicture = remember(accountUserState) { accountUserState?.user?.profilePicture() }
|
tags = userInfo?.tags,
|
||||||
// val bestUserName = remember(accountUserState) { accountUserState?.user?.bestUsername() }
|
modifier = modifier,
|
||||||
val bestDisplayName = remember(accountUserState) { accountUserState?.user?.toBestDisplayName() }
|
accountViewModel = accountViewModel,
|
||||||
val tags = remember(accountUserState) { accountUserState?.user?.info?.latestMetadata?.tags?.toImmutableListOfLists() }
|
onClick = onClickUser
|
||||||
val route = remember(accountUserState) { "User/${accountUserState?.user?.pubkeyHex}" }
|
)
|
||||||
|
}
|
||||||
val automaticallyShowProfilePicture = remember {
|
|
||||||
accountViewModel.settings.showProfilePictures.value
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ProfileContentTemplate(
|
||||||
|
profilePubHex: HexKey,
|
||||||
|
profileBanner: String?,
|
||||||
|
profilePicture: String?,
|
||||||
|
bestDisplayName: String?,
|
||||||
|
tags: ImmutableListOfLists<String>?,
|
||||||
|
modifier: Modifier,
|
||||||
|
accountViewModel: AccountViewModel,
|
||||||
|
onClick: () -> Unit
|
||||||
|
) {
|
||||||
Box {
|
Box {
|
||||||
if (profileBanner != null) {
|
if (profileBanner != null) {
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = profileBanner,
|
model = profileBanner,
|
||||||
contentDescription = stringResource(id = R.string.profile_image),
|
contentDescription = stringResource(id = R.string.profile_image),
|
||||||
contentScale = ContentScale.FillWidth,
|
contentScale = ContentScale.FillWidth,
|
||||||
modifier = Modifier
|
modifier = bannerModifier
|
||||||
.fillMaxWidth()
|
|
||||||
.height(120.dp)
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(R.drawable.profile_banner),
|
painter = painterResource(R.drawable.profile_banner),
|
||||||
contentDescription = stringResource(R.string.profile_banner),
|
contentDescription = stringResource(R.string.profile_banner),
|
||||||
contentScale = ContentScale.FillWidth,
|
contentScale = ContentScale.FillWidth,
|
||||||
modifier = Modifier
|
modifier = bannerModifier
|
||||||
.fillMaxWidth()
|
|
||||||
.height(120.dp)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,13 +214,8 @@ fun ProfileContent(
|
|||||||
.clip(shape = CircleShape)
|
.clip(shape = CircleShape)
|
||||||
.border(3.dp, MaterialTheme.colorScheme.background, CircleShape)
|
.border(3.dp, MaterialTheme.colorScheme.background, CircleShape)
|
||||||
.background(MaterialTheme.colorScheme.background)
|
.background(MaterialTheme.colorScheme.background)
|
||||||
.clickable(onClick = {
|
.clickable(onClick = onClick),
|
||||||
nav(route)
|
loadProfilePicture = accountViewModel.settings.showProfilePictures.value
|
||||||
coroutineScope.launch {
|
|
||||||
drawerState.close()
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
loadProfilePicture = automaticallyShowProfilePicture
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (bestDisplayName != null) {
|
if (bestDisplayName != null) {
|
||||||
@@ -205,139 +224,98 @@ fun ProfileContent(
|
|||||||
tags = tags,
|
tags = tags,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(top = 7.dp)
|
.padding(top = 7.dp)
|
||||||
.clickable(onClick = {
|
.clickable(onClick = onClick),
|
||||||
nav(route)
|
|
||||||
coroutineScope.launch {
|
|
||||||
drawerState.close()
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
fontSize = 18.sp,
|
fontSize = 18.sp,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Column(Modifier.padding(top = Size10dp)) {
|
|
||||||
EditStatusBoxes(baseAccountUser, accountViewModel)
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(top = Size10dp)
|
|
||||||
.clickable(onClick = {
|
|
||||||
nav(route)
|
|
||||||
coroutineScope.launch {
|
|
||||||
drawerState.close()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
) {
|
|
||||||
FollowingAndFollowerCounts(baseAccountUser)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun EditStatusBoxes(baseAccountUser: User, accountViewModel: AccountViewModel) {
|
private fun EditStatusBoxes(baseAccountUser: User, accountViewModel: AccountViewModel) {
|
||||||
val focusManager = LocalFocusManager.current
|
|
||||||
|
|
||||||
LoadStatuses(user = baseAccountUser, accountViewModel) { statuses ->
|
LoadStatuses(user = baseAccountUser, accountViewModel) { statuses ->
|
||||||
if (statuses.isEmpty()) {
|
if (statuses.isEmpty()) {
|
||||||
val currentStatus = remember {
|
StatusEditBar(accountViewModel = accountViewModel)
|
||||||
mutableStateOf("")
|
|
||||||
}
|
|
||||||
val hasChanged by remember {
|
|
||||||
derivedStateOf {
|
|
||||||
currentStatus.value != ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = currentStatus.value,
|
|
||||||
onValueChange = { currentStatus.value = it },
|
|
||||||
label = { Text(text = stringResource(R.string.status_update)) },
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
placeholder = {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.status_update),
|
|
||||||
color = MaterialTheme.colorScheme.placeholderText
|
|
||||||
)
|
|
||||||
},
|
|
||||||
keyboardOptions = KeyboardOptions.Default.copy(
|
|
||||||
imeAction = ImeAction.Send,
|
|
||||||
capitalization = KeyboardCapitalization.Sentences
|
|
||||||
),
|
|
||||||
keyboardActions = KeyboardActions(
|
|
||||||
onSend = {
|
|
||||||
accountViewModel.createStatus(currentStatus.value)
|
|
||||||
focusManager.clearFocus(true)
|
|
||||||
}
|
|
||||||
),
|
|
||||||
singleLine = true,
|
|
||||||
trailingIcon = {
|
|
||||||
if (hasChanged) {
|
|
||||||
SendButton() {
|
|
||||||
accountViewModel.createStatus(currentStatus.value)
|
|
||||||
focusManager.clearFocus(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
statuses.forEach {
|
statuses.forEach {
|
||||||
val originalStatus by it.live().content.observeAsState("")
|
val originalStatus by it.live().content.observeAsState()
|
||||||
|
|
||||||
val thisStatus = remember {
|
StatusEditBar(originalStatus, it.address, accountViewModel)
|
||||||
mutableStateOf(originalStatus)
|
|
||||||
}
|
|
||||||
val hasChanged by remember {
|
|
||||||
derivedStateOf {
|
|
||||||
thisStatus.value != originalStatus
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = thisStatus.value,
|
|
||||||
onValueChange = { thisStatus.value = it },
|
|
||||||
label = { Text(text = stringResource(R.string.status_update)) },
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
placeholder = {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.status_update),
|
|
||||||
color = MaterialTheme.colorScheme.placeholderText
|
|
||||||
)
|
|
||||||
},
|
|
||||||
keyboardOptions = KeyboardOptions.Default.copy(
|
|
||||||
imeAction = ImeAction.Send,
|
|
||||||
capitalization = KeyboardCapitalization.Sentences
|
|
||||||
),
|
|
||||||
keyboardActions = KeyboardActions(
|
|
||||||
onSend = {
|
|
||||||
accountViewModel.updateStatus(it, thisStatus.value)
|
|
||||||
focusManager.clearFocus(true)
|
|
||||||
}
|
|
||||||
),
|
|
||||||
singleLine = true,
|
|
||||||
trailingIcon = {
|
|
||||||
if (hasChanged) {
|
|
||||||
SendButton() {
|
|
||||||
accountViewModel.updateStatus(it, thisStatus.value)
|
|
||||||
focusManager.clearFocus(true)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
UserStatusDeleteButton() {
|
|
||||||
accountViewModel.deleteStatus(it)
|
|
||||||
focusManager.clearFocus(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun StatusEditBar(
|
||||||
|
savedStatus: String? = null,
|
||||||
|
tag: ATag? = null,
|
||||||
|
accountViewModel: AccountViewModel
|
||||||
|
) {
|
||||||
|
val focusManager = LocalFocusManager.current
|
||||||
|
|
||||||
|
val currentStatus = remember {
|
||||||
|
mutableStateOf(savedStatus ?: "")
|
||||||
|
}
|
||||||
|
val hasChanged = remember {
|
||||||
|
derivedStateOf {
|
||||||
|
currentStatus.value != (savedStatus ?: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OutlinedTextField(
|
||||||
|
value = currentStatus.value,
|
||||||
|
onValueChange = { currentStatus.value = it },
|
||||||
|
label = { Text(text = stringResource(R.string.status_update)) },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
placeholder = {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.status_update),
|
||||||
|
color = MaterialTheme.colorScheme.placeholderText
|
||||||
|
)
|
||||||
|
},
|
||||||
|
keyboardOptions = KeyboardOptions.Default.copy(
|
||||||
|
imeAction = ImeAction.Send,
|
||||||
|
capitalization = KeyboardCapitalization.Sentences
|
||||||
|
),
|
||||||
|
keyboardActions = KeyboardActions(
|
||||||
|
onSend = {
|
||||||
|
if (tag == null) {
|
||||||
|
accountViewModel.createStatus(currentStatus.value)
|
||||||
|
} else {
|
||||||
|
accountViewModel.updateStatus(tag, currentStatus.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
focusManager.clearFocus(true)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
singleLine = true,
|
||||||
|
trailingIcon = {
|
||||||
|
if (hasChanged.value) {
|
||||||
|
SendButton {
|
||||||
|
if (tag == null) {
|
||||||
|
accountViewModel.createStatus(currentStatus.value)
|
||||||
|
} else {
|
||||||
|
accountViewModel.updateStatus(tag, currentStatus.value)
|
||||||
|
}
|
||||||
|
focusManager.clearFocus(true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (tag != null) {
|
||||||
|
UserStatusDeleteButton {
|
||||||
|
accountViewModel.deleteStatus(tag)
|
||||||
|
focusManager.clearFocus(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SendButton(onClick: () -> Unit) {
|
fun SendButton(onClick: () -> Unit) {
|
||||||
IconButton(
|
IconButton(
|
||||||
@@ -369,7 +347,7 @@ fun UserStatusDeleteButton(onClick: () -> Unit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun FollowingAndFollowerCounts(baseAccountUser: User) {
|
private fun FollowingAndFollowerCounts(baseAccountUser: User, onClick: () -> Unit) {
|
||||||
var followingCount by remember { mutableStateOf("--") }
|
var followingCount by remember { mutableStateOf("--") }
|
||||||
var followerCount by remember { mutableStateOf("--") }
|
var followerCount by remember { mutableStateOf("--") }
|
||||||
|
|
||||||
@@ -385,21 +363,25 @@ private fun FollowingAndFollowerCounts(baseAccountUser: User) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Row(
|
||||||
text = followingCount,
|
modifier = drawerSpacing.clickable(onClick = onClick)
|
||||||
fontWeight = FontWeight.Bold
|
) {
|
||||||
)
|
Text(
|
||||||
|
text = followingCount,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
|
||||||
Text(stringResource(R.string.following))
|
Text(stringResource(R.string.following))
|
||||||
|
|
||||||
Spacer(modifier = DoubleHorzSpacer)
|
Spacer(modifier = DoubleHorzSpacer)
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = followerCount,
|
text = followerCount,
|
||||||
fontWeight = FontWeight.Bold
|
fontWeight = FontWeight.Bold
|
||||||
)
|
)
|
||||||
|
|
||||||
Text(stringResource(R.string.followers))
|
Text(stringResource(R.string.followers))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -426,20 +408,18 @@ fun WatchFollower(baseAccountUser: User, onReady: (String) -> Unit) {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ListContent(
|
fun ListContent(
|
||||||
nav: (String) -> Unit,
|
modifier: Modifier,
|
||||||
drawerState: DrawerState,
|
drawerState: DrawerState,
|
||||||
openSheet: () -> Unit,
|
openSheet: () -> Unit,
|
||||||
modifier: Modifier,
|
accountViewModel: AccountViewModel,
|
||||||
accountViewModel: AccountViewModel
|
nav: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
val route = remember(accountViewModel) {
|
val route = remember(accountViewModel) {
|
||||||
"User/${accountViewModel.userProfile().pubkeyHex}"
|
"User/${accountViewModel.userProfile().pubkeyHex}"
|
||||||
}
|
}
|
||||||
|
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
var wantsToEditRelays by remember {
|
var wantsToEditRelays by remember { mutableStateOf(false) }
|
||||||
mutableStateOf(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
var backupDialogOpen by remember { mutableStateOf(false) }
|
var backupDialogOpen by remember { mutableStateOf(false) }
|
||||||
var checked by remember { mutableStateOf(accountViewModel.account.proxy != null) }
|
var checked by remember { mutableStateOf(accountViewModel.account.proxy != null) }
|
||||||
@@ -504,9 +484,8 @@ fun ListContent(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val textTorProxy = if (checked) stringResource(R.string.disconnect_from_your_orbot_setup) else stringResource(R.string.connect_via_tor_short)
|
|
||||||
IconRow(
|
IconRow(
|
||||||
title = textTorProxy,
|
title = if (checked) stringResource(R.string.disconnect_from_your_orbot_setup) else stringResource(R.string.connect_via_tor_short),
|
||||||
icon = R.drawable.ic_tor,
|
icon = R.drawable.ic_tor,
|
||||||
tint = MaterialTheme.colorScheme.onBackground,
|
tint = MaterialTheme.colorScheme.onBackground,
|
||||||
onLongClick = {
|
onLongClick = {
|
||||||
@@ -672,21 +651,19 @@ fun IconRow(title: String, icon: Int, tint: Color, onClick: () -> Unit, onLongCl
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = IconRowModifier,
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(vertical = 15.dp, horizontal = 25.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(icon),
|
painter = painterResource(icon),
|
||||||
null,
|
null,
|
||||||
modifier = Modifier.size(22.dp),
|
modifier = Size22Modifier,
|
||||||
tint = tint
|
tint = tint
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.padding(start = 16.dp),
|
modifier = IconRowTextModifier,
|
||||||
text = title,
|
text = title,
|
||||||
fontSize = 18.sp
|
fontSize = Font18SP
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -675,15 +675,15 @@ class AccountViewModel(val account: Account, val settings: SettingsState) : View
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateStatus(it: AddressableNote, newStatus: String) {
|
fun updateStatus(it: ATag, newStatus: String) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
account.updateStatus(it, newStatus)
|
account.updateStatus(LocalCache.getOrCreateAddressableNote(it), newStatus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteStatus(it: AddressableNote) {
|
fun deleteStatus(it: ATag) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
account.deleteStatus(it)
|
account.deleteStatus(LocalCache.getOrCreateAddressableNote(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,10 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn
|
|||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
|
import androidx.compose.animation.AnimatedContentTransitionScope
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.ContentTransform
|
||||||
|
import androidx.compose.animation.ExperimentalAnimationApi
|
||||||
import androidx.compose.animation.scaleIn
|
import androidx.compose.animation.scaleIn
|
||||||
import androidx.compose.animation.scaleOut
|
import androidx.compose.animation.scaleOut
|
||||||
import androidx.compose.animation.slideInVertically
|
import androidx.compose.animation.slideInVertically
|
||||||
@@ -302,10 +305,8 @@ fun MainScreen(
|
|||||||
bottomBar = {
|
bottomBar = {
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = shouldShow.value,
|
targetState = shouldShow.value,
|
||||||
transitionSpec = {
|
transitionSpec = AnimatedContentTransitionScope<Boolean>::bottomBarTransitionSpec,
|
||||||
slideInVertically { height -> height } togetherWith
|
label = "BottomBarAnimatedContent"
|
||||||
slideOutVertically { height -> height }
|
|
||||||
}
|
|
||||||
) { isVisible ->
|
) { isVisible ->
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
AppBottomBar(accountViewModel, navState, navBottomRow)
|
AppBottomBar(accountViewModel, navState, navBottomRow)
|
||||||
@@ -315,10 +316,8 @@ fun MainScreen(
|
|||||||
topBar = {
|
topBar = {
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = shouldShow.value,
|
targetState = shouldShow.value,
|
||||||
transitionSpec = {
|
transitionSpec = AnimatedContentTransitionScope<Boolean>::topBarTransitionSpec,
|
||||||
slideInVertically { height -> 0 } togetherWith
|
label = "TopBarAnimatedContent"
|
||||||
slideOutVertically { height -> 0 }
|
|
||||||
}
|
|
||||||
) { isVisible ->
|
) { isVisible ->
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
AppTopBar(
|
AppTopBar(
|
||||||
@@ -396,6 +395,23 @@ fun MainScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalAnimationApi::class)
|
||||||
|
private fun <S> AnimatedContentTransitionScope<S>.topBarTransitionSpec(): ContentTransform {
|
||||||
|
return topBarAnimation
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalAnimationApi::class)
|
||||||
|
private fun <S> AnimatedContentTransitionScope<S>.bottomBarTransitionSpec(): ContentTransform {
|
||||||
|
return bottomBarAnimation
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalAnimationApi
|
||||||
|
val topBarAnimation: ContentTransform =
|
||||||
|
slideInVertically { height -> 0 } togetherWith slideOutVertically { height -> 0 }
|
||||||
|
|
||||||
|
val bottomBarAnimation: ContentTransform =
|
||||||
|
slideInVertically { height -> height } togetherWith slideOutVertically { height -> height }
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DisplayErrorMessages(accountViewModel: AccountViewModel) {
|
private fun DisplayErrorMessages(accountViewModel: AccountViewModel) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|||||||
@@ -148,3 +148,12 @@ val EditFieldLeadingIconModifier = Modifier
|
|||||||
val ZeroPadding = PaddingValues(0.dp)
|
val ZeroPadding = PaddingValues(0.dp)
|
||||||
val FeedPadding = PaddingValues(top = 10.dp, bottom = 10.dp)
|
val FeedPadding = PaddingValues(top = 10.dp, bottom = 10.dp)
|
||||||
val ButtonPadding = PaddingValues(vertical = 6.dp, horizontal = 16.dp)
|
val ButtonPadding = PaddingValues(vertical = 6.dp, horizontal = 16.dp)
|
||||||
|
|
||||||
|
val profileContentHeaderModifier = Modifier.fillMaxWidth().padding(top = 70.dp, start = Size25dp, end = Size25dp)
|
||||||
|
val bannerModifier = Modifier.fillMaxWidth().height(120.dp)
|
||||||
|
val drawerSpacing = Modifier.padding(top = Size10dp, start = Size25dp, end = Size25dp)
|
||||||
|
|
||||||
|
val IconRowTextModifier = Modifier.padding(start = 16.dp)
|
||||||
|
val IconRowModifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(vertical = 15.dp, horizontal = 25.dp)
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ val Typography = Typography(
|
|||||||
val Font12SP = 12.sp
|
val Font12SP = 12.sp
|
||||||
val Font14SP = 14.sp
|
val Font14SP = 14.sp
|
||||||
val Font17SP = 17.sp
|
val Font17SP = 17.sp
|
||||||
|
val Font18SP = 18.sp
|
||||||
|
|
||||||
val MarkdownTextStyle = TextStyle(lineHeight = 1.30.em)
|
val MarkdownTextStyle = TextStyle(lineHeight = 1.30.em)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user