Fixing new line of Loading Animation and Download buttons for images.

This commit is contained in:
Vitor Pamplona
2023-10-30 16:39:39 -04:00
parent 717c3bc45e
commit 0571312dca
10 changed files with 291 additions and 230 deletions
@@ -103,8 +103,7 @@ fun NewRelayListView(onClose: () -> Unit, accountViewModel: AccountViewModel, re
TopAppBar( TopAppBar(
title = { title = {
Row( Row(
modifier = Modifier modifier = Modifier.fillMaxWidth(),
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
@@ -685,15 +685,17 @@ fun InLineIconRenderer(
} }
}.associate { it.first to it.second } }.associate { it.first to it.second }
val annotatedText = buildAnnotatedString { val annotatedText = remember {
wordsInOrder.forEachIndexed { idx, value -> buildAnnotatedString {
withStyle( wordsInOrder.forEachIndexed { idx, value ->
style withStyle(
) { style
if (value is TextType) { ) {
append(value.text) if (value is TextType) {
} else if (value is ImageUrlType) { append(value.text)
appendInlineContent("inlineContent$idx", "[icon]") } else if (value is ImageUrlType) {
appendInlineContent("inlineContent$idx", "[icon]")
}
} }
} }
} }
@@ -556,32 +556,32 @@ private fun RenderHashtag(
nav: (String) -> Unit nav: (String) -> Unit
) { ) {
val primary = MaterialTheme.colorScheme.primary val primary = MaterialTheme.colorScheme.primary
val background = MaterialTheme.colorScheme.onBackground
val hashtagIcon = remember(segment.hashtag) { val hashtagIcon = remember(segment.hashtag) {
checkForHashtagWithIcon(segment.hashtag, primary) checkForHashtagWithIcon(segment.hashtag, primary)
} }
val regularText = val regularText = remember { SpanStyle(color = background) }
SpanStyle(color = MaterialTheme.colorScheme.onBackground) val clickableTextStyle = remember { SpanStyle(color = primary) }
val clickableTextStyle = val annotatedTermsString = remember {
SpanStyle(color = primary) buildAnnotatedString {
val annotatedTermsString = buildAnnotatedString {
withStyle(clickableTextStyle) {
pushStringAnnotation("routeToHashtag", "")
append("#${segment.hashtag}")
}
if (hashtagIcon != null) {
withStyle(clickableTextStyle) { withStyle(clickableTextStyle) {
pushStringAnnotation("routeToHashtag", "") pushStringAnnotation("routeToHashtag", "")
appendInlineContent("inlineContent", "[icon]") append("#${segment.hashtag}")
} }
}
segment.extras?.ifBlank { "" }?.let { if (hashtagIcon != null) {
withStyle(regularText) { withStyle(clickableTextStyle) {
append(it) pushStringAnnotation("routeToHashtag", "")
appendInlineContent("inlineContent", "[icon]")
}
}
segment.extras?.ifBlank { "" }?.let {
withStyle(regularText) {
append(it)
}
} }
} }
} }
@@ -592,8 +592,10 @@ private fun RenderHashtag(
emptyMap() emptyMap()
} }
val pressIndicator = Modifier.clickable { val pressIndicator = remember {
nav("Hashtag/${segment.hashtag}") Modifier.clickable {
nav("Hashtag/${segment.hashtag}")
}
} }
Text( Text(
@@ -41,7 +41,6 @@ import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
@@ -62,11 +61,13 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.Placeholder import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign import androidx.compose.ui.text.PlaceholderVerticalAlign
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
@@ -305,7 +306,9 @@ private fun LocalImageView(
} }
val verifierModifier = if (topPaddingForControllers.isSpecified) { val verifierModifier = if (topPaddingForControllers.isSpecified) {
Modifier.padding(top = topPaddingForControllers).align(Alignment.TopEnd) Modifier
.padding(top = topPaddingForControllers)
.align(Alignment.TopEnd)
} else { } else {
Modifier.align(Alignment.TopEnd) Modifier.align(Alignment.TopEnd)
} }
@@ -373,7 +376,9 @@ private fun UrlImageView(
} }
val verifierModifier = if (topPaddingForControllers.isSpecified) { val verifierModifier = if (topPaddingForControllers.isSpecified) {
Modifier.padding(top = topPaddingForControllers).align(Alignment.TopEnd) Modifier
.padding(top = topPaddingForControllers)
.align(Alignment.TopEnd)
} else { } else {
Modifier.align(Alignment.TopEnd) Modifier.align(Alignment.TopEnd)
} }
@@ -405,11 +410,58 @@ private fun UrlImageView(
} }
} }
@OptIn(ExperimentalLayoutApi::class)
@Composable @Composable
fun ImageUrlWithDownloadButton(url: String, showImage: MutableState<Boolean>) { fun ImageUrlWithDownloadButton(url: String, showImage: MutableState<Boolean>) {
FlowRow() { val uri = LocalUriHandler.current
ClickableUrl(urlText = url, url = url)
val primary = MaterialTheme.colorScheme.primary
val background = MaterialTheme.colorScheme.onBackground
val regularText = remember { SpanStyle(color = background) }
val clickableTextStyle = remember { SpanStyle(color = primary) }
val annotatedTermsString = remember {
buildAnnotatedString {
withStyle(clickableTextStyle) {
pushStringAnnotation("routeToImage", "")
append("$url ")
}
withStyle(clickableTextStyle) {
pushStringAnnotation("routeToImage", "")
appendInlineContent("inlineContent", "[icon]")
}
withStyle(regularText) {
append(" ")
}
}
}
val inlineContent = mapOf("inlineContent" to InlineDownloadIcon(showImage))
val pressIndicator = remember {
Modifier.clickable {
runCatching { uri.openUri(url) }
}
}
Text(
text = annotatedTermsString,
modifier = pressIndicator,
inlineContent = inlineContent
)
}
@Composable
private fun InlineDownloadIcon(showImage: MutableState<Boolean>) =
InlineTextContent(
Placeholder(
width = Font17SP,
height = Font17SP,
placeholderVerticalAlign = PlaceholderVerticalAlign.Center
)
) {
IconButton( IconButton(
modifier = Modifier.size(Size20dp), modifier = Modifier.size(Size20dp),
onClick = { showImage.value = true } onClick = { showImage.value = true }
@@ -417,7 +469,6 @@ fun ImageUrlWithDownloadButton(url: String, showImage: MutableState<Boolean>) {
DownloadForOfflineIcon(Size24dp) DownloadForOfflineIcon(Size24dp)
} }
} }
}
@Composable @Composable
@OptIn(ExperimentalLayoutApi::class) @OptIn(ExperimentalLayoutApi::class)
@@ -548,43 +599,69 @@ private fun DisplayUrlWithLoadingSymbol(content: ZoomableContent) {
@Composable @Composable
private fun DisplayUrlWithLoadingSymbolWait(content: ZoomableContent) { private fun DisplayUrlWithLoadingSymbolWait(content: ZoomableContent) {
if (content is ZoomableUrlContent) { val uri = LocalUriHandler.current
ClickableUrl(urlText = remember { "${content.url} " }, url = content.url)
} else {
Text("Loading content... ")
}
val myId = "inlineContent" val primary = MaterialTheme.colorScheme.primary
val emptytext = buildAnnotatedString { val background = MaterialTheme.colorScheme.onBackground
withStyle(
LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary).toSpanStyle() val regularText = remember { SpanStyle(color = background) }
) { val clickableTextStyle = remember { SpanStyle(color = primary) }
append("")
appendInlineContent(myId, "[icon]") val annotatedTermsString = remember {
buildAnnotatedString {
if (content is ZoomableUrlContent) {
withStyle(clickableTextStyle) {
pushStringAnnotation("routeToImage", "")
append(content.url + " ")
}
} else {
withStyle(regularText) {
append("Loading content...")
}
}
withStyle(clickableTextStyle) {
pushStringAnnotation("routeToImage", "")
appendInlineContent("inlineContent", "[icon]")
}
withStyle(regularText) {
append(" ")
}
}
}
val inlineContent = mapOf("inlineContent" to InlineLoadingIcon())
val pressIndicator = remember {
if (content is ZoomableUrlContent) {
Modifier.clickable {
runCatching { uri.openUri(content.url) }
}
} else {
Modifier
} }
} }
val inlineContent = mapOf(
Pair(
myId,
InlineTextContent(
Placeholder(
width = Font17SP,
height = Font17SP,
placeholderVerticalAlign = PlaceholderVerticalAlign.Center
)
) {
LoadingAnimation()
}
)
)
// Empty Text for Size of Icon
Text( Text(
text = emptytext, text = annotatedTermsString,
modifier = pressIndicator,
inlineContent = inlineContent inlineContent = inlineContent
) )
} }
@Composable
private fun InlineLoadingIcon() =
InlineTextContent(
Placeholder(
width = Font17SP,
height = Font17SP,
placeholderVerticalAlign = PlaceholderVerticalAlign.Center
)
) {
LoadingAnimation()
}
@Composable @Composable
private fun DisplayBlurHash( private fun DisplayBlurHash(
blurhash: String?, blurhash: String?,
@@ -4,7 +4,6 @@ import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@@ -55,15 +54,13 @@ fun RefresheableCardView(
) )
val modifier = if (enablePullRefresh) { val modifier = if (enablePullRefresh) {
Modifier.pullRefresh(pullRefreshState) Modifier.fillMaxSize().pullRefresh(pullRefreshState)
} else { } else {
Modifier Modifier.fillMaxSize()
} }
Box(modifier) { Box(modifier) {
Column { SaveableCardFeedState(viewModel, accountViewModel, nav, routeForLastRead, scrollStateKey)
SaveableCardFeedState(viewModel, accountViewModel, nav, routeForLastRead, scrollStateKey)
}
if (enablePullRefresh) { if (enablePullRefresh) {
PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter)) PullRefreshIndicator(refreshing, pullRefreshState, Modifier.align(Alignment.TopCenter))
@@ -2,7 +2,7 @@ package com.vitorpamplona.amethyst.ui.screen
import android.util.Log import android.util.Log
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
@@ -126,27 +126,25 @@ fun RelayFeedView(
val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh) val pullRefreshState = rememberPullRefreshState(refreshing, onRefresh = refresh)
val modifier = if (enablePullRefresh) { val modifier = if (enablePullRefresh) {
Modifier.pullRefresh(pullRefreshState) Modifier.fillMaxSize().pullRefresh(pullRefreshState)
} else { } else {
Modifier Modifier.fillMaxSize()
} }
Box(modifier) { Box(modifier) {
Column() { val listState = rememberLazyListState()
val listState = rememberLazyListState()
LazyColumn( LazyColumn(
contentPadding = FeedPadding, contentPadding = FeedPadding,
state = listState state = listState
) { ) {
itemsIndexed(feedState, key = { _, item -> item.url }) { _, item -> itemsIndexed(feedState, key = { _, item -> item.url }) { _, item ->
RelayCompose( RelayCompose(
item, item,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
onAddRelay = { wantsToAddRelay = item.url }, onAddRelay = { wantsToAddRelay = item.url },
onRemoveRelay = { wantsToAddRelay = item.url } onRemoveRelay = { wantsToAddRelay = item.url }
) )
}
} }
} }
@@ -3,7 +3,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@@ -17,7 +16,6 @@ import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter
@@ -31,65 +29,58 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun BookmarkListScreen(accountViewModel: AccountViewModel, nav: (String) -> Unit) { fun BookmarkListScreen(accountViewModel: AccountViewModel, nav: (String) -> Unit) {
val accountState by accountViewModel.accountLiveData.observeAsState() BookmarkPublicFeedFilter.account = accountViewModel.account
val account = accountState?.account BookmarkPrivateFeedFilter.account = accountViewModel.account
if (account != null) { val publicFeedViewModel: NostrBookmarkPublicFeedViewModel = viewModel()
BookmarkPublicFeedFilter.account = account val privateFeedViewModel: NostrBookmarkPrivateFeedViewModel = viewModel()
BookmarkPrivateFeedFilter.account = account
val publicFeedViewModel: NostrBookmarkPublicFeedViewModel = viewModel() val userState by accountViewModel.account.userProfile().live().bookmarks.observeAsState()
val privateFeedViewModel: NostrBookmarkPrivateFeedViewModel = viewModel()
val userState by account.userProfile().live().bookmarks.observeAsState() LaunchedEffect(userState) {
publicFeedViewModel.invalidateData()
privateFeedViewModel.invalidateData()
}
LaunchedEffect(userState) { Column(Modifier.fillMaxHeight()) {
publicFeedViewModel.invalidateData() val pagerState = rememberPagerState() { 2 }
privateFeedViewModel.invalidateData() val coroutineScope = rememberCoroutineScope()
TabRow(
containerColor = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground,
selectedTabIndex = pagerState.currentPage,
modifier = TabRowHeight
) {
Tab(
selected = pagerState.currentPage == 0,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(0) } },
text = {
Text(text = stringResource(R.string.private_bookmarks))
}
)
Tab(
selected = pagerState.currentPage == 1,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(1) } },
text = {
Text(text = stringResource(R.string.public_bookmarks))
}
)
} }
HorizontalPager(state = pagerState) { page ->
Column(Modifier.fillMaxHeight()) { when (page) {
Column(modifier = Modifier.padding(start = 10.dp, end = 10.dp)) { 0 -> RefresheableFeedView(
val pagerState = rememberPagerState() { 2 } privateFeedViewModel,
val coroutineScope = rememberCoroutineScope() null,
accountViewModel = accountViewModel,
TabRow( nav = nav
containerColor = MaterialTheme.colorScheme.background, )
contentColor = MaterialTheme.colorScheme.onBackground, 1 -> RefresheableFeedView(
selectedTabIndex = pagerState.currentPage, publicFeedViewModel,
modifier = TabRowHeight null,
) { accountViewModel = accountViewModel,
Tab( nav = nav
selected = pagerState.currentPage == 0, )
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(0) } },
text = {
Text(text = stringResource(R.string.private_bookmarks))
}
)
Tab(
selected = pagerState.currentPage == 1,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(1) } },
text = {
Text(text = stringResource(R.string.public_bookmarks))
}
)
}
HorizontalPager(state = pagerState) { page ->
when (page) {
0 -> RefresheableFeedView(
privateFeedViewModel,
null,
accountViewModel = accountViewModel,
nav = nav
)
1 -> RefresheableFeedView(
publicFeedViewModel,
null,
accountViewModel = accountViewModel,
nav = nav
)
}
}
} }
} }
} }
@@ -58,7 +58,6 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.ButtonPadding import com.vitorpamplona.amethyst.ui.theme.ButtonPadding
import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.DividerThickness
import com.vitorpamplona.amethyst.ui.theme.HorzPadding import com.vitorpamplona.amethyst.ui.theme.HorzPadding
import com.vitorpamplona.amethyst.ui.theme.Size10dp
import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.StdPadding
import com.vitorpamplona.amethyst.ui.theme.TabRowHeight import com.vitorpamplona.amethyst.ui.theme.TabRowHeight
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
@@ -109,78 +108,76 @@ fun HiddenUsersScreen(
} }
Column(Modifier.fillMaxHeight()) { Column(Modifier.fillMaxHeight()) {
Column(modifier = Modifier.padding(start = 10.dp, end = 10.dp)) { val pagerState = rememberPagerState() { 3 }
val pagerState = rememberPagerState() { 3 } val coroutineScope = rememberCoroutineScope()
val coroutineScope = rememberCoroutineScope() var warnAboutReports by remember { mutableStateOf(accountViewModel.account.warnAboutPostsWithReports) }
var warnAboutReports by remember { mutableStateOf(accountViewModel.account.warnAboutPostsWithReports) } var filterSpam by remember { mutableStateOf(accountViewModel.account.filterSpamFromStrangers) }
var filterSpam by remember { mutableStateOf(accountViewModel.account.filterSpamFromStrangers) }
Row(verticalAlignment = Alignment.CenterVertically) { Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox( Checkbox(
checked = warnAboutReports, checked = warnAboutReports,
onCheckedChange = { onCheckedChange = {
warnAboutReports = it warnAboutReports = it
accountViewModel.account.updateOptOutOptions(warnAboutReports, filterSpam) accountViewModel.account.updateOptOutOptions(warnAboutReports, filterSpam)
}
)
Text(stringResource(R.string.warn_when_posts_have_reports_from_your_follows))
}
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = filterSpam,
onCheckedChange = {
filterSpam = it
accountViewModel.account.updateOptOutOptions(warnAboutReports, filterSpam)
}
)
Text(stringResource(R.string.filter_spam_from_strangers))
}
ScrollableTabRow(
containerColor = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground,
edgePadding = 8.dp,
selectedTabIndex = pagerState.currentPage,
modifier = TabRowHeight,
divider = {
Divider(thickness = DividerThickness)
} }
) { )
Tab(
selected = pagerState.currentPage == 0, Text(stringResource(R.string.warn_when_posts_have_reports_from_your_follows))
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(0) } }, }
text = {
Text(text = stringResource(R.string.blocked_users)) Row(verticalAlignment = Alignment.CenterVertically) {
} Checkbox(
) checked = filterSpam,
Tab( onCheckedChange = {
selected = pagerState.currentPage == 1, filterSpam = it
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(1) } }, accountViewModel.account.updateOptOutOptions(warnAboutReports, filterSpam)
text = {
Text(text = stringResource(R.string.spamming_users))
}
)
Tab(
selected = pagerState.currentPage == 2,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(2) } },
text = {
Text(text = stringResource(R.string.hidden_words))
}
)
}
HorizontalPager(state = pagerState) { page ->
when (page) {
0 -> RefreshingUserFeedView(hiddenFeedViewModel, accountViewModel) {
RefreshingFeedUserFeedView(hiddenFeedViewModel, accountViewModel, nav)
}
1 -> RefreshingUserFeedView(spammerFeedViewModel, accountViewModel) {
RefreshingFeedUserFeedView(spammerFeedViewModel, accountViewModel, nav)
}
2 -> HiddenWordsFeed(hiddenWordsViewModel, accountViewModel)
} }
)
Text(stringResource(R.string.filter_spam_from_strangers))
}
ScrollableTabRow(
containerColor = MaterialTheme.colorScheme.background,
contentColor = MaterialTheme.colorScheme.onBackground,
edgePadding = 8.dp,
selectedTabIndex = pagerState.currentPage,
modifier = TabRowHeight,
divider = {
Divider(thickness = DividerThickness)
}
) {
Tab(
selected = pagerState.currentPage == 0,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(0) } },
text = {
Text(text = stringResource(R.string.blocked_users))
}
)
Tab(
selected = pagerState.currentPage == 1,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(1) } },
text = {
Text(text = stringResource(R.string.spamming_users))
}
)
Tab(
selected = pagerState.currentPage == 2,
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(2) } },
text = {
Text(text = stringResource(R.string.hidden_words))
}
)
}
HorizontalPager(state = pagerState) { page ->
when (page) {
0 -> RefreshingUserFeedView(hiddenFeedViewModel, accountViewModel) {
RefreshingFeedUserFeedView(hiddenFeedViewModel, accountViewModel, nav)
}
1 -> RefreshingUserFeedView(spammerFeedViewModel, accountViewModel) {
RefreshingFeedUserFeedView(spammerFeedViewModel, accountViewModel, nav)
}
2 -> HiddenWordsFeed(hiddenWordsViewModel, accountViewModel)
} }
} }
} }
@@ -203,7 +200,7 @@ private fun HiddenWordsFeed(
@Composable @Composable
private fun AddMuteWordTextField(accountViewModel: AccountViewModel) { private fun AddMuteWordTextField(accountViewModel: AccountViewModel) {
Row(modifier = Modifier.padding(vertical = Size10dp)) { Row() {
val currentWordToAdd = remember { val currentWordToAdd = remember {
mutableStateOf("") mutableStateOf("")
} }
@@ -217,7 +214,7 @@ private fun AddMuteWordTextField(accountViewModel: AccountViewModel) {
value = currentWordToAdd.value, value = currentWordToAdd.value,
onValueChange = { currentWordToAdd.value = it }, onValueChange = { currentWordToAdd.value = it },
label = { Text(text = stringResource(R.string.hide_new_word_label)) }, label = { Text(text = stringResource(R.string.hide_new_word_label)) },
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth().padding(10.dp),
placeholder = { placeholder = {
Text( Text(
text = stringResource(R.string.hide_new_word_label), text = stringResource(R.string.hide_new_word_label),
@@ -97,21 +97,17 @@ fun NotificationScreen(
} }
Column(Modifier.fillMaxHeight()) { Column(Modifier.fillMaxHeight()) {
Column( SummaryBar(
modifier = Modifier.padding(vertical = 0.dp) model = userReactionsStatsModel
) { )
SummaryBar(
model = userReactionsStatsModel
)
RefresheableCardView( RefresheableCardView(
viewModel = notifFeedViewModel, viewModel = notifFeedViewModel,
accountViewModel = accountViewModel, accountViewModel = accountViewModel,
nav = nav, nav = nav,
routeForLastRead = Route.Notification.base, routeForLastRead = Route.Notification.base,
scrollStateKey = ScrollStateKeys.NOTIFICATION_SCREEN scrollStateKey = ScrollStateKeys.NOTIFICATION_SCREEN
) )
}
} }
} }
@@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.layout.windowInsetsPadding
@@ -132,6 +133,7 @@ fun SettingsScreen(
Column( Column(
Modifier Modifier
.fillMaxSize()
.padding(top = Size10dp, start = Size20dp, end = Size20dp) .padding(top = Size10dp, start = Size20dp, end = Size20dp)
.verticalScroll(rememberScrollState()), .verticalScroll(rememberScrollState()),
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally