mirror of
https://github.com/TeamNewPipe/NewPipe.git
synced 2024-11-25 04:22:30 +01:00
Merge pull request #11725 from Profpatsch/lwj.compose_migrate_empty_state_view
Migrate empty_state_view xml/view to Jetpack Compose
This commit is contained in:
commit
9b78e49e45
@ -6,9 +6,11 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.compose.ui.platform.ComposeView;
|
||||
|
||||
import org.schabi.newpipe.BaseFragment;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||
|
||||
public class EmptyFragment extends BaseFragment {
|
||||
private static final String SHOW_MESSAGE = "SHOW_MESSAGE";
|
||||
@ -26,8 +28,10 @@ public class EmptyFragment extends BaseFragment {
|
||||
final Bundle savedInstanceState) {
|
||||
final boolean showMessage = getArguments().getBoolean(SHOW_MESSAGE);
|
||||
final View view = inflater.inflate(R.layout.fragment_empty, container, false);
|
||||
view.findViewById(R.id.empty_state_view).setVisibility(
|
||||
showMessage ? View.VISIBLE : View.GONE);
|
||||
|
||||
final ComposeView composeView = view.findViewById(R.id.empty_state_view);
|
||||
EmptyStateUtil.setEmptyStateComposable(composeView);
|
||||
composeView.setVisibility(showMessage ? View.VISIBLE : View.GONE);
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
@ -45,6 +44,8 @@ import org.schabi.newpipe.fragments.detail.TabAdapter;
|
||||
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;
|
||||
@ -199,6 +200,11 @@ 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()
|
||||
);
|
||||
|
||||
tabAdapter = new TabAdapter(getChildFragmentManager());
|
||||
binding.viewPager.setAdapter(tabAdapter);
|
||||
binding.tabLayout.setupWithViewPager(binding.viewPager);
|
||||
@ -645,8 +651,6 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo>
|
||||
return;
|
||||
}
|
||||
|
||||
binding.errorContentNotSupported.setVisibility(View.VISIBLE);
|
||||
binding.channelKaomoji.setText("(︶︹︺)");
|
||||
binding.channelKaomoji.setTextSize(TypedValue.COMPLEX_UNIT_SP, 45f);
|
||||
binding.emptyStateView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
|
||||
import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder;
|
||||
import org.schabi.newpipe.player.playqueue.ChannelTabPlayQueue;
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||
import org.schabi.newpipe.util.ChannelTabHelper;
|
||||
import org.schabi.newpipe.util.ExtractorHelper;
|
||||
import org.schabi.newpipe.util.PlayButtonHelper;
|
||||
@ -79,6 +80,12 @@ public class ChannelTabFragment extends BaseListInfoFragment<InfoItem, ChannelTa
|
||||
return inflater.inflate(R.layout.fragment_channel_tab, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull final View rootView, final Bundle savedInstanceState) {
|
||||
super.onViewCreated(rootView, savedInstanceState);
|
||||
EmptyStateUtil.setEmptyStateComposable(rootView.findViewById(R.id.empty_state_view));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
|
@ -64,6 +64,8 @@ import org.schabi.newpipe.ktx.AnimationType;
|
||||
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;
|
||||
@ -344,6 +346,10 @@ 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());
|
||||
|
||||
searchBinding.suggestionsList.setAdapter(suggestionListAdapter);
|
||||
// animations are just strange and useless, since the suggestions keep changing too much
|
||||
searchBinding.suggestionsList.setItemAnimator(null);
|
||||
|
@ -38,6 +38,8 @@ import org.schabi.newpipe.local.holder.LocalBookmarkPlaylistItemHolder;
|
||||
import org.schabi.newpipe.local.holder.RemoteBookmarkPlaylistItemHolder;
|
||||
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
|
||||
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.OnClickGesture;
|
||||
import org.schabi.newpipe.util.debounce.DebounceSavable;
|
||||
@ -123,6 +125,10 @@ 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()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,6 +74,7 @@ import org.schabi.newpipe.ktx.slideUp
|
||||
import org.schabi.newpipe.local.feed.item.StreamItem
|
||||
import org.schabi.newpipe.local.feed.service.FeedLoadService
|
||||
import org.schabi.newpipe.local.subscription.SubscriptionManager
|
||||
import org.schabi.newpipe.ui.emptystate.setEmptyStateComposable
|
||||
import org.schabi.newpipe.util.DeviceUtils
|
||||
import org.schabi.newpipe.util.Localization
|
||||
import org.schabi.newpipe.util.NavigationHelper
|
||||
@ -132,6 +133,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
||||
override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) {
|
||||
// super.onViewCreated() calls initListeners() which require the binding to be initialized
|
||||
_feedBinding = FragmentFeedBinding.bind(rootView)
|
||||
feedBinding.emptyStateView.setEmptyStateComposable()
|
||||
super.onViewCreated(rootView, savedInstanceState)
|
||||
|
||||
val factory = FeedViewModel.getFactory(requireContext(), groupId)
|
||||
|
@ -56,6 +56,7 @@ import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService
|
||||
import org.schabi.newpipe.local.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE
|
||||
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
|
||||
import org.schabi.newpipe.streams.io.StoredFileHelper
|
||||
import org.schabi.newpipe.ui.emptystate.setEmptyStateComposable
|
||||
import org.schabi.newpipe.util.NavigationHelper
|
||||
import org.schabi.newpipe.util.OnClickGesture
|
||||
import org.schabi.newpipe.util.ServiceHelper
|
||||
@ -257,6 +258,8 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
||||
binding.itemsList.adapter = groupAdapter
|
||||
binding.itemsList.itemAnimator = null
|
||||
|
||||
binding.emptyStateView.setEmptyStateComposable()
|
||||
|
||||
viewModel = ViewModelProvider(this)[SubscriptionViewModel::class.java]
|
||||
viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(this::handleResult) }
|
||||
viewModel.feedGroupsLiveData.observe(viewLifecycleOwner) {
|
||||
|
@ -3,14 +3,18 @@ package org.schabi.newpipe.local.subscription.item
|
||||
import android.view.View
|
||||
import com.xwray.groupie.viewbinding.BindableItem
|
||||
import org.schabi.newpipe.R
|
||||
import org.schabi.newpipe.databinding.ListEmptyViewBinding
|
||||
import org.schabi.newpipe.databinding.ListEmptyViewSubscriptionsBinding
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec
|
||||
import org.schabi.newpipe.ui.emptystate.setEmptyStateComposable
|
||||
|
||||
/**
|
||||
* When there are no subscriptions, show a hint to the user about how to import subscriptions
|
||||
*/
|
||||
class ImportSubscriptionsHintPlaceholderItem : BindableItem<ListEmptyViewBinding>() {
|
||||
class ImportSubscriptionsHintPlaceholderItem : BindableItem<ListEmptyViewSubscriptionsBinding>() {
|
||||
override fun getLayout(): Int = R.layout.list_empty_view_subscriptions
|
||||
override fun bind(viewBinding: ListEmptyViewBinding, position: Int) {}
|
||||
override fun bind(viewBinding: ListEmptyViewSubscriptionsBinding, position: Int) {
|
||||
viewBinding.root.setEmptyStateComposable(EmptyStateSpec.NoSubscriptionsHint)
|
||||
}
|
||||
override fun getSpanSize(spanCount: Int, position: Int): Int = spanCount
|
||||
override fun initializeViewBinding(view: View) = ListEmptyViewBinding.bind(view)
|
||||
override fun initializeViewBinding(view: View) = ListEmptyViewSubscriptionsBinding.bind(view)
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.compose.ui.platform.ComposeView;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@ -19,6 +20,8 @@ import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.database.subscription.SubscriptionEntity;
|
||||
import org.schabi.newpipe.error.ErrorUtil;
|
||||
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.ThemeHelper;
|
||||
import org.schabi.newpipe.util.image.CoilHelper;
|
||||
|
||||
@ -57,7 +60,7 @@ public class SelectChannelFragment extends DialogFragment {
|
||||
private OnCancelListener onCancelListener = null;
|
||||
|
||||
private ProgressBar progressBar;
|
||||
private TextView emptyView;
|
||||
private ComposeView emptyView;
|
||||
private RecyclerView recyclerView;
|
||||
|
||||
private List<SubscriptionEntity> subscriptions = new Vector<>();
|
||||
@ -91,6 +94,9 @@ 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());
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
|
@ -11,6 +11,7 @@ import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.compose.ui.platform.ComposeView;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@ -27,6 +28,8 @@ import org.schabi.newpipe.error.ErrorUtil;
|
||||
import org.schabi.newpipe.error.UserAction;
|
||||
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
|
||||
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||
import org.schabi.newpipe.util.image.CoilHelper;
|
||||
|
||||
import java.util.List;
|
||||
@ -40,7 +43,7 @@ public class SelectPlaylistFragment extends DialogFragment {
|
||||
private OnSelectedListener onSelectedListener = null;
|
||||
|
||||
private ProgressBar progressBar;
|
||||
private TextView emptyView;
|
||||
private ComposeView emptyView;
|
||||
private RecyclerView recyclerView;
|
||||
private Disposable disposable = null;
|
||||
|
||||
@ -62,6 +65,8 @@ 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());
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
final SelectPlaylistAdapter playlistAdapter = new SelectPlaylistAdapter();
|
||||
recyclerView.setAdapter(playlistAdapter);
|
||||
|
@ -11,6 +11,8 @@ import androidx.fragment.app.Fragment;
|
||||
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;
|
||||
|
||||
@ -39,6 +41,9 @@ public class PreferenceSearchFragment extends Fragment {
|
||||
binding = SettingsPreferencesearchFragmentBinding.inflate(inflater, container, false);
|
||||
|
||||
binding.searchResults.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
EmptyStateUtil.setEmptyStateComposable(
|
||||
binding.emptyStateView,
|
||||
EmptyStateSpec.Companion.getNoSearchMaxSizeResult());
|
||||
|
||||
adapter = new PreferenceSearchAdapter();
|
||||
adapter.setOnItemClickListener(this::onItemClicked);
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,159 @@
|
||||
package org.schabi.newpipe.ui.emptystate
|
||||
|
||||
import android.graphics.Color
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
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.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.schabi.newpipe.R
|
||||
import org.schabi.newpipe.ui.theme.AppTheme
|
||||
|
||||
@Composable
|
||||
fun EmptyStateComposable(
|
||||
spec: EmptyStateSpec,
|
||||
modifier: Modifier = Modifier,
|
||||
) = EmptyStateComposable(
|
||||
modifier = spec.modifier(modifier),
|
||||
emojiText = spec.emojiText(),
|
||||
descriptionText = spec.descriptionText(),
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun EmptyStateComposable(
|
||||
emojiText: String,
|
||||
descriptionText: String,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = emojiText,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(top = 6.dp)
|
||||
.padding(horizontal = 16.dp),
|
||||
text = descriptionText,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, backgroundColor = Color.WHITE.toLong())
|
||||
@Composable
|
||||
fun EmptyStateComposableGenericErrorPreview() {
|
||||
AppTheme {
|
||||
EmptyStateComposable(EmptyStateSpec.GenericError)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, backgroundColor = Color.WHITE.toLong())
|
||||
@Composable
|
||||
fun EmptyStateComposableNoCommentPreview() {
|
||||
AppTheme {
|
||||
EmptyStateComposable(EmptyStateSpec.NoComments)
|
||||
}
|
||||
}
|
||||
|
||||
data class EmptyStateSpec(
|
||||
val modifier: (Modifier) -> Modifier,
|
||||
val emojiText: @Composable () -> String,
|
||||
val descriptionText: @Composable () -> String,
|
||||
) {
|
||||
companion object {
|
||||
|
||||
val GenericError =
|
||||
EmptyStateSpec(
|
||||
modifier = {
|
||||
it
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 128.dp)
|
||||
},
|
||||
emojiText = { "¯\\_(ツ)_/¯" },
|
||||
descriptionText = { stringResource(id = R.string.empty_list_subtitle) },
|
||||
)
|
||||
|
||||
val NoVideos =
|
||||
EmptyStateSpec(
|
||||
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 =
|
||||
NoComments.copy(
|
||||
modifier = { it },
|
||||
emojiText = { "╰(°●°╰)" },
|
||||
descriptionText = { stringResource(id = R.string.search_no_results) }
|
||||
)
|
||||
|
||||
val NoSearchMaxSizeResult =
|
||||
NoSearchResult.copy(
|
||||
modifier = { it.fillMaxSize() },
|
||||
)
|
||||
|
||||
val ContentNotSupported =
|
||||
NoComments.copy(
|
||||
modifier = { it.padding(top = 90.dp) },
|
||||
emojiText = { "(︶︹︺)" },
|
||||
descriptionText = { stringResource(id = R.string.content_not_supported) },
|
||||
)
|
||||
|
||||
val NoBookmarkedPlaylist =
|
||||
EmptyStateSpec(
|
||||
modifier = { it },
|
||||
emojiText = { "(╥﹏╥)" },
|
||||
descriptionText = { stringResource(id = R.string.no_playlist_bookmarked_yet) },
|
||||
)
|
||||
|
||||
val NoSubscriptionsHint =
|
||||
EmptyStateSpec(
|
||||
modifier = { it },
|
||||
emojiText = { "(꩜ᯅ꩜)" },
|
||||
descriptionText = { stringResource(id = R.string.import_subscriptions_hint) },
|
||||
)
|
||||
|
||||
val NoSubscriptions =
|
||||
NoSubscriptionsHint.copy(
|
||||
descriptionText = { stringResource(id = R.string.no_channel_subscribed_yet) },
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
@file:JvmName("EmptyStateUtil")
|
||||
|
||||
package org.schabi.newpipe.ui.emptystate
|
||||
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.contentColorFor
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import org.schabi.newpipe.ui.theme.AppTheme
|
||||
|
||||
@JvmOverloads
|
||||
fun ComposeView.setEmptyStateComposable(
|
||||
spec: EmptyStateSpec = EmptyStateSpec.GenericError,
|
||||
strategy: ViewCompositionStrategy = ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed,
|
||||
) = apply {
|
||||
setViewCompositionStrategy(strategy)
|
||||
setContent {
|
||||
AppTheme {
|
||||
CompositionLocalProvider(
|
||||
LocalContentColor provides contentColorFor(MaterialTheme.colorScheme.background)
|
||||
) {
|
||||
EmptyStateComposable(
|
||||
spec = spec
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.compose.ui.platform.ComposeView;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
@ -34,6 +35,7 @@ import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.settings.NewPipeSettings;
|
||||
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
|
||||
import org.schabi.newpipe.streams.io.StoredFileHelper;
|
||||
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||
import org.schabi.newpipe.util.FilePickerActivityHelper;
|
||||
|
||||
import java.io.File;
|
||||
@ -108,7 +110,8 @@ public class MissionsFragment extends Fragment {
|
||||
mContext.bindService(new Intent(mContext, DownloadManagerService.class), mConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
// Views
|
||||
mEmpty = v.findViewById(R.id.list_empty_view);
|
||||
mEmpty = v.findViewById(R.id.empty_state_view);
|
||||
EmptyStateUtil.setEmptyStateComposable((ComposeView) mEmpty);
|
||||
mList = v.findViewById(R.id.mission_recycler);
|
||||
|
||||
// Init layouts managers
|
||||
|
@ -24,15 +24,15 @@
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<include
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
layout="@layout/list_empty_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginTop="50dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
|
@ -168,37 +168,14 @@
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="90dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:id="@+id/channel_kaomoji"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:fontFamily="monospace"
|
||||
android:text="(︶︹︺)"
|
||||
android:textSize="35sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:id="@+id/error_content_not_supported"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="@string/content_not_supported"
|
||||
android:textSize="15sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
|
||||
<!--ERROR PANEL-->
|
||||
<include
|
||||
|
@ -20,15 +20,15 @@
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<include
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
layout="@layout/list_empty_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
|
||||
<!--ERROR PANEL-->
|
||||
<include
|
||||
|
@ -20,36 +20,14 @@
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="90dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:id="@+id/channel_kaomoji"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:fontFamily="monospace"
|
||||
android:text="(╯°-°)╯"
|
||||
android:textSize="35sp"
|
||||
tools:ignore="HardcodedText,UnusedAttribute" />
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:id="@+id/channel_no_videos"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/empty_view_no_videos"
|
||||
android:textSize="24sp" />
|
||||
|
||||
</LinearLayout>
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
|
||||
<!--ERROR PANEL-->
|
||||
<include
|
||||
|
@ -7,12 +7,13 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
layout="@layout/list_empty_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="90dp" />
|
||||
android:layout_marginTop="90dp"
|
||||
/>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</RelativeLayout>
|
||||
|
@ -140,15 +140,15 @@
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<include
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
layout="@layout/list_empty_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginTop="50dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
|
@ -52,33 +52,14 @@
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:fontFamily="monospace"
|
||||
android:text="╰(°●°╰)"
|
||||
android:textSize="35sp"
|
||||
tools:ignore="HardcodedText,UnusedAttribute" />
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/search_no_results"
|
||||
android:textSize="24sp" />
|
||||
|
||||
</LinearLayout>
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/suggestions_panel"
|
||||
|
@ -24,16 +24,16 @@
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<include
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
layout="@layout/list_empty_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/items_list"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginTop="50dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:minHeight="128dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="¯\\_(ツ)_/¯"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="6dp"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/empty_list_subtitle" />
|
||||
</LinearLayout>
|
@ -1,25 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:minHeight="128dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="¯\\_(ツ)_/¯"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="6dp"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/import_subscriptions_hint" />
|
||||
</LinearLayout>
|
||||
xmlns:android="http://schemas.android.com/apk/res/android" />
|
||||
|
@ -3,10 +3,11 @@
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/list_empty_view"
|
||||
layout="@layout/list_empty_view"
|
||||
android:visibility="gone" />
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="128dp" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/mission_recycler"
|
||||
|
@ -24,14 +24,11 @@
|
||||
android:layout_height="wrap_content"
|
||||
tools:listitem="@layout/select_channel_item" />
|
||||
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:text="@string/no_channel_subscribed_yet"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem" />
|
||||
android:layout_margin="10dp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
|
@ -26,14 +26,11 @@
|
||||
|
||||
</androidx.recyclerview.widget.RecyclerView>
|
||||
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
android:text="@string/no_playlist_bookmarked_yet"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem" />
|
||||
android:layout_margin="10dp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
|
@ -12,33 +12,14 @@
|
||||
android:layout_height="4dp"
|
||||
android:background="?attr/toolbar_shadow" />
|
||||
|
||||
<LinearLayout
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:id="@+id/empty_state_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
tools:visibility="gone">
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:fontFamily="monospace"
|
||||
android:text="╰(°●°╰)"
|
||||
android:textSize="35sp"
|
||||
tools:ignore="HardcodedText,UnusedAttribute" />
|
||||
|
||||
<org.schabi.newpipe.views.NewPipeTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/search_no_results"
|
||||
android:textSize="24sp" />
|
||||
|
||||
</LinearLayout>
|
||||
tools:visibility="gone"
|
||||
/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/searchResults"
|
||||
|
Loading…
Reference in New Issue
Block a user