mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-23 08:30:44 +00: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 android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.compose.ui.platform.ComposeView;
|
||||||
|
|
||||||
import org.schabi.newpipe.BaseFragment;
|
import org.schabi.newpipe.BaseFragment;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||||
|
|
||||||
public class EmptyFragment extends BaseFragment {
|
public class EmptyFragment extends BaseFragment {
|
||||||
private static final String SHOW_MESSAGE = "SHOW_MESSAGE";
|
private static final String SHOW_MESSAGE = "SHOW_MESSAGE";
|
||||||
@ -26,8 +28,10 @@ public class EmptyFragment extends BaseFragment {
|
|||||||
final Bundle savedInstanceState) {
|
final Bundle savedInstanceState) {
|
||||||
final boolean showMessage = getArguments().getBoolean(SHOW_MESSAGE);
|
final boolean showMessage = getArguments().getBoolean(SHOW_MESSAGE);
|
||||||
final View view = inflater.inflate(R.layout.fragment_empty, container, false);
|
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;
|
return view;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import android.graphics.Color;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
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.ktx.AnimationType;
|
||||||
import org.schabi.newpipe.local.feed.notifications.NotificationHelper;
|
import org.schabi.newpipe.local.feed.notifications.NotificationHelper;
|
||||||
import org.schabi.newpipe.local.subscription.SubscriptionManager;
|
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.ChannelTabHelper;
|
||||||
import org.schabi.newpipe.util.Constants;
|
import org.schabi.newpipe.util.Constants;
|
||||||
import org.schabi.newpipe.util.ExtractorHelper;
|
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) {
|
protected void initViews(final View rootView, final Bundle savedInstanceState) {
|
||||||
super.initViews(rootView, savedInstanceState);
|
super.initViews(rootView, savedInstanceState);
|
||||||
|
|
||||||
|
EmptyStateUtil.setEmptyStateComposable(
|
||||||
|
binding.emptyStateView,
|
||||||
|
EmptyStateSpec.Companion.getContentNotSupported()
|
||||||
|
);
|
||||||
|
|
||||||
tabAdapter = new TabAdapter(getChildFragmentManager());
|
tabAdapter = new TabAdapter(getChildFragmentManager());
|
||||||
binding.viewPager.setAdapter(tabAdapter);
|
binding.viewPager.setAdapter(tabAdapter);
|
||||||
binding.tabLayout.setupWithViewPager(binding.viewPager);
|
binding.tabLayout.setupWithViewPager(binding.viewPager);
|
||||||
@ -645,8 +651,6 @@ public class ChannelFragment extends BaseStateFragment<ChannelInfo>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.errorContentNotSupported.setVisibility(View.VISIBLE);
|
binding.emptyStateView.setVisibility(View.VISIBLE);
|
||||||
binding.channelKaomoji.setText("(︶︹︺)");
|
|
||||||
binding.channelKaomoji.setTextSize(TypedValue.COMPLEX_UNIT_SP, 45f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
|
|||||||
import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder;
|
import org.schabi.newpipe.fragments.list.playlist.PlaylistControlViewHolder;
|
||||||
import org.schabi.newpipe.player.playqueue.ChannelTabPlayQueue;
|
import org.schabi.newpipe.player.playqueue.ChannelTabPlayQueue;
|
||||||
import org.schabi.newpipe.player.playqueue.PlayQueue;
|
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.ChannelTabHelper;
|
||||||
import org.schabi.newpipe.util.ExtractorHelper;
|
import org.schabi.newpipe.util.ExtractorHelper;
|
||||||
import org.schabi.newpipe.util.PlayButtonHelper;
|
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);
|
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
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
|
@ -64,6 +64,8 @@ import org.schabi.newpipe.ktx.AnimationType;
|
|||||||
import org.schabi.newpipe.ktx.ExceptionUtils;
|
import org.schabi.newpipe.ktx.ExceptionUtils;
|
||||||
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
import org.schabi.newpipe.local.history.HistoryRecordManager;
|
||||||
import org.schabi.newpipe.settings.NewPipeSettings;
|
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.Constants;
|
||||||
import org.schabi.newpipe.util.DeviceUtils;
|
import org.schabi.newpipe.util.DeviceUtils;
|
||||||
import org.schabi.newpipe.util.ExtractorHelper;
|
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) {
|
protected void initViews(final View rootView, final Bundle savedInstanceState) {
|
||||||
super.initViews(rootView, savedInstanceState);
|
super.initViews(rootView, savedInstanceState);
|
||||||
|
|
||||||
|
EmptyStateUtil.setEmptyStateComposable(
|
||||||
|
searchBinding.emptyStateView,
|
||||||
|
EmptyStateSpec.Companion.getNoSearchResult());
|
||||||
|
|
||||||
searchBinding.suggestionsList.setAdapter(suggestionListAdapter);
|
searchBinding.suggestionsList.setAdapter(suggestionListAdapter);
|
||||||
// animations are just strange and useless, since the suggestions keep changing too much
|
// animations are just strange and useless, since the suggestions keep changing too much
|
||||||
searchBinding.suggestionsList.setItemAnimator(null);
|
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.holder.RemoteBookmarkPlaylistItemHolder;
|
||||||
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
|
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
|
||||||
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
|
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.NavigationHelper;
|
||||||
import org.schabi.newpipe.util.OnClickGesture;
|
import org.schabi.newpipe.util.OnClickGesture;
|
||||||
import org.schabi.newpipe.util.debounce.DebounceSavable;
|
import org.schabi.newpipe.util.debounce.DebounceSavable;
|
||||||
@ -123,6 +125,10 @@ public final class BookmarkFragment extends BaseLocalListFragment<List<PlaylistL
|
|||||||
super.initViews(rootView, savedInstanceState);
|
super.initViews(rootView, savedInstanceState);
|
||||||
|
|
||||||
itemListAdapter.setUseItemHandle(true);
|
itemListAdapter.setUseItemHandle(true);
|
||||||
|
EmptyStateUtil.setEmptyStateComposable(
|
||||||
|
rootView.findViewById(R.id.empty_state_view),
|
||||||
|
EmptyStateSpec.Companion.getNoBookmarkedPlaylist()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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.item.StreamItem
|
||||||
import org.schabi.newpipe.local.feed.service.FeedLoadService
|
import org.schabi.newpipe.local.feed.service.FeedLoadService
|
||||||
import org.schabi.newpipe.local.subscription.SubscriptionManager
|
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.DeviceUtils
|
||||||
import org.schabi.newpipe.util.Localization
|
import org.schabi.newpipe.util.Localization
|
||||||
import org.schabi.newpipe.util.NavigationHelper
|
import org.schabi.newpipe.util.NavigationHelper
|
||||||
@ -132,6 +133,7 @@ class FeedFragment : BaseStateFragment<FeedState>() {
|
|||||||
override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) {
|
||||||
// super.onViewCreated() calls initListeners() which require the binding to be initialized
|
// super.onViewCreated() calls initListeners() which require the binding to be initialized
|
||||||
_feedBinding = FragmentFeedBinding.bind(rootView)
|
_feedBinding = FragmentFeedBinding.bind(rootView)
|
||||||
|
feedBinding.emptyStateView.setEmptyStateComposable()
|
||||||
super.onViewCreated(rootView, savedInstanceState)
|
super.onViewCreated(rootView, savedInstanceState)
|
||||||
|
|
||||||
val factory = FeedViewModel.getFactory(requireContext(), groupId)
|
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.local.subscription.services.SubscriptionsImportService.PREVIOUS_EXPORT_MODE
|
||||||
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
|
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
|
||||||
import org.schabi.newpipe.streams.io.StoredFileHelper
|
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.NavigationHelper
|
||||||
import org.schabi.newpipe.util.OnClickGesture
|
import org.schabi.newpipe.util.OnClickGesture
|
||||||
import org.schabi.newpipe.util.ServiceHelper
|
import org.schabi.newpipe.util.ServiceHelper
|
||||||
@ -257,6 +258,8 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
|||||||
binding.itemsList.adapter = groupAdapter
|
binding.itemsList.adapter = groupAdapter
|
||||||
binding.itemsList.itemAnimator = null
|
binding.itemsList.itemAnimator = null
|
||||||
|
|
||||||
|
binding.emptyStateView.setEmptyStateComposable()
|
||||||
|
|
||||||
viewModel = ViewModelProvider(this)[SubscriptionViewModel::class.java]
|
viewModel = ViewModelProvider(this)[SubscriptionViewModel::class.java]
|
||||||
viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(this::handleResult) }
|
viewModel.stateLiveData.observe(viewLifecycleOwner) { it?.let(this::handleResult) }
|
||||||
viewModel.feedGroupsLiveData.observe(viewLifecycleOwner) {
|
viewModel.feedGroupsLiveData.observe(viewLifecycleOwner) {
|
||||||
|
@ -3,14 +3,18 @@ package org.schabi.newpipe.local.subscription.item
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import com.xwray.groupie.viewbinding.BindableItem
|
import com.xwray.groupie.viewbinding.BindableItem
|
||||||
import org.schabi.newpipe.R
|
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
|
* 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 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 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.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.compose.ui.platform.ComposeView;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
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.database.subscription.SubscriptionEntity;
|
||||||
import org.schabi.newpipe.error.ErrorUtil;
|
import org.schabi.newpipe.error.ErrorUtil;
|
||||||
import org.schabi.newpipe.local.subscription.SubscriptionManager;
|
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.ThemeHelper;
|
||||||
import org.schabi.newpipe.util.image.CoilHelper;
|
import org.schabi.newpipe.util.image.CoilHelper;
|
||||||
|
|
||||||
@ -57,7 +60,7 @@ public class SelectChannelFragment extends DialogFragment {
|
|||||||
private OnCancelListener onCancelListener = null;
|
private OnCancelListener onCancelListener = null;
|
||||||
|
|
||||||
private ProgressBar progressBar;
|
private ProgressBar progressBar;
|
||||||
private TextView emptyView;
|
private ComposeView emptyView;
|
||||||
private RecyclerView recyclerView;
|
private RecyclerView recyclerView;
|
||||||
|
|
||||||
private List<SubscriptionEntity> subscriptions = new Vector<>();
|
private List<SubscriptionEntity> subscriptions = new Vector<>();
|
||||||
@ -91,6 +94,9 @@ public class SelectChannelFragment extends DialogFragment {
|
|||||||
|
|
||||||
progressBar = v.findViewById(R.id.progressBar);
|
progressBar = v.findViewById(R.id.progressBar);
|
||||||
emptyView = v.findViewById(R.id.empty_state_view);
|
emptyView = v.findViewById(R.id.empty_state_view);
|
||||||
|
|
||||||
|
EmptyStateUtil.setEmptyStateComposable(emptyView,
|
||||||
|
EmptyStateSpec.Companion.getNoSubscriptions());
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
recyclerView.setVisibility(View.GONE);
|
recyclerView.setVisibility(View.GONE);
|
||||||
emptyView.setVisibility(View.GONE);
|
emptyView.setVisibility(View.GONE);
|
||||||
|
@ -11,6 +11,7 @@ import android.widget.ProgressBar;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.compose.ui.platform.ComposeView;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
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.error.UserAction;
|
||||||
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
|
import org.schabi.newpipe.local.playlist.LocalPlaylistManager;
|
||||||
import org.schabi.newpipe.local.playlist.RemotePlaylistManager;
|
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 org.schabi.newpipe.util.image.CoilHelper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -40,7 +43,7 @@ public class SelectPlaylistFragment extends DialogFragment {
|
|||||||
private OnSelectedListener onSelectedListener = null;
|
private OnSelectedListener onSelectedListener = null;
|
||||||
|
|
||||||
private ProgressBar progressBar;
|
private ProgressBar progressBar;
|
||||||
private TextView emptyView;
|
private ComposeView emptyView;
|
||||||
private RecyclerView recyclerView;
|
private RecyclerView recyclerView;
|
||||||
private Disposable disposable = null;
|
private Disposable disposable = null;
|
||||||
|
|
||||||
@ -62,6 +65,8 @@ public class SelectPlaylistFragment extends DialogFragment {
|
|||||||
recyclerView = v.findViewById(R.id.items_list);
|
recyclerView = v.findViewById(R.id.items_list);
|
||||||
emptyView = v.findViewById(R.id.empty_state_view);
|
emptyView = v.findViewById(R.id.empty_state_view);
|
||||||
|
|
||||||
|
EmptyStateUtil.setEmptyStateComposable(emptyView,
|
||||||
|
EmptyStateSpec.Companion.getNoBookmarkedPlaylist());
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
final SelectPlaylistAdapter playlistAdapter = new SelectPlaylistAdapter();
|
final SelectPlaylistAdapter playlistAdapter = new SelectPlaylistAdapter();
|
||||||
recyclerView.setAdapter(playlistAdapter);
|
recyclerView.setAdapter(playlistAdapter);
|
||||||
|
@ -11,6 +11,8 @@ import androidx.fragment.app.Fragment;
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
import org.schabi.newpipe.databinding.SettingsPreferencesearchFragmentBinding;
|
import org.schabi.newpipe.databinding.SettingsPreferencesearchFragmentBinding;
|
||||||
|
import org.schabi.newpipe.ui.emptystate.EmptyStateSpec;
|
||||||
|
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -39,6 +41,9 @@ public class PreferenceSearchFragment extends Fragment {
|
|||||||
binding = SettingsPreferencesearchFragmentBinding.inflate(inflater, container, false);
|
binding = SettingsPreferencesearchFragmentBinding.inflate(inflater, container, false);
|
||||||
|
|
||||||
binding.searchResults.setLayoutManager(new LinearLayoutManager(getContext()));
|
binding.searchResults.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
EmptyStateUtil.setEmptyStateComposable(
|
||||||
|
binding.emptyStateView,
|
||||||
|
EmptyStateSpec.Companion.getNoSearchMaxSizeResult());
|
||||||
|
|
||||||
adapter = new PreferenceSearchAdapter();
|
adapter = new PreferenceSearchAdapter();
|
||||||
adapter.setOnItemClickListener(this::onItemClicked);
|
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.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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.activity.result.contract.ActivityResultContracts.StartActivityForResult;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.compose.ui.platform.ComposeView;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
@ -34,6 +35,7 @@ import org.schabi.newpipe.R;
|
|||||||
import org.schabi.newpipe.settings.NewPipeSettings;
|
import org.schabi.newpipe.settings.NewPipeSettings;
|
||||||
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
|
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
|
||||||
import org.schabi.newpipe.streams.io.StoredFileHelper;
|
import org.schabi.newpipe.streams.io.StoredFileHelper;
|
||||||
|
import org.schabi.newpipe.ui.emptystate.EmptyStateUtil;
|
||||||
import org.schabi.newpipe.util.FilePickerActivityHelper;
|
import org.schabi.newpipe.util.FilePickerActivityHelper;
|
||||||
|
|
||||||
import java.io.File;
|
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);
|
mContext.bindService(new Intent(mContext, DownloadManagerService.class), mConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
|
||||||
// Views
|
// 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);
|
mList = v.findViewById(R.id.mission_recycler);
|
||||||
|
|
||||||
// Init layouts managers
|
// Init layouts managers
|
||||||
|
@ -24,15 +24,15 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<include
|
<androidx.compose.ui.platform.ComposeView
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
layout="@layout/list_empty_view"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:layout_marginTop="50dp"
|
android:layout_marginTop="50dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible"
|
||||||
|
/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -168,37 +168,14 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.compose.ui.platform.ComposeView
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingTop="90dp"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible">
|
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>
|
|
||||||
|
|
||||||
<!--ERROR PANEL-->
|
<!--ERROR PANEL-->
|
||||||
<include
|
<include
|
||||||
|
@ -20,15 +20,15 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<include
|
<androidx.compose.ui.platform.ComposeView
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
layout="@layout/list_empty_view"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible"
|
||||||
|
/>
|
||||||
|
|
||||||
<!--ERROR PANEL-->
|
<!--ERROR PANEL-->
|
||||||
<include
|
<include
|
||||||
|
@ -20,36 +20,14 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.compose.ui.platform.ComposeView
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingTop="90dp"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible">
|
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>
|
|
||||||
|
|
||||||
<!--ERROR PANEL-->
|
<!--ERROR PANEL-->
|
||||||
<include
|
<include
|
||||||
|
@ -7,12 +7,13 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<include
|
<androidx.compose.ui.platform.ComposeView
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
layout="@layout/list_empty_view"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:layout_marginTop="90dp" />
|
android:layout_marginTop="90dp"
|
||||||
|
/>
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -140,15 +140,15 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<include
|
<androidx.compose.ui.platform.ComposeView
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
layout="@layout/list_empty_view"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:layout_marginTop="50dp"
|
android:layout_marginTop="50dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible"
|
||||||
|
/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -52,33 +52,14 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.compose.ui.platform.ComposeView
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:orientation="vertical"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible">
|
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>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/suggestions_panel"
|
android:id="@+id/suggestions_panel"
|
||||||
|
@ -24,16 +24,16 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<include
|
<androidx.compose.ui.platform.ComposeView
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
layout="@layout/list_empty_view"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/items_list"
|
android:layout_below="@id/items_list"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:layout_marginTop="50dp"
|
android:layout_marginTop="50dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible"
|
||||||
|
/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
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"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.compose.ui.platform.ComposeView
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
|
||||||
android:minHeight="128dp"
|
android:minHeight="128dp"
|
||||||
android:orientation="vertical">
|
xmlns:android="http://schemas.android.com/apk/res/android" />
|
||||||
|
|
||||||
<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>
|
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include
|
<androidx.compose.ui.platform.ComposeView
|
||||||
android:id="@+id/list_empty_view"
|
android:id="@+id/empty_state_view"
|
||||||
layout="@layout/list_empty_view"
|
android:layout_width="match_parent"
|
||||||
android:visibility="gone" />
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="128dp" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/mission_recycler"
|
android:id="@+id/mission_recycler"
|
||||||
|
@ -24,14 +24,11 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
tools:listitem="@layout/select_channel_item" />
|
tools:listitem="@layout/select_channel_item" />
|
||||||
|
|
||||||
|
<androidx.compose.ui.platform.ComposeView
|
||||||
<org.schabi.newpipe.views.NewPipeTextView
|
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp" />
|
||||||
android:text="@string/no_channel_subscribed_yet"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceListItem" />
|
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
|
@ -26,14 +26,11 @@
|
|||||||
|
|
||||||
</androidx.recyclerview.widget.RecyclerView>
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
|
||||||
|
<androidx.compose.ui.platform.ComposeView
|
||||||
<org.schabi.newpipe.views.NewPipeTextView
|
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="10dp"
|
android:layout_margin="10dp" />
|
||||||
android:text="@string/no_playlist_bookmarked_yet"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceListItem" />
|
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
|
@ -12,33 +12,14 @@
|
|||||||
android:layout_height="4dp"
|
android:layout_height="4dp"
|
||||||
android:background="?attr/toolbar_shadow" />
|
android:background="?attr/toolbar_shadow" />
|
||||||
|
|
||||||
<LinearLayout
|
<androidx.compose.ui.platform.ComposeView
|
||||||
android:id="@+id/empty_state_view"
|
android:id="@+id/empty_state_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="vertical"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools: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>
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/searchResults"
|
android:id="@+id/searchResults"
|
||||||
|
Loading…
Reference in New Issue
Block a user