mirror of
https://github.com/TeamNewPipe/NewPipe.git
synced 2025-10-03 17:59:41 +02:00
Merge pull request #12604 from Isira-Seneviratne/Refactor-EmptyState
This commit is contained in:
commit
b2d89a41fb
9 changed files with 77 additions and 132 deletions
|
@ -3,6 +3,7 @@ package org.schabi.newpipe.fragments.list.channel;
|
|||
import static org.schabi.newpipe.ktx.TextViewUtils.animateTextColor;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animateBackgroundColor;
|
||||
import static org.schabi.newpipe.ui.emptystate.EmptyStateUtil.setEmptyStateComposable;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
@ -45,7 +46,6 @@ import org.schabi.newpipe.ktx.AnimationType;
|
|||
import org.schabi.newpipe.local.feed.notifications.NotificationHelper;
|
||||
import org.schabi.newpipe.local.subscription.SubscriptionManager;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||
import org.schabi.newpipe.util.ChannelTabHelper;
|
||||
import org.schabi.newpipe.util.Constants;
|
||||
import org.schabi.newpipe.util.ExtractorHelper;
|
||||
|
@ -200,10 +200,7 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo>
|
|||
protected void initViews(final View rootView, final Bundle savedInstanceState) {
|
||||
super.initViews(rootView, savedInstanceState);
|
||||
|
||||
EmptyStateUtil.setEmptyStateComposable(
|
||||
binding.emptyStateView,
|
||||
EmptyStateSpec.Companion.getContentNotSupported()
|
||||
);
|
||||
setEmptyStateComposable(binding.emptyStateView, EmptyStateSpec.ContentNotSupported);
|
||||
|
||||
tabAdapter = new TabAdapter(getChildFragmentManager());
|
||||
binding.viewPager.setAdapter(tabAdapter);
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.schabi.newpipe.fragments.list.search;
|
|||
import static androidx.recyclerview.widget.ItemTouchHelper.Callback.makeMovementFlags;
|
||||
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
|
||||
import static org.schabi.newpipe.ktx.ViewUtils.animate;
|
||||
import static org.schabi.newpipe.ui.emptystate.EmptyStateUtil.setEmptyStateComposable;
|
||||
import static org.schabi.newpipe.util.ExtractorHelper.showMetaInfoInTextView;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
|
@ -66,7 +67,6 @@ import org.schabi.newpipe.ktx.ExceptionUtils;
|
|||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||
import org.schabi.newpipe.settings.NewPipeSettings;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||
import org.schabi.newpipe.util.Constants;
|
||||
import org.schabi.newpipe.util.DeviceUtils;
|
||||
import org.schabi.newpipe.util.ExtractorHelper;
|
||||
|
@ -357,9 +357,7 @@ public class SearchFragment extends BaseListFragment<SearchInfo, ListExtractor.I
|
|||
protected void initViews(final View rootView, final Bundle savedInstanceState) {
|
||||
super.initViews(rootView, savedInstanceState);
|
||||
|
||||
EmptyStateUtil.setEmptyStateComposable(
|
||||
searchBinding.emptyStateView,
|
||||
EmptyStateSpec.Companion.getNoSearchResult());
|
||||
setEmptyStateComposable(searchBinding.emptyStateView, EmptyStateSpec.NoSearchResult);
|
||||
|
||||
searchBinding.suggestionsList.setAdapter(suggestionListAdapter);
|
||||
// animations are just strange and useless, since the suggestions keep changing too much
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.view.ViewGroup;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.compose.ui.platform.ComposeView;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
@ -125,10 +126,8 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL
|
|||
super.initViews(rootView, savedInstanceState);
|
||||
|
||||
itemListAdapter.setUseItemHandle(true);
|
||||
EmptyStateUtil.setEmptyStateComposable(
|
||||
rootView.findViewById(R.id.empty_state_view),
|
||||
EmptyStateSpec.Companion.getNoBookmarkedPlaylist()
|
||||
);
|
||||
final ComposeView emptyView = rootView.findViewById(R.id.empty_state_view);
|
||||
EmptyStateUtil.setEmptyStateComposable(emptyView, EmptyStateSpec.NoBookmarkedPlaylist);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -95,8 +95,7 @@ public class SelectChannelFragment extends DialogFragment {
|
|||
progressBar = v.findViewById(R.id.progressBar);
|
||||
emptyView = v.findViewById(R.id.empty_state_view);
|
||||
|
||||
EmptyStateUtil.setEmptyStateComposable(emptyView,
|
||||
EmptyStateSpec.Companion.getNoSubscriptions());
|
||||
EmptyStateUtil.setEmptyStateComposable(emptyView, EmptyStateSpec.NoSubscriptions);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
|
|
|
@ -65,8 +65,7 @@ public class SelectPlaylistFragment extends DialogFragment {
|
|||
recyclerView = v.findViewById(R.id.items_list);
|
||||
emptyView = v.findViewById(R.id.empty_state_view);
|
||||
|
||||
EmptyStateUtil.setEmptyStateComposable(emptyView,
|
||||
EmptyStateSpec.Companion.getNoBookmarkedPlaylist());
|
||||
EmptyStateUtil.setEmptyStateComposable(emptyView, EmptyStateSpec.NoBookmarkedPlaylist);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
final SelectPlaylistAdapter playlistAdapter = new SelectPlaylistAdapter();
|
||||
recyclerView.setAdapter(playlistAdapter);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.schabi.newpipe.settings.preferencesearch;
|
||||
|
||||
import static org.schabi.newpipe.ui.emptystate.EmptyStateUtil.setEmptyStateComposable;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -12,7 +14,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
|||
|
||||
import org.schabi.newpipe.databinding.SettingsPreferencesearchFragmentBinding;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -41,9 +42,7 @@ public class PreferenceSearchFragment extends Fragment {
|
|||
binding = SettingsPreferencesearchFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
binding.searchResults.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
EmptyStateUtil.setEmptyStateComposable(
|
||||
binding.emptyStateView,
|
||||
EmptyStateSpec.Companion.getNoSearchMaxSizeResult());
|
||||
setEmptyStateComposable(binding.emptyStateView, EmptyStateSpec.NoSearchResult);
|
||||
|
||||
adapter = new PreferenceSearchAdapter();
|
||||
adapter.setOnItemClickListener(this::onItemClicked);
|
||||
|
|
|
@ -19,7 +19,6 @@ 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
|
||||
|
@ -122,28 +121,23 @@ private fun CommentRepliesDialog(
|
|||
|
||||
if (comments.itemCount == 0) {
|
||||
item {
|
||||
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(
|
||||
spec = EmptyStateSpec.DisabledComments.copy(
|
||||
descriptionText = {
|
||||
stringResource(R.string.error_unable_to_load_comments)
|
||||
when (val refresh = comments.loadState.refresh) {
|
||||
is LoadState.Loading -> {
|
||||
LoadingIndicator(modifier = Modifier.padding(top = 8.dp))
|
||||
}
|
||||
else -> {
|
||||
// TODO use error panel instead
|
||||
EmptyStateComposable(
|
||||
spec = if (refresh is LoadState.Error) {
|
||||
EmptyStateSpec.ErrorLoadingComments
|
||||
} else {
|
||||
EmptyStateSpec.NoComments
|
||||
},
|
||||
),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 128.dp)
|
||||
)
|
||||
} else {
|
||||
EmptyStateComposable(
|
||||
spec = EmptyStateSpec.NoComments,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 128.dp)
|
||||
)
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 128.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -15,7 +15,6 @@ 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
|
||||
|
@ -75,7 +74,6 @@ private fun CommentSection(
|
|||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 128.dp)
|
||||
|
||||
)
|
||||
}
|
||||
} else if (count == 0) {
|
||||
|
@ -111,13 +109,7 @@ private fun CommentSection(
|
|||
is LoadState.Error -> {
|
||||
item {
|
||||
// TODO use error panel instead
|
||||
EmptyStateComposable(
|
||||
EmptyStateSpec.DisabledComments.copy(
|
||||
descriptionText = {
|
||||
stringResource(R.string.error_unable_to_load_comments)
|
||||
}
|
||||
)
|
||||
)
|
||||
EmptyStateComposable(EmptyStateSpec.ErrorLoadingComments)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,11 +126,7 @@ private fun CommentSection(
|
|||
item {
|
||||
// TODO use error panel instead
|
||||
EmptyStateComposable(
|
||||
spec = EmptyStateSpec.DisabledComments.copy(
|
||||
descriptionText = {
|
||||
stringResource(R.string.error_unable_to_load_comments)
|
||||
}
|
||||
),
|
||||
spec = EmptyStateSpec.ErrorLoadingComments,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 128.dp)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.schabi.newpipe.ui.emptystate
|
||||
|
||||
import android.graphics.Color
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
|
@ -22,25 +23,14 @@ import org.schabi.newpipe.ui.theme.AppTheme
|
|||
fun EmptyStateComposable(
|
||||
spec: EmptyStateSpec,
|
||||
modifier: Modifier = Modifier,
|
||||
) = EmptyStateComposable(
|
||||
emojiText = spec.emojiText(),
|
||||
descriptionText = spec.descriptionText(),
|
||||
modifier = modifier
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun EmptyStateComposable(
|
||||
emojiText: String,
|
||||
descriptionText: String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Text(
|
||||
text = emojiText,
|
||||
text = spec.emojiText,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
@ -49,7 +39,7 @@ private fun EmptyStateComposable(
|
|||
modifier = Modifier
|
||||
.padding(top = 6.dp)
|
||||
.padding(horizontal = 16.dp),
|
||||
text = descriptionText,
|
||||
text = stringResource(spec.descriptionText),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
@ -82,66 +72,48 @@ fun EmptyStateComposableNoCommentPreview() {
|
|||
}
|
||||
}
|
||||
|
||||
data class EmptyStateSpec(
|
||||
val emojiText: @Composable () -> String,
|
||||
val descriptionText: @Composable () -> String,
|
||||
enum class EmptyStateSpec(
|
||||
val emojiText: String,
|
||||
@field:StringRes val descriptionText: Int,
|
||||
) {
|
||||
companion object {
|
||||
|
||||
val GenericError =
|
||||
EmptyStateSpec(
|
||||
emojiText = { "¯\\_(ツ)_/¯" },
|
||||
descriptionText = { stringResource(id = R.string.empty_list_subtitle) },
|
||||
)
|
||||
|
||||
val NoVideos =
|
||||
EmptyStateSpec(
|
||||
emojiText = { "(╯°-°)╯" },
|
||||
descriptionText = { stringResource(id = R.string.no_videos) },
|
||||
)
|
||||
|
||||
val NoComments =
|
||||
EmptyStateSpec(
|
||||
|
||||
emojiText = { "¯\\_(╹x╹)_/¯" },
|
||||
descriptionText = { stringResource(id = R.string.no_comments) },
|
||||
)
|
||||
|
||||
val DisabledComments =
|
||||
NoComments.copy(
|
||||
descriptionText = { stringResource(id = R.string.comments_are_disabled) },
|
||||
)
|
||||
|
||||
val NoSearchResult =
|
||||
NoComments.copy(
|
||||
emojiText = { "╰(°●°╰)" },
|
||||
descriptionText = { stringResource(id = R.string.search_no_results) }
|
||||
)
|
||||
|
||||
val NoSearchMaxSizeResult =
|
||||
NoSearchResult
|
||||
|
||||
val ContentNotSupported =
|
||||
NoComments.copy(
|
||||
emojiText = { "(︶︹︺)" },
|
||||
descriptionText = { stringResource(id = R.string.content_not_supported) },
|
||||
)
|
||||
|
||||
val NoBookmarkedPlaylist =
|
||||
EmptyStateSpec(
|
||||
emojiText = { "(╥﹏╥)" },
|
||||
descriptionText = { stringResource(id = R.string.no_playlist_bookmarked_yet) },
|
||||
)
|
||||
|
||||
val NoSubscriptionsHint =
|
||||
EmptyStateSpec(
|
||||
emojiText = { "(꩜ᯅ꩜)" },
|
||||
descriptionText = { stringResource(id = R.string.import_subscriptions_hint) },
|
||||
)
|
||||
|
||||
val NoSubscriptions =
|
||||
NoSubscriptionsHint.copy(
|
||||
descriptionText = { stringResource(id = R.string.no_channel_subscribed_yet) },
|
||||
)
|
||||
}
|
||||
GenericError(
|
||||
emojiText = "¯\\_(ツ)_/¯",
|
||||
descriptionText = R.string.empty_list_subtitle,
|
||||
),
|
||||
NoVideos(
|
||||
emojiText = "(╯°-°)╯",
|
||||
descriptionText = R.string.no_videos,
|
||||
),
|
||||
NoComments(
|
||||
emojiText = "¯\\_(╹x╹)_/¯",
|
||||
descriptionText = R.string.no_comments,
|
||||
),
|
||||
DisabledComments(
|
||||
emojiText = "¯\\_(╹x╹)_/¯",
|
||||
descriptionText = R.string.comments_are_disabled,
|
||||
),
|
||||
ErrorLoadingComments(
|
||||
emojiText = "¯\\_(╹x╹)_/¯",
|
||||
descriptionText = R.string.error_unable_to_load_comments,
|
||||
),
|
||||
NoSearchResult(
|
||||
emojiText = "╰(°●°╰)",
|
||||
descriptionText = R.string.search_no_results,
|
||||
),
|
||||
ContentNotSupported(
|
||||
emojiText = "(︶︹︺)",
|
||||
descriptionText = R.string.content_not_supported,
|
||||
),
|
||||
NoBookmarkedPlaylist(
|
||||
emojiText = "(╥﹏╥)",
|
||||
descriptionText = R.string.no_playlist_bookmarked_yet,
|
||||
),
|
||||
NoSubscriptionsHint(
|
||||
emojiText = "(꩜ᯅ꩜)",
|
||||
descriptionText = R.string.import_subscriptions_hint,
|
||||
),
|
||||
NoSubscriptions(
|
||||
emojiText = "(꩜ᯅ꩜)",
|
||||
descriptionText = R.string.no_channel_subscribed_yet,
|
||||
),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue