merged upstream/dev

This commit is contained in:
yausername 2019-11-22 22:41:59 +05:30
commit 81658de08f
12 changed files with 202 additions and 144 deletions

View File

@ -107,6 +107,7 @@ public abstract class BaseFragment extends Fragment {
if (DEBUG) Log.d(TAG, "setTitle() called with: title = [" + title + "]"); if (DEBUG) Log.d(TAG, "setTitle() called with: title = [" + title + "]");
if((!useAsFrontPage || mIsVisibleToUser) if((!useAsFrontPage || mIsVisibleToUser)
&& (activity != null && activity.getSupportActionBar() != null)) { && (activity != null && activity.getSupportActionBar() != null)) {
activity.getSupportActionBar().setDisplayShowTitleEnabled(true);
activity.getSupportActionBar().setTitle(title); activity.getSupportActionBar().setTitle(title);
} }
} }

View File

@ -1,5 +1,6 @@
package org.schabi.newpipe.fragments; package org.schabi.newpipe.fragments;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -15,7 +16,7 @@ import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter; import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
@ -52,32 +53,19 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setHasOptionsMenu(true); setHasOptionsMenu(true);
destroyOldFragments();
tabsManager = TabsManager.getManager(activity); tabsManager = TabsManager.getManager(activity);
tabsManager.setSavedTabsListener(() -> { tabsManager.setSavedTabsListener(() -> {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "TabsManager.SavedTabsChangeListener: onTabsChanged called, isResumed = " + isResumed()); Log.d(TAG, "TabsManager.SavedTabsChangeListener: onTabsChanged called, isResumed = " + isResumed());
} }
if (isResumed()) { if (isResumed()) {
updateTabs(); setupTabs();
} else { } else {
hasTabsChanged = true; hasTabsChanged = true;
} }
}); });
} }
private void destroyOldFragments() {
for (Fragment fragment : getChildFragmentManager().getFragments()) {
if (fragment != null) {
getChildFragmentManager()
.beginTransaction()
.remove(fragment)
.commitNowAllowingStateLoss();
}
}
}
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false); return inflater.inflate(R.layout.fragment_main, container, false);
@ -90,23 +78,17 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
tabLayout = rootView.findViewById(R.id.main_tab_layout); tabLayout = rootView.findViewById(R.id.main_tab_layout);
viewPager = rootView.findViewById(R.id.pager); viewPager = rootView.findViewById(R.id.pager);
/* Nested fragment, use child fragment here to maintain backstack in view pager. */
pagerAdapter = new SelectedTabsPagerAdapter(getChildFragmentManager());
viewPager.setAdapter(pagerAdapter);
tabLayout.setupWithViewPager(viewPager); tabLayout.setupWithViewPager(viewPager);
tabLayout.addOnTabSelectedListener(this); tabLayout.addOnTabSelectedListener(this);
updateTabs();
setupTabs();
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (hasTabsChanged) { if (hasTabsChanged) setupTabs();
hasTabsChanged = false;
updateTabs();
}
} }
@Override @Override
@ -153,45 +135,42 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
// Tabs // Tabs
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
public void updateTabs() { public void setupTabs() {
tabsList.clear(); tabsList.clear();
tabsList.addAll(tabsManager.getTabs()); tabsList.addAll(tabsManager.getTabs());
pagerAdapter.notifyDataSetChanged();
viewPager.setOffscreenPageLimit(pagerAdapter.getCount()); if (pagerAdapter == null || !pagerAdapter.sameTabs(tabsList)) {
updateTabsIcon(); pagerAdapter = new SelectedTabsPagerAdapter(requireContext(), getChildFragmentManager(), tabsList);
updateTabsContentDescription(); }
updateCurrentTitle(); // Clear previous tabs/fragments and set new adapter
viewPager.setAdapter(pagerAdapter);
viewPager.setOffscreenPageLimit(tabsList.size());
updateTabsIconAndDescription();
updateTitleForTab(viewPager.getCurrentItem());
hasTabsChanged = false;
} }
private void updateTabsIcon() { private void updateTabsIconAndDescription() {
for (int i = 0; i < tabsList.size(); i++) { for (int i = 0; i < tabsList.size(); i++) {
final TabLayout.Tab tabToSet = tabLayout.getTabAt(i); final TabLayout.Tab tabToSet = tabLayout.getTabAt(i);
if (tabToSet != null) { if (tabToSet != null) {
tabToSet.setIcon(tabsList.get(i).getTabIconRes(activity)); final Tab tab = tabsList.get(i);
tabToSet.setIcon(tab.getTabIconRes(requireContext()));
tabToSet.setContentDescription(tab.getTabName(requireContext()));
} }
} }
} }
private void updateTabsContentDescription() { private void updateTitleForTab(int tabPosition) {
for (int i = 0; i < tabsList.size(); i++) { setTitle(tabsList.get(tabPosition).getTabName(requireContext()));
final TabLayout.Tab tabToSet = tabLayout.getTabAt(i);
if (tabToSet != null) {
final Tab t = tabsList.get(i);
tabToSet.setIcon(t.getTabIconRes(activity));
tabToSet.setContentDescription(t.getTabName(activity));
}
}
}
private void updateCurrentTitle() {
setTitle(tabsList.get(viewPager.getCurrentItem()).getTabName(requireContext()));
} }
@Override @Override
public void onTabSelected(TabLayout.Tab selectedTab) { public void onTabSelected(TabLayout.Tab selectedTab) {
if (DEBUG) Log.d(TAG, "onTabSelected() called with: selectedTab = [" + selectedTab + "]"); if (DEBUG) Log.d(TAG, "onTabSelected() called with: selectedTab = [" + selectedTab + "]");
updateCurrentTitle(); updateTitleForTab(selectedTab.getPosition());
} }
@Override @Override
@ -201,29 +180,33 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
@Override @Override
public void onTabReselected(TabLayout.Tab tab) { public void onTabReselected(TabLayout.Tab tab) {
if (DEBUG) Log.d(TAG, "onTabReselected() called with: tab = [" + tab + "]"); if (DEBUG) Log.d(TAG, "onTabReselected() called with: tab = [" + tab + "]");
updateCurrentTitle(); updateTitleForTab(tab.getPosition());
} }
private class SelectedTabsPagerAdapter extends FragmentPagerAdapter { private static class SelectedTabsPagerAdapter extends FragmentStatePagerAdapter {
private final Context context;
private final List<Tab> internalTabsList;
private SelectedTabsPagerAdapter(FragmentManager fragmentManager) { private SelectedTabsPagerAdapter(Context context, FragmentManager fragmentManager, List<Tab> tabsList) {
super(fragmentManager); super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
this.context = context;
this.internalTabsList = new ArrayList<>(tabsList);
} }
@Override @Override
public Fragment getItem(int position) { public Fragment getItem(int position) {
final Tab tab = tabsList.get(position); final Tab tab = internalTabsList.get(position);
Throwable throwable = null; Throwable throwable = null;
Fragment fragment = null; Fragment fragment = null;
try { try {
fragment = tab.getFragment(); fragment = tab.getFragment(context);
} catch (ExtractionException e) { } catch (ExtractionException e) {
throwable = e; throwable = e;
} }
if (throwable != null) { if (throwable != null) {
ErrorActivity.reportError(activity, throwable, activity.getClass(), null, ErrorActivity.reportError(context, throwable, null, null,
ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR, "none", "", R.string.app_ui_crash)); ErrorActivity.ErrorInfo.make(UserAction.UI_ERROR, "none", "", R.string.app_ui_crash));
return new BlankFragment(); return new BlankFragment();
} }
@ -244,15 +227,11 @@ public class MainFragment extends BaseFragment implements TabLayout.OnTabSelecte
@Override @Override
public int getCount() { public int getCount() {
return tabsList.size(); return internalTabsList.size();
} }
@Override public boolean sameTabs(List<Tab> tabsToCompare) {
public void destroyItem(ViewGroup container, int position, Object object) { return internalTabsList.equals(tabsToCompare);
getChildFragmentManager()
.beginTransaction()
.remove((Fragment) object)
.commitNowAllowingStateLoss();
} }
} }
} }

