1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-01-11 01:40:59 +00:00

Use empty state view in compose

This commit is contained in:
Stypox 2024-11-21 13:14:23 +01:00
parent 414b1a8344
commit c8b01a06b0
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
5 changed files with 94 additions and 92 deletions

View File

@ -1,42 +0,0 @@
package org.schabi.newpipe.ui.components.common
import android.content.res.Configuration
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.sp
import org.schabi.newpipe.R
import org.schabi.newpipe.ui.theme.AppTheme
@Composable
fun NoItemsMessage(@StringRes message: Int) {
Column(
modifier = Modifier
.fillMaxWidth()
.wrapContentSize(Alignment.Center),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "(╯°-°)╯", fontSize = 35.sp)
Text(text = stringResource(id = message), fontSize = 24.sp)
}
}
@Preview(name = "Light mode", uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(name = "Dark mode", uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun NoItemsMessagePreview() {
AppTheme {
Surface(color = MaterialTheme.colorScheme.background) {
NoItemsMessage(message = R.string.no_videos)
}
}
}

View File

@ -26,9 +26,10 @@ import org.schabi.newpipe.R
import org.schabi.newpipe.extractor.stream.StreamInfo import org.schabi.newpipe.extractor.stream.StreamInfo
import org.schabi.newpipe.extractor.stream.StreamType import org.schabi.newpipe.extractor.stream.StreamType
import org.schabi.newpipe.info_list.ItemViewMode import org.schabi.newpipe.info_list.ItemViewMode
import org.schabi.newpipe.ui.components.common.NoItemsMessage
import org.schabi.newpipe.ui.components.items.ItemList import org.schabi.newpipe.ui.components.items.ItemList
import org.schabi.newpipe.ui.components.items.stream.StreamInfoItem import org.schabi.newpipe.ui.components.items.stream.StreamInfoItem
import org.schabi.newpipe.ui.emptystate.EmptyStateComposable
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec
import org.schabi.newpipe.ui.theme.AppTheme import org.schabi.newpipe.ui.theme.AppTheme
import org.schabi.newpipe.util.NO_SERVICE_ID import org.schabi.newpipe.util.NO_SERVICE_ID
@ -41,9 +42,6 @@ fun RelatedItems(info: StreamInfo) {
mutableStateOf(sharedPreferences.getBoolean(key, false)) mutableStateOf(sharedPreferences.getBoolean(key, false))
} }
if (info.relatedItems.isEmpty()) {
NoItemsMessage(message = R.string.no_videos)
} else {
ItemList( ItemList(
items = info.relatedItems, items = info.relatedItems,
mode = ItemViewMode.LIST, mode = ItemViewMode.LIST,
@ -75,9 +73,13 @@ fun RelatedItems(info: StreamInfo) {
} }
} }
} }
if (info.relatedItems.isEmpty()) {
item {
EmptyStateComposable(EmptyStateSpec.NoVideos)
}
}
} }
) )
}
} }
@Preview(name = "Light mode", uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(name = "Light mode", uiMode = Configuration.UI_MODE_NIGHT_NO)

View File

@ -20,6 +20,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -38,7 +39,8 @@ import org.schabi.newpipe.extractor.stream.Description
import org.schabi.newpipe.paging.CommentRepliesSource import org.schabi.newpipe.paging.CommentRepliesSource
import org.schabi.newpipe.ui.components.common.LazyColumnThemedScrollbar import org.schabi.newpipe.ui.components.common.LazyColumnThemedScrollbar
import org.schabi.newpipe.ui.components.common.LoadingIndicator import org.schabi.newpipe.ui.components.common.LoadingIndicator
import org.schabi.newpipe.ui.components.common.NoItemsMessage import org.schabi.newpipe.ui.emptystate.EmptyStateComposable
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec
import org.schabi.newpipe.ui.theme.AppTheme import org.schabi.newpipe.ui.theme.AppTheme
@Composable @Composable
@ -130,13 +132,17 @@ private fun CommentRepliesDialog(
val refresh = comments.loadState.refresh val refresh = comments.loadState.refresh
if (refresh is LoadState.Loading) { if (refresh is LoadState.Loading) {
LoadingIndicator(modifier = Modifier.padding(top = 8.dp)) LoadingIndicator(modifier = Modifier.padding(top = 8.dp))
} else { } else if (refresh is LoadState.Error) {
val message = if (refresh is LoadState.Error) { // TODO use error panel instead
R.string.error_unable_to_load_comments EmptyStateComposable(
} else { EmptyStateSpec.DisabledComments.copy(
R.string.no_comments descriptionText = {
stringResource(R.string.error_unable_to_load_comments)
} }
NoItemsMessage(message) )
)
} else {
EmptyStateComposable(EmptyStateSpec.NoComments)
} }
} }
} else { } else {

View File

@ -13,6 +13,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
@ -28,7 +29,8 @@ import org.schabi.newpipe.extractor.comments.CommentsInfoItem
import org.schabi.newpipe.extractor.stream.Description import org.schabi.newpipe.extractor.stream.Description
import org.schabi.newpipe.ui.components.common.LazyColumnThemedScrollbar import org.schabi.newpipe.ui.components.common.LazyColumnThemedScrollbar
import org.schabi.newpipe.ui.components.common.LoadingIndicator import org.schabi.newpipe.ui.components.common.LoadingIndicator
import org.schabi.newpipe.ui.components.common.NoItemsMessage import org.schabi.newpipe.ui.emptystate.EmptyStateComposable
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec
import org.schabi.newpipe.ui.theme.AppTheme import org.schabi.newpipe.ui.theme.AppTheme
import org.schabi.newpipe.viewmodels.CommentsViewModel import org.schabi.newpipe.viewmodels.CommentsViewModel
import org.schabi.newpipe.viewmodels.util.Resource import org.schabi.newpipe.viewmodels.util.Resource
@ -66,11 +68,11 @@ private fun CommentSection(
if (commentInfo.isCommentsDisabled) { if (commentInfo.isCommentsDisabled) {
item { item {
NoItemsMessage(R.string.comments_are_disabled) EmptyStateComposable(EmptyStateSpec.DisabledComments)
} }
} else if (count == 0) { } else if (count == 0) {
item { item {
NoItemsMessage(R.string.no_comments) EmptyStateComposable(EmptyStateSpec.NoComments)
} }
} else { } else {
// do not show anything if the comment count is unknown // do not show anything if the comment count is unknown
@ -95,7 +97,14 @@ private fun CommentSection(
is LoadState.Error -> { is LoadState.Error -> {
item { item {
NoItemsMessage(R.string.error_unable_to_load_comments) // TODO use error panel instead
EmptyStateComposable(
EmptyStateSpec.DisabledComments.copy(
descriptionText = {
stringResource(R.string.error_unable_to_load_comments)
}
)
)
} }
} }
@ -110,7 +119,14 @@ private fun CommentSection(
is Resource.Error -> { is Resource.Error -> {
item { item {
NoItemsMessage(R.string.error_unable_to_load_comments) // TODO use error panel instead
EmptyStateComposable(
EmptyStateSpec.DisabledComments.copy(
descriptionText = {
stringResource(R.string.error_unable_to_load_comments)
}
)
)
} }
} }
} }

View File

@ -69,7 +69,7 @@ fun EmptyStateComposableGenericErrorPreview() {
@Composable @Composable
fun EmptyStateComposableNoCommentPreview() { fun EmptyStateComposableNoCommentPreview() {
AppTheme { AppTheme {
EmptyStateComposable(EmptyStateSpec.NoComment) EmptyStateComposable(EmptyStateSpec.NoComments)
} }
} }
@ -91,15 +91,35 @@ data class EmptyStateSpec(
descriptionText = { stringResource(id = R.string.empty_list_subtitle) }, descriptionText = { stringResource(id = R.string.empty_list_subtitle) },
) )
val NoComment = val NoVideos =
EmptyStateSpec( EmptyStateSpec(
modifier = { it.padding(top = 85.dp) }, modifier = {
it
.fillMaxWidth()
.heightIn(min = 128.dp)
},
emojiText = { "(╯°-°)╯" }, emojiText = { "(╯°-°)╯" },
descriptionText = { stringResource(id = R.string.no_videos) },
)
val NoComments =
EmptyStateSpec(
modifier = {
it
.fillMaxWidth()
.heightIn(min = 128.dp)
},
emojiText = { "¯\\_(╹x╹)_/¯" },
descriptionText = { stringResource(id = R.string.no_comments) }, descriptionText = { stringResource(id = R.string.no_comments) },
) )
val DisabledComments =
NoComments.copy(
descriptionText = { stringResource(id = R.string.comments_are_disabled) },
)
val NoSearchResult = val NoSearchResult =
NoComment.copy( NoComments.copy(
modifier = { it }, modifier = { it },
emojiText = { "╰(°●°╰)" }, emojiText = { "╰(°●°╰)" },
descriptionText = { stringResource(id = R.string.search_no_results) } descriptionText = { stringResource(id = R.string.search_no_results) }
@ -111,7 +131,7 @@ data class EmptyStateSpec(
) )
val ContentNotSupported = val ContentNotSupported =
NoComment.copy( NoComments.copy(
modifier = { it.padding(top = 90.dp) }, modifier = { it.padding(top = 90.dp) },
emojiText = { "(︶︹︺)" }, emojiText = { "(︶︹︺)" },
descriptionText = { stringResource(id = R.string.content_not_supported) }, descriptionText = { stringResource(id = R.string.content_not_supported) },