1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-12-23 08:30:44 +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.StreamType
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.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.util.NO_SERVICE_ID
@ -41,43 +42,44 @@ fun RelatedItems(info: StreamInfo) {
mutableStateOf(sharedPreferences.getBoolean(key, false))
}
if (info.relatedItems.isEmpty()) {
NoItemsMessage(message = R.string.no_videos)
} else {
ItemList(
items = info.relatedItems,
mode = ItemViewMode.LIST,
listHeader = {
item {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 12.dp, end = 12.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Text(text = stringResource(R.string.auto_queue_description))
ItemList(
items = info.relatedItems,
mode = ItemViewMode.LIST,
listHeader = {
item {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 12.dp, end = 12.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Text(text = stringResource(R.string.auto_queue_description))
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(text = stringResource(R.string.auto_queue_toggle))
Switch(
checked = isAutoQueueEnabled,
onCheckedChange = {
isAutoQueueEnabled = it
sharedPreferences.edit {
putBoolean(key, it)
}
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(text = stringResource(R.string.auto_queue_toggle))
Switch(
checked = isAutoQueueEnabled,
onCheckedChange = {
isAutoQueueEnabled = it
sharedPreferences.edit {
putBoolean(key, it)
}
)
}
}
)
}
}
}
)
}
if (info.relatedItems.isEmpty()) {
item {
EmptyStateComposable(EmptyStateSpec.NoVideos)
}
}
}
)
}
@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.platform.rememberNestedScrollInteropConnection
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.datasource.LoremIpsum
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.ui.components.common.LazyColumnThemedScrollbar
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
@Composable
@ -130,13 +132,17 @@ private fun CommentRepliesDialog(
val refresh = comments.loadState.refresh
if (refresh is LoadState.Loading) {
LoadingIndicator(modifier = Modifier.padding(top = 8.dp))
} else if (refresh is LoadState.Error) {
// TODO use error panel instead
EmptyStateComposable(
EmptyStateSpec.DisabledComments.copy(
descriptionText = {
stringResource(R.string.error_unable_to_load_comments)
}
)
)
} else {
val message = if (refresh is LoadState.Error) {
R.string.error_unable_to_load_comments
} else {
R.string.no_comments
}
NoItemsMessage(message)
EmptyStateComposable(EmptyStateSpec.NoComments)
}
}
} else {

View File

@ -13,6 +13,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
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.ui.components.common.LazyColumnThemedScrollbar
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.viewmodels.CommentsViewModel
import org.schabi.newpipe.viewmodels.util.Resource
@ -66,11 +68,11 @@ private fun CommentSection(
if (commentInfo.isCommentsDisabled) {
item {
NoItemsMessage(R.string.comments_are_disabled)
EmptyStateComposable(EmptyStateSpec.DisabledComments)
}
} else if (count == 0) {
item {
NoItemsMessage(R.string.no_comments)
EmptyStateComposable(EmptyStateSpec.NoComments)
}
} else {
// do not show anything if the comment count is unknown
@ -95,7 +97,14 @@ private fun CommentSection(
is LoadState.Error -> {
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 -> {
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
fun EmptyStateComposableNoCommentPreview() {
AppTheme {
EmptyStateComposable(EmptyStateSpec.NoComment)
EmptyStateComposable(EmptyStateSpec.NoComments)
}
}
@ -91,15 +91,35 @@ data class EmptyStateSpec(
descriptionText = { stringResource(id = R.string.empty_list_subtitle) },
)
val NoComment =
val NoVideos =
EmptyStateSpec(
modifier = { it.padding(top = 85.dp) },
modifier = {
it
.fillMaxWidth()
.heightIn(min = 128.dp)
},
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) },
)
val DisabledComments =
NoComments.copy(
descriptionText = { stringResource(id = R.string.comments_are_disabled) },
)
val NoSearchResult =
NoComment.copy(
NoComments.copy(
modifier = { it },
emojiText = { "╰(°●°╰)" },
descriptionText = { stringResource(id = R.string.search_no_results) }
@ -111,7 +131,7 @@ data class EmptyStateSpec(
)
val ContentNotSupported =
NoComment.copy(
NoComments.copy(
modifier = { it.padding(top = 90.dp) },
emojiText = { "(︶︹︺)" },
descriptionText = { stringResource(id = R.string.content_not_supported) },