View File

@ -111,6 +111,8 @@ public abstract class BaseListInfoFragment<I extends ListInfo>
super.startLoading(forceLoad); super.startLoading(forceLoad);
showListFooter(false); showListFooter(false);
infoListAdapter.clearStreamItemList();
currentInfo = null; currentInfo = null;
if (currentWorker != null) currentWorker.dispose(); if (currentWorker != null) currentWorker.dispose();
currentWorker = loadResult(forceLoad) currentWorker = loadResult(forceLoad)

View File

@ -0,0 +1,51 @@
package org.schabi.newpipe.fragments.list.kiosk;
import android.os.Bundle;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.kiosk.KioskList;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.KioskTranslator;
import org.schabi.newpipe.util.ServiceHelper;
public class DefaultKioskFragment extends KioskFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (serviceId < 0) {
updateSelectedDefaultKiosk();
}
}
@Override
public void onResume() {
super.onResume();
if (serviceId != ServiceHelper.getSelectedServiceId(requireContext())) {
if (currentWorker != null) currentWorker.dispose();
updateSelectedDefaultKiosk();
reloadContent();
}
}
private void updateSelectedDefaultKiosk() {
try {
serviceId = ServiceHelper.getSelectedServiceId(requireContext());
final KioskList kioskList = NewPipe.getService(serviceId).getKioskList();
kioskId = kioskList.getDefaultKioskId();
url = kioskList.getListLinkHandlerFactoryByType(kioskId).fromId(kioskId).getUrl();
kioskTranslatedName = KioskTranslator.getTranslatedKioskName(kioskId, requireContext());
name = kioskTranslatedName;
currentInfo = null;
currentNextPageUrl = null;
} catch (ExtractionException e) {
onUnrecoverableError(e, UserAction.REQUESTED_KIOSK, "none", "Loading default kiosk from selected service", 0);
}
}
}

View File

@ -4,6 +4,8 @@ import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import android.preference.PreferenceManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -17,10 +19,12 @@ import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.kiosk.KioskInfo; import org.schabi.newpipe.extractor.kiosk.KioskInfo;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
import org.schabi.newpipe.extractor.localization.ContentCountry;
import org.schabi.newpipe.fragments.list.BaseListInfoFragment; import org.schabi.newpipe.fragments.list.BaseListInfoFragment;
import org.schabi.newpipe.report.UserAction; import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.ExtractorHelper; import org.schabi.newpipe.util.ExtractorHelper;
import org.schabi.newpipe.util.KioskTranslator; import org.schabi.newpipe.util.KioskTranslator;
import org.schabi.newpipe.util.Localization;
import icepick.State; import icepick.State;
import io.reactivex.Single; import io.reactivex.Single;
@ -52,6 +56,8 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
@State @State
protected String kioskId = ""; protected String kioskId = "";
protected String kioskTranslatedName; protected String kioskTranslatedName;
@State
protected ContentCountry contentCountry;
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
@ -87,6 +93,7 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
kioskTranslatedName = KioskTranslator.getTranslatedKioskName(kioskId, activity); kioskTranslatedName = KioskTranslator.getTranslatedKioskName(kioskId, activity);
name = kioskTranslatedName; name = kioskTranslatedName;
contentCountry = Localization.getPreferredContentCountry(requireContext());
} }
@Override @Override
@ -108,6 +115,15 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
return inflater.inflate(R.layout.fragment_kiosk, container, false); return inflater.inflate(R.layout.fragment_kiosk, container, false);
} }
@Override
public void onResume() {
super.onResume();
if (!Localization.getPreferredContentCountry(requireContext()).equals(contentCountry)) {
reloadContent();
}
}
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Menu // Menu
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
@ -127,6 +143,7 @@ public class KioskFragment extends BaseListInfoFragment<KioskInfo> {
@Override @Override
public Single<KioskInfo> loadResult(boolean forceReload) { public Single<KioskInfo> loadResult(boolean forceReload) {
contentCountry = Localization.getPreferredContentCountry(requireContext());
return ExtractorHelper.getKioskInfo(serviceId, return ExtractorHelper.getKioskInfo(serviceId,
url, url,
forceReload); forceReload);

View File

@ -20,6 +20,7 @@ import com.nostra13.universalimageloader.core.ImageLoader;
import org.schabi.newpipe.App; import org.schabi.newpipe.App;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.ServiceList; import org.schabi.newpipe.extractor.ServiceList;
import org.schabi.newpipe.extractor.localization.ContentCountry; import org.schabi.newpipe.extractor.localization.ContentCountry;
import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.Localization;
@ -182,6 +183,8 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
if (!selectedLocalization.equals(initialSelectedLocalization) if (!selectedLocalization.equals(initialSelectedLocalization)
|| !selectedContentCountry.equals(initialSelectedContentCountry)) { || !selectedContentCountry.equals(initialSelectedContentCountry)) {
Toast.makeText(requireContext(), R.string.localization_changes_requires_app_restart, Toast.LENGTH_LONG).show(); Toast.makeText(requireContext(), R.string.localization_changes_requires_app_restart, Toast.LENGTH_LONG).show();
NewPipe.setupLocalization(selectedLocalization, selectedContentCountry);
} }
} }

View File

@ -231,7 +231,7 @@ public class ChooseTabsFragment extends Fragment {
break; break;
case DEFAULT_KIOSK: case DEFAULT_KIOSK:
if (!tabList.contains(tab)) { if (!tabList.contains(tab)) {
returnList.add(new ChooseTabListItem(tab.getTabId(), getString(R.string.default_kiosk_page_sumatry), returnList.add(new ChooseTabListItem(tab.getTabId(), getString(R.string.default_kiosk_page_summary),
ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_hot))); ThemeHelper.resolveResourceIdFromAttr(context, R.attr.ic_hot)));
} }
break; break;
@ -305,23 +305,25 @@ public class ChooseTabsFragment extends Fragment {
return; return;
} }
String tabName = tab.getTabName(requireContext()); final String tabName;
switch (type) { switch (type) {
case BLANK: case BLANK:
tabName = requireContext().getString(R.string.blank_page_summary); tabName = getString(R.string.blank_page_summary);
break;
case KIOSK:
tabName = NewPipe.getNameOfService(((Tab.KioskTab) tab).getKioskServiceId()) + "/" + tabName;
break;
case CHANNEL:
tabName = NewPipe.getNameOfService(((Tab.ChannelTab) tab).getChannelServiceId()) + "/" + tabName;
break; break;
case DEFAULT_KIOSK: case DEFAULT_KIOSK:
tabName = requireContext().getString(R.string.default_kiosk_page_sumatry); tabName = getString(R.string.default_kiosk_page_summary);
break;
case KIOSK:
tabName = NewPipe.getNameOfService(((Tab.KioskTab) tab).getKioskServiceId()) + "/" + tab.getTabName(requireContext());
break;
case CHANNEL:
tabName = NewPipe.getNameOfService(((Tab.ChannelTab) tab).getChannelServiceId()) + "/" + tab.getTabName(requireContext());
break;
default:
tabName = tab.getTabName(requireContext());
break; break;
} }
tabNameView.setText(tabName); tabNameView.setText(tabName);
tabIconView.setImageResource(tab.getTabIconRes(requireContext())); tabIconView.setImageResource(tab.getTabIconRes(requireContext()));
} }

View File

@ -1,6 +1,7 @@
package org.schabi.newpipe.settings.tabs; package org.schabi.newpipe.settings.tabs;
import android.content.Context; import android.content.Context;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -9,22 +10,26 @@ import androidx.fragment.app.Fragment;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonSink; import com.grack.nanojson.JsonSink;
import org.jsoup.helper.StringUtil;
import org.schabi.newpipe.App;
import org.schabi.newpipe.R; import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.fragments.BlankFragment; import org.schabi.newpipe.fragments.BlankFragment;
import org.schabi.newpipe.fragments.list.channel.ChannelFragment; import org.schabi.newpipe.fragments.list.channel.ChannelFragment;
import org.schabi.newpipe.fragments.list.kiosk.DefaultKioskFragment;
import org.schabi.newpipe.fragments.list.kiosk.KioskFragment; import org.schabi.newpipe.fragments.list.kiosk.KioskFragment;
import org.schabi.newpipe.local.bookmark.BookmarkFragment; import org.schabi.newpipe.local.bookmark.BookmarkFragment;
import org.schabi.newpipe.local.feed.FeedFragment; import org.schabi.newpipe.local.feed.FeedFragment;
import org.schabi.newpipe.local.history.StatisticsPlaylistFragment; import org.schabi.newpipe.local.history.StatisticsPlaylistFragment;
import org.schabi.newpipe.local.subscription.SubscriptionFragment; import org.schabi.newpipe.local.subscription.SubscriptionFragment;
import org.schabi.newpipe.report.ErrorActivity;
import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.KioskTranslator; import org.schabi.newpipe.util.KioskTranslator;
import org.schabi.newpipe.util.ServiceHelper; import org.schabi.newpipe.util.ServiceHelper;
import org.schabi.newpipe.util.ThemeHelper; import org.schabi.newpipe.util.ThemeHelper;
import java.util.Objects;
public abstract class Tab { public abstract class Tab {
Tab() { Tab() {
} }
@ -40,10 +45,12 @@ public abstract class Tab {
/** /**
* Return a instance of the fragment that this tab represent. * Return a instance of the fragment that this tab represent.
*/ */
public abstract Fragment getFragment() throws ExtractionException; public abstract Fragment getFragment(Context context) throws ExtractionException;
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (obj == this) return true;
return obj instanceof Tab && obj.getClass().equals(this.getClass()) return obj instanceof Tab && obj.getClass().equals(this.getClass())
&& ((Tab) obj).getTabId() == this.getTabId(); && ((Tab) obj).getTabId() == this.getTabId();
} }
@ -115,12 +122,6 @@ public abstract class Tab {
return new KioskTab(jsonObject); return new KioskTab(jsonObject);
case CHANNEL: case CHANNEL:
return new ChannelTab(jsonObject); return new ChannelTab(jsonObject);
case DEFAULT_KIOSK:
DefaultKioskTab tab = new DefaultKioskTab();
if(!StringUtil.isBlank(tab.getKioskId())){
return tab;
}
return null;
} }
} }
@ -133,13 +134,13 @@ public abstract class Tab {
public enum Type { public enum Type {
BLANK(new BlankTab()), BLANK(new BlankTab()),
DEFAULT_KIOSK(new DefaultKioskTab()),
SUBSCRIPTIONS(new SubscriptionsTab()), SUBSCRIPTIONS(new SubscriptionsTab()),
FEED(new FeedTab()), FEED(new FeedTab()),
BOOKMARKS(new BookmarksTab()), BOOKMARKS(new BookmarksTab()),
HISTORY(new HistoryTab()), HISTORY(new HistoryTab()),
KIOSK(new KioskTab()), KIOSK(new KioskTab()),
CHANNEL(new ChannelTab()), CHANNEL(new ChannelTab());
DEFAULT_KIOSK(new DefaultKioskTab());
private Tab tab; private Tab tab;
@ -176,7 +177,7 @@ public abstract class Tab {
} }
@Override @Override
public BlankFragment getFragment() { public BlankFragment getFragment(Context context) {
return new BlankFragment(); return new BlankFragment();
} }
} }
@ -201,7 +202,7 @@ public abstract class Tab {
} }
@Override @Override
public SubscriptionFragment getFragment() { public SubscriptionFragment getFragment(Context context) {
return new SubscriptionFragment(); return new SubscriptionFragment();
} }
@ -227,7 +228,7 @@ public abstract class Tab {
} }
@Override @Override
public FeedFragment getFragment() { public FeedFragment getFragment(Context context) {
return new FeedFragment(); return new FeedFragment();
} }
} }
@ -252,7 +253,7 @@ public abstract class Tab {
} }
@Override @Override
public BookmarkFragment getFragment() { public BookmarkFragment getFragment(Context context) {
return new BookmarkFragment(); return new BookmarkFragment();
} }
} }
@ -277,7 +278,7 @@ public abstract class Tab {
} }
@Override @Override
public StatisticsPlaylistFragment getFragment() { public StatisticsPlaylistFragment getFragment(Context context) {
return new StatisticsPlaylistFragment(); return new StatisticsPlaylistFragment();
} }
} }
@ -327,7 +328,7 @@ public abstract class Tab {
} }
@Override @Override
public KioskFragment getFragment() throws ExtractionException { public KioskFragment getFragment(Context context) throws ExtractionException {
return KioskFragment.getInstance(kioskServiceId, kioskId); return KioskFragment.getInstance(kioskServiceId, kioskId);
} }
@ -343,6 +344,13 @@ public abstract class Tab {
kioskId = jsonObject.getString(JSON_KIOSK_ID_KEY, "<no-id>"); kioskId = jsonObject.getString(JSON_KIOSK_ID_KEY, "<no-id>");
} }
@Override
public boolean equals(Object obj) {
return super.equals(obj) &&
kioskServiceId == ((KioskTab) obj).kioskServiceId
&& Objects.equals(kioskId, ((KioskTab) obj).kioskId);
}
public int getKioskServiceId() { public int getKioskServiceId() {
return kioskServiceId; return kioskServiceId;
} }
@ -394,7 +402,7 @@ public abstract class Tab {
} }
@Override @Override
public ChannelFragment getFragment() { public ChannelFragment getFragment(Context context) {
return ChannelFragment.getInstance(channelServiceId, channelUrl, channelName); return ChannelFragment.getInstance(channelServiceId, channelUrl, channelName);
} }
@ -412,6 +420,14 @@ public abstract class Tab {
channelName = jsonObject.getString(JSON_CHANNEL_NAME_KEY, "<no-name>"); channelName = jsonObject.getString(JSON_CHANNEL_NAME_KEY, "<no-name>");
} }
@Override
public boolean equals(Object obj) {
return super.equals(obj) &&
channelServiceId == ((ChannelTab) obj).channelServiceId
&& Objects.equals(channelUrl, ((ChannelTab) obj).channelUrl)
&& Objects.equals(channelName, ((ChannelTab) obj).channelName);
}
public int getChannelServiceId() { public int getChannelServiceId() {
return channelServiceId; return channelServiceId;
} }
@ -428,22 +444,6 @@ public abstract class Tab {
public static class DefaultKioskTab extends Tab { public static class DefaultKioskTab extends Tab {
public static final int ID = 7; public static final int ID = 7;
private int kioskServiceId;
private String kioskId;
protected DefaultKioskTab() {
initKiosk();
}
public void initKiosk() {
this.kioskServiceId = ServiceHelper.getSelectedServiceId(App.getApp());
try {
this.kioskId = NewPipe.getService(this.kioskServiceId).getKioskList().getDefaultKioskId();
} catch (ExtractionException e) {
this.kioskId = "";
}
}
@Override @Override
public int getTabId() { public int getTabId() {
return ID; return ID;
@ -451,27 +451,31 @@ public abstract class Tab {
@Override @Override
public String getTabName(Context context) { public String getTabName(Context context) {
return KioskTranslator.getTranslatedKioskName(kioskId, context); return KioskTranslator.getTranslatedKioskName(getDefaultKioskId(context), context);
} }
@DrawableRes @DrawableRes
@Override @Override
public int getTabIconRes(Context context) { public int getTabIconRes(Context context) {
final int kioskIcon = KioskTranslator.getKioskIcons(kioskId, context); return KioskTranslator.getKioskIcons(getDefaultKioskId(context), context);
if (kioskIcon <= 0) {
throw new IllegalStateException("Kiosk ID is not valid: \"" + kioskId + "\"");
}
return kioskIcon;
} }
@Override @Override
public KioskFragment getFragment() throws ExtractionException { public DefaultKioskFragment getFragment(Context context) throws ExtractionException {
return KioskFragment.getInstance(kioskServiceId, kioskId); return new DefaultKioskFragment();
} }
public String getKioskId() { private String getDefaultKioskId(Context context) {
final int kioskServiceId = ServiceHelper.getSelectedServiceId(context);
String kioskId = "";
try {
final StreamingService service = NewPipe.getService(kioskServiceId);
kioskId = service.getKioskList().getDefaultKioskId();
} catch (ExtractionException e) {
ErrorActivity.reportError(context, e, null, null,
ErrorActivity.ErrorInfo.make(UserAction.REQUESTED_KIOSK, "none", "Loading default kiosk from selected service", 0));
}
return kioskId; return kioskId;
} }
} }

View File

@ -1,7 +1,5 @@
package org.schabi.newpipe.settings.tabs; package org.schabi.newpipe.settings.tabs;
import androidx.annotation.Nullable;
import com.grack.nanojson.JsonArray; import com.grack.nanojson.JsonArray;
import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonParser; import com.grack.nanojson.JsonParser;
@ -9,18 +7,25 @@ import com.grack.nanojson.JsonParserException;
import com.grack.nanojson.JsonStringWriter; import com.grack.nanojson.JsonStringWriter;
import com.grack.nanojson.JsonWriter; import com.grack.nanojson.JsonWriter;
import org.jsoup.helper.StringUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import androidx.annotation.Nullable;
/** /**
* Class to get a JSON representation of a list of tabs, and the other way around. * Class to get a JSON representation of a list of tabs, and the other way around.
*/ */
public class TabsJsonHelper { public class TabsJsonHelper {
private static final String JSON_TABS_ARRAY_KEY = "tabs"; private static final String JSON_TABS_ARRAY_KEY = "tabs";
private static final List<Tab> FALLBACK_INITIAL_TABS_LIST = Collections.unmodifiableList(Arrays.asList(
Tab.Type.DEFAULT_KIOSK.getTab(),
Tab.Type.SUBSCRIPTIONS.getTab(),
Tab.Type.BOOKMARKS.getTab()
));
public static class InvalidJsonException extends Exception { public static class InvalidJsonException extends Exception {
private InvalidJsonException() { private InvalidJsonException() {
super(); super();
@ -83,16 +88,6 @@ public class TabsJsonHelper {
return returnTabs; return returnTabs;
} }
public static List<Tab> getDefaultTabs(){
List<Tab> tabs = new ArrayList<>();
Tab.DefaultKioskTab tab = new Tab.DefaultKioskTab();
if(!StringUtil.isBlank(tab.getKioskId())){
tabs.add(tab);
}
tabs.add(Tab.Type.SUBSCRIPTIONS.getTab());
tabs.add(Tab.Type.BOOKMARKS.getTab());
return Collections.unmodifiableList(tabs);
}
/** /**
* Get a JSON representation from a list of tabs. * Get a JSON representation from a list of tabs.
* *
@ -112,4 +107,8 @@ public class TabsJsonHelper {
jsonWriter.end(); jsonWriter.end();
return jsonWriter.done(); return jsonWriter.done();
} }
public static List<Tab> getDefaultTabs(){
return FALLBACK_INITIAL_TABS_LIST;
}
} }

View File

@ -380,7 +380,7 @@
<string name="selection">Selection</string> <string name="selection">Selection</string>
<string name="blank_page_summary">Blank Page</string> <string name="blank_page_summary">Blank Page</string>
<string name="kiosk_page_summary">Kiosk Page</string> <string name="kiosk_page_summary">Kiosk Page</string>
<string name="default_kiosk_page_sumatry">Default Kiosk</string> <string name="default_kiosk_page_summary">Default Kiosk</string>
<string name="subscription_page_summary">Subscription Page</string> <string name="subscription_page_summary">Subscription Page</string>
<string name="feed_page_summary">Feed Page</string> <string name="feed_page_summary">Feed Page</string>
<string name="channel_page_summary">Channel Page</string> <string name="channel_page_summary">Channel Page</string>

View File

@ -1,6 +1,5 @@
package org.schabi.newpipe.settings.tabs; package org.schabi.newpipe.settings.tabs;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import java.util.HashSet; import java.util.HashSet;
@ -9,7 +8,6 @@ import java.util.Set;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class TabTest { public class TabTest {
@Ignore
@Test @Test
public void checkIdDuplication() { public void checkIdDuplication() {
final Set<Integer> usedIds = new HashSet<>(); final Set<Integer> usedIds = new HashSet<>();

View File

@ -5,7 +5,6 @@ import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonParser; import com.grack.nanojson.JsonParser;
import com.grack.nanojson.JsonParserException; import com.grack.nanojson.JsonParserException;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
@ -21,19 +20,19 @@ public class TabsJsonHelperTest {
private static final String JSON_TABS_ARRAY_KEY = "tabs"; private static final String JSON_TABS_ARRAY_KEY = "tabs";
private static final String JSON_TAB_ID_KEY = "tab_id"; private static final String JSON_TAB_ID_KEY = "tab_id";
@Ignore
@Test @Test
public void testEmptyAndNullRead() throws TabsJsonHelper.InvalidJsonException { public void testEmptyAndNullRead() throws TabsJsonHelper.InvalidJsonException {
final List<Tab> defaultTabs = TabsJsonHelper.getDefaultTabs();
final String emptyTabsJson = "{\"" + JSON_TABS_ARRAY_KEY + "\":[]}"; final String emptyTabsJson = "{\"" + JSON_TABS_ARRAY_KEY + "\":[]}";
List<Tab> items = TabsJsonHelper.getTabsFromJson(emptyTabsJson); List<Tab> items = TabsJsonHelper.getTabsFromJson(emptyTabsJson);
assertTrue(!items.isEmpty()); assertEquals(items, defaultTabs);
final String nullSource = null; final String nullSource = null;
items = TabsJsonHelper.getTabsFromJson(nullSource); items = TabsJsonHelper.getTabsFromJson(nullSource);
assertTrue(!items.isEmpty()); assertEquals(items, defaultTabs);
} }
@Ignore
@Test @Test
public void testInvalidIdRead() throws TabsJsonHelper.InvalidJsonException { public void testInvalidIdRead() throws TabsJsonHelper.InvalidJsonException {
final int blankTabId = Tab.Type.BLANK.getTabId(); final int blankTabId = Tab.Type.BLANK.getTabId();
@ -84,17 +83,17 @@ public class TabsJsonHelperTest {
return jsonObject.getArray(JSON_TABS_ARRAY_KEY).size() == 0; return jsonObject.getArray(JSON_TABS_ARRAY_KEY).size() == 0;
} }
@Ignore
@Test @Test
public void testSaveAndReading() throws JsonParserException { public void testSaveAndReading() throws JsonParserException {
// Saving // Saving
final Tab.BlankTab blankTab = new Tab.BlankTab(); final Tab.BlankTab blankTab = new Tab.BlankTab();
final Tab.DefaultKioskTab defaultKioskTab = new Tab.DefaultKioskTab();
final Tab.SubscriptionsTab subscriptionsTab = new Tab.SubscriptionsTab(); final Tab.SubscriptionsTab subscriptionsTab = new Tab.SubscriptionsTab();
final Tab.ChannelTab channelTab = new Tab.ChannelTab(666, "https://example.org", "testName"); final Tab.ChannelTab channelTab = new Tab.ChannelTab(666, "https://example.org", "testName");
final Tab.KioskTab kioskTab = new Tab.KioskTab(123, "trending_key"); final Tab.KioskTab kioskTab = new Tab.KioskTab(123, "trending_key");
final List<Tab> tabs = Arrays.asList(blankTab, subscriptionsTab, channelTab, kioskTab); final List<Tab> tabs = Arrays.asList(blankTab, defaultKioskTab, subscriptionsTab, channelTab, kioskTab);
String returnedJson = TabsJsonHelper.getJsonToSave(tabs); final String returnedJson = TabsJsonHelper.getJsonToSave(tabs);
// Reading // Reading
final JsonObject jsonObject = JsonParser.object().from(returnedJson); final JsonObject jsonObject = JsonParser.object().from(returnedJson);
@ -106,16 +105,19 @@ public class TabsJsonHelperTest {
final Tab.BlankTab blankTabFromReturnedJson = requireNonNull((Tab.BlankTab) Tab.from(((JsonObject) tabsFromArray.get(0)))); final Tab.BlankTab blankTabFromReturnedJson = requireNonNull((Tab.BlankTab) Tab.from(((JsonObject) tabsFromArray.get(0))));
assertEquals(blankTab.getTabId(), blankTabFromReturnedJson.getTabId()); assertEquals(blankTab.getTabId(), blankTabFromReturnedJson.getTabId());
final Tab.SubscriptionsTab subscriptionsTabFromReturnedJson = requireNonNull((Tab.SubscriptionsTab) Tab.from(((JsonObject) tabsFromArray.get(1)))); final Tab.DefaultKioskTab defaultKioskTabFromReturnedJson = requireNonNull((Tab.DefaultKioskTab) Tab.from(((JsonObject) tabsFromArray.get(1))));
assertEquals(defaultKioskTab.getTabId(), defaultKioskTabFromReturnedJson.getTabId());
final Tab.SubscriptionsTab subscriptionsTabFromReturnedJson = requireNonNull((Tab.SubscriptionsTab) Tab.from(((JsonObject) tabsFromArray.get(2))));
assertEquals(subscriptionsTab.getTabId(), subscriptionsTabFromReturnedJson.getTabId()); assertEquals(subscriptionsTab.getTabId(), subscriptionsTabFromReturnedJson.getTabId());
final Tab.ChannelTab channelTabFromReturnedJson = requireNonNull((Tab.ChannelTab) Tab.from(((JsonObject) tabsFromArray.get(2)))); final Tab.ChannelTab channelTabFromReturnedJson = requireNonNull((Tab.ChannelTab) Tab.from(((JsonObject) tabsFromArray.get(3))));
assertEquals(channelTab.getTabId(), channelTabFromReturnedJson.getTabId()); assertEquals(channelTab.getTabId(), channelTabFromReturnedJson.getTabId());
assertEquals(channelTab.getChannelServiceId(), channelTabFromReturnedJson.getChannelServiceId()); assertEquals(channelTab.getChannelServiceId(), channelTabFromReturnedJson.getChannelServiceId());
assertEquals(channelTab.getChannelUrl(), channelTabFromReturnedJson.getChannelUrl()); assertEquals(channelTab.getChannelUrl(), channelTabFromReturnedJson.getChannelUrl());
assertEquals(channelTab.getChannelName(), channelTabFromReturnedJson.getChannelName()); assertEquals(channelTab.getChannelName(), channelTabFromReturnedJson.getChannelName());
final Tab.KioskTab kioskTabFromReturnedJson = requireNonNull((Tab.KioskTab) Tab.from(((JsonObject) tabsFromArray.get(3)))); final Tab.KioskTab kioskTabFromReturnedJson = requireNonNull((Tab.KioskTab) Tab.from(((JsonObject) tabsFromArray.get(4))));
assertEquals(kioskTab.getTabId(), kioskTabFromReturnedJson.getTabId()); assertEquals(kioskTab.getTabId(), kioskTabFromReturnedJson.getTabId());
assertEquals(kioskTab.getKioskServiceId(), kioskTabFromReturnedJson.getKioskServiceId()); assertEquals(kioskTab.getKioskServiceId(), kioskTabFromReturnedJson.getKioskServiceId());
assertEquals(kioskTab.getKioskId(), kioskTabFromReturnedJson.getKioskId()); assertEquals(kioskTab.getKioskId(), kioskTabFromReturnedJson.getKioskId());