From 77678b8f31afb03f57d1ba33e61644597fcbb12b Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Mon, 13 Nov 2017 21:13:52 -0800 Subject: [PATCH 1/8] -Modified InfoItem LRU cache expire to allow expiration (current default 4 hours). -Modified info type display on InfoItemDialog to show uploader name if exists. --- .../fragments/detail/VideoDetailFragment.java | 2 + .../fragments/list/BaseListFragment.java | 2 + .../list/channel/ChannelFragment.java | 2 + .../list/playlist/PlaylistFragment.java | 3 +- .../newpipe/info_list/InfoItemDialog.java | 26 ++++++-- .../org/schabi/newpipe/util/InfoCache.java | 63 +++++++++++++++++-- app/src/main/res/layout/dialog_title.xml | 10 ++- 7 files changed, 94 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java index a4ee01ccc..d0460c347 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.java @@ -485,6 +485,8 @@ public class VideoDetailFragment extends BaseStateFragment implement private void showStreamDialog(final StreamInfoItem item) { final Context context = getContext(); + if (context == null || context.getResources() == null || getActivity() == null) return; + final String[] commands = new String[]{ context.getResources().getString(R.string.enqueue_on_background), context.getResources().getString(R.string.enqueue_on_popup) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java index fd1e9ea63..ae17dafff 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/BaseListFragment.java @@ -192,6 +192,8 @@ public abstract class BaseListFragment extends BaseStateFragment implem protected void showStreamDialog(final StreamInfoItem item) { final Context context = getContext(); + if (context == null || context.getResources() == null || getActivity() == null) return; + final String[] commands = new String[]{ context.getResources().getString(R.string.enqueue_on_background), context.getResources().getString(R.string.enqueue_on_popup) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java index 348495079..857fb81e0 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/channel/ChannelFragment.java @@ -154,6 +154,8 @@ public class ChannelFragment extends BaseListInfoFragment { @Override protected void showStreamDialog(final StreamInfoItem item) { final Context context = getContext(); + if (context == null || context.getResources() == null || getActivity() == null) return; + final String[] commands = new String[]{ context.getResources().getString(R.string.enqueue_on_background), context.getResources().getString(R.string.enqueue_on_popup), diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java index 878dbf385..e7f7e9968 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/playlist/PlaylistFragment.java @@ -15,7 +15,6 @@ import android.view.MenuInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -109,6 +108,8 @@ public class PlaylistFragment extends BaseListInfoFragment { @Override protected void showStreamDialog(final StreamInfoItem item) { final Context context = getContext(); + if (context == null || context.getResources() == null || getActivity() == null) return; + final String[] commands = new String[]{ context.getResources().getString(R.string.enqueue_on_background), context.getResources().getString(R.string.enqueue_on_popup), diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java index 72152500f..1cc2ca19e 100644 --- a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java +++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemDialog.java @@ -4,28 +4,44 @@ import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; import org.schabi.newpipe.R; -import org.schabi.newpipe.extractor.InfoItem; +import org.schabi.newpipe.extractor.stream.StreamInfoItem; public class InfoItemDialog { private final AlertDialog dialog; public InfoItemDialog(@NonNull final Activity activity, - @NonNull final InfoItem item, + @NonNull final StreamInfoItem info, @NonNull final String[] commands, @NonNull final DialogInterface.OnClickListener actions) { + this(activity, commands, actions, info.name, info.uploader_name); + } + + public InfoItemDialog(@NonNull final Activity activity, + @NonNull final String[] commands, + @NonNull final DialogInterface.OnClickListener actions, + @NonNull final String title, + @Nullable final String additionalDetail) { final LayoutInflater inflater = activity.getLayoutInflater(); final View bannerView = inflater.inflate(R.layout.dialog_title, null); bannerView.setSelected(true); + TextView titleView = bannerView.findViewById(R.id.itemTitleView); - titleView.setText(item.name); - TextView typeView = bannerView.findViewById(R.id.itemTypeView); - typeView.setText(item.info_type.name()); + titleView.setText(title); + + TextView detailsView = bannerView.findViewById(R.id.itemAdditionalDetails); + if (additionalDetail != null) { + detailsView.setText(additionalDetail); + detailsView.setVisibility(View.VISIBLE); + } else { + detailsView.setVisibility(View.GONE); + } dialog = new AlertDialog.Builder(activity) .setCustomTitle(bannerView) diff --git a/app/src/main/java/org/schabi/newpipe/util/InfoCache.java b/app/src/main/java/org/schabi/newpipe/util/InfoCache.java index 5b22af86a..a3fd7805a 100644 --- a/app/src/main/java/org/schabi/newpipe/util/InfoCache.java +++ b/app/src/main/java/org/schabi/newpipe/util/InfoCache.java @@ -26,6 +26,9 @@ import android.util.Log; import org.schabi.newpipe.MainActivity; import org.schabi.newpipe.extractor.Info; +import java.util.Map; +import java.util.concurrent.TimeUnit; + public final class InfoCache { private static final boolean DEBUG = MainActivity.DEBUG; @@ -37,9 +40,10 @@ public final class InfoCache { * Trim the cache to this size */ private static final int TRIM_CACHE_TO = 30; + private static final int DEFAULT_TIMEOUT_HOURS = 4; // TODO: Replace to one with timeout (like the one from guava) - private static final LruCache lruCache = new LruCache<>(MAX_ITEMS_ON_CACHE); + private static final LruCache lruCache = new LruCache<>(MAX_ITEMS_ON_CACHE); private InfoCache() { //no instance @@ -52,28 +56,29 @@ public final class InfoCache { public Info getFromKey(int serviceId, @NonNull String url) { if (DEBUG) Log.d(TAG, "getFromKey() called with: serviceId = [" + serviceId + "], url = [" + url + "]"); synchronized (lruCache) { - return lruCache.get(serviceId + url); + return getInfo(lruCache, keyOf(serviceId, url)); } } public void putInfo(@NonNull Info info) { if (DEBUG) Log.d(TAG, "putInfo() called with: info = [" + info + "]"); synchronized (lruCache) { - lruCache.put(info.service_id + info.url, info); + final CacheData data = new CacheData(info, DEFAULT_TIMEOUT_HOURS, TimeUnit.HOURS); + lruCache.put(keyOf(info), data); } } public void removeInfo(@NonNull Info info) { if (DEBUG) Log.d(TAG, "removeInfo() called with: info = [" + info + "]"); synchronized (lruCache) { - lruCache.remove(info.service_id + info.url); + lruCache.remove(keyOf(info)); } } public void removeInfo(int serviceId, @NonNull String url) { if (DEBUG) Log.d(TAG, "removeInfo() called with: serviceId = [" + serviceId + "], url = [" + url + "]"); synchronized (lruCache) { - lruCache.remove(serviceId + url); + lruCache.remove(keyOf(serviceId, url)); } } @@ -87,6 +92,7 @@ public final class InfoCache { public void trimCache() { if (DEBUG) Log.d(TAG, "trimCache() called"); synchronized (lruCache) { + removeStaleCache(lruCache); lruCache.trimToSize(TRIM_CACHE_TO); } } @@ -97,4 +103,51 @@ public final class InfoCache { } } + private static String keyOf(@NonNull final Info info) { + return keyOf(info.service_id, info.url); + } + + private static String keyOf(final int serviceId, @NonNull final String url) { + return serviceId + url; + } + + private static void removeStaleCache(@NonNull final LruCache cache) { + for (Map.Entry entry : cache.snapshot().entrySet()) { + final CacheData data = entry.getValue(); + if (data != null && data.isExpired()) { + cache.remove(entry.getKey()); + } + } + } + + private static Info getInfo(@NonNull final LruCache cache, + @NonNull final String key) { + final CacheData data = cache.get(key); + if (data == null) return null; + + if (data.isExpired()) { + cache.remove(key); + return null; + } + + return data.info; + } + + final private static class CacheData { + final private long expireTimestamp; + final private Info info; + + private CacheData(@NonNull final Info info, + final long timeout, + @NonNull final TimeUnit timeUnit) { + this.expireTimestamp = System.currentTimeMillis() + + TimeUnit.MILLISECONDS.convert(timeout, timeUnit); + + this.info = info; + } + + private boolean isExpired() { + return System.currentTimeMillis() > expireTimestamp; + } + } } diff --git a/app/src/main/res/layout/dialog_title.xml b/app/src/main/res/layout/dialog_title.xml index dc76a4f20..fa7e155d2 100644 --- a/app/src/main/res/layout/dialog_title.xml +++ b/app/src/main/res/layout/dialog_title.xml @@ -6,7 +6,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="false" - android:padding="@dimen/video_item_search_padding"> + android:paddingLeft="@dimen/video_item_search_padding" + android:paddingRight="@dimen/video_item_search_padding" + android:paddingTop="@dimen/video_item_search_padding"> \ No newline at end of file From 979bd09b29ff8326ef875ae158c8f895d89b35bc Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Tue, 14 Nov 2017 10:13:36 -0800 Subject: [PATCH 2/8] -Fixed popup player not in foreground when opened by external intent. -Fixed popup overlay permission causing exception when opened externally. --- app/src/main/AndroidManifest.xml | 2 +- .../org/schabi/newpipe/RouterPopupActivity.java | 1 + .../schabi/newpipe/player/PopupVideoPlayer.java | 14 +++++++++----- app/src/main/res/values/styles.xml | 8 ++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4f97a7201..dab6fb2ec 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -185,7 +185,7 @@ android:name=".RouterPopupActivity" android:label="@string/popup_mode_share_menu_title" android:taskAffinity="" - android:theme="@android:style/Theme.NoDisplay"> + android:theme="@style/PopupPermissionsTheme"> diff --git a/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java b/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java index 1cff0ca76..2e7089300 100644 --- a/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java +++ b/app/src/main/java/org/schabi/newpipe/RouterPopupActivity.java @@ -21,6 +21,7 @@ public class RouterPopupActivity extends RouterActivity { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !PermissionHelper.checkSystemAlertWindowPermission(this)) { Toast.makeText(this, R.string.msg_popup_permission, Toast.LENGTH_LONG).show(); + finish(); return; } StreamingService service; diff --git a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java index a3fd0f7a7..5f8b36449 100644 --- a/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/PopupVideoPlayer.java @@ -842,6 +842,8 @@ public final class PopupVideoPlayer extends Service { } savePositionAndSize(); } + + v.performClick(); return true; } @@ -880,23 +882,25 @@ public final class PopupVideoPlayer extends Service { private final Context context; private final Handler mainHandler; - FetcherHandler(Context context, int serviceId, String url) { + private FetcherHandler(Context context, int serviceId, String url) { this.mainHandler = new Handler(PopupVideoPlayer.this.getMainLooper()); this.context = context; this.url = url; this.serviceId = serviceId; } - /*package-private*/ void onReceive(final StreamInfo info) { + private void onReceive(final StreamInfo info) { mainHandler.post(new Runnable() { @Override public void run() { - playerImpl.initPlayback(new SinglePlayQueue(info)); + final Intent intent = NavigationHelper.getPlayerIntent(getApplicationContext(), + PopupVideoPlayer.class, new SinglePlayQueue(info)); + playerImpl.handleIntent(intent); } }); } - protected void onError(final Throwable exception) { + private void onError(final Throwable exception) { if (DEBUG) Log.d(TAG, "onError() called with: exception = [" + exception + "]"); exception.printStackTrace(); mainHandler.post(new Runnable() { @@ -922,7 +926,7 @@ public final class PopupVideoPlayer extends Service { stopSelf(); } - /*package-private*/ void onReCaptchaException() { + private void onReCaptchaException() { Toast.makeText(context, R.string.recaptcha_request_toast, Toast.LENGTH_LONG).show(); // Starting ReCaptcha Challenge Activity Intent intent = new Intent(context, ReCaptchaActivity.class); diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 8f0bb02cd..d69bba254 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -160,4 +160,12 @@ @color/dark_youtube_primary_color + From 98e617001dd63200003041bcacfcdb095c42fb11 Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Tue, 14 Nov 2017 10:51:44 -0800 Subject: [PATCH 3/8] -Added search suggestion insert per #840. --- .../fragments/list/search/SearchFragment.java | 7 +- .../list/search/SuggestionListAdapter.java | 24 ++++-- .../ic_arrow_top_left_black_24dp.png | Bin 0 -> 554 bytes .../ic_arrow_top_left_white_24dp.png | Bin 0 -> 546 bytes .../ic_arrow_top_left_black_24dp.png | Bin 0 -> 418 bytes .../ic_arrow_top_left_white_24dp.png | Bin 0 -> 427 bytes .../ic_arrow_top_left_black_24dp.png | Bin 0 -> 492 bytes .../ic_arrow_top_left_white_24dp.png | Bin 0 -> 500 bytes .../ic_arrow_top_left_black_24dp.png | Bin 0 -> 570 bytes .../ic_arrow_top_left_white_24dp.png | Bin 0 -> 573 bytes .../ic_arrow_top_left_black_24dp.png | Bin 0 -> 675 bytes .../ic_arrow_top_left_white_24dp.png | Bin 0 -> 730 bytes .../res/layout/item_search_suggestion.xml | 80 ++++++++++++------ app/src/main/res/values/attrs.xml | 1 + app/src/main/res/values/styles.xml | 2 + 15 files changed, 79 insertions(+), 35 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/ic_arrow_top_left_black_24dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_arrow_top_left_white_24dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_arrow_top_left_black_24dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_arrow_top_left_white_24dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_arrow_top_left_black_24dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_arrow_top_left_white_24dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_black_24dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_white_24dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_arrow_top_left_black_24dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_arrow_top_left_white_24dp.png diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index fae97bb7b..597c8d74f 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -165,7 +165,7 @@ public class SearchFragment extends BaseListFragment items = new ArrayList<>(); private final Context context; private OnSuggestionItemSelected listener; - private boolean showSugestinHistory = true; + private boolean showSuggestionHistory = true; public interface OnSuggestionItemSelected { void onSuggestionItemSelected(SuggestionItem item); + void onSuggestionItemInserted(SuggestionItem item); void onSuggestionItemLongClick(SuggestionItem item); } @@ -32,7 +33,7 @@ public class SuggestionListAdapter extends RecyclerView.Adapter items) { this.items.clear(); - if (showSugestinHistory) { + if (showSuggestionHistory) { this.items.addAll(items); } else { // remove history items if history is disabled @@ -49,8 +50,8 @@ public class SuggestionListAdapter extends RecyclerView.Adapter|k1|%Oc%$NbBSkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+eS5K)hhiu0R{01Y44~ zy9wy$!fk$L9koEv$x0Bg+K*noN7srr@!*8cKavd@dU|7DDU%=)U*Iq5V zWiK2*2-dc6DcL!Hc;UGJ;nm3x*mG>R9DSvlwp+1DQlrFk)693v1UOij>fKT#_&4@Gttwrp zx*_jK@TqGny>6;S*LWw3^66~CoRIOlk7jeO&>D!23MQWL&KtEOCgze??@ zVUPNOsh_k8S@ha|vM=E0SzQru^tab7Zov(Y{%UR7yf$RQCs&`!4cQCX4L)kJtoM3) z;Ldg*-!uFnY62X8RQ!X*J%62OC7#SFv>lzyB8k&R{ zT38tw0FkzVft7)Q^7o6MP&DM`r(~v8;?@wfD$@_BK?7t%aap=mQettcZfQ{_Lt17| ss+GRJeo1bDer{rVW^%S}nP+i9ak8WPm6!+bfO;4_UHx3vIVCg!0K|k1|%Oc%$NbBSkfJR9T^xl_H+M9WCijWi-X*q z7}lMWc?skwBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+eS5K)hhiu0R{01Y44~ zy9wy$!fk$L9koEv$x0Bg+K*nQF7srr@!*8cLavd@daJ}EbE@0F5=+xv6 zJr@3pOW6Y)yS86^%n^5>&RkE0+w|oTt!Iu4m!5n-+vl>=!hj#fZ*KZ}CMQgpQERk$ z@#?ipyk3TAo`175?16)Q;yKn8jn9tmSW>o>gSSC(gTdzTpo>Sgy!lgL$NX*5ooG4X z9gJoC*NYc?o7Tk}%^GB!zjB3wad6(s7ZdITc`{lqouvMJQdX!h-^y#Y-=`Jbl$?K~ zmce6|SJeIfm(q``C%t;G{{6p?J-UZfa+y~;Py8ji^26L+Ub9NnMAn2TXWm@tvmxm2 zIv=1L!}1~oWKZY|WdK8pLAAs+q9i4;B-JXpC>2OC7#SFv>lzyB8k&R{T38tw0FkzV zft7)Q^7o6MP&DM`r(~v8;?@wfD$@_BK?7t%aap=mQettcZfQ{_Lt17|s+GRJeo1bD jer{rVW^%S}fNrRZw^LD|th;#(P!EHrtDnm{r-UW|&5FRu literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/ic_arrow_top_left_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_arrow_top_left_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..056a0ff28fe1c73e040bbcfe98d4916e35d2c2c1 GIT binary patch literal 418 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaL-l0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YPV z+ua371Hn({-St38vK4 z>mKHF>KMOU+RAF+{SB!2#f4K%fd(fS8P;&S6G7^>bP0l+XkK DgQ!lvI6;x#X;^) z4C~IxyaaL-l0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YPV z+ua371Hn({-St32@2ahr!d; K&t;ucLK6U^dWg{g literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_arrow_top_left_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_arrow_top_left_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..e4255a18aa1fe5067cc5f6cb263513c3f8ce30a3 GIT binary patch literal 492 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTCmUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)pVryh>nTu$sZZAYL$MSD+10f-TA0 z-33Sk!B6Mi^+1ZVz$3C4NPB>>+sSM@AY-kki(^Q}y|>play2^$v^+F?BKUNc&HSnP z60Ev8E_;vc<-Qp?S6+wZ;Lkl?4w_4+1l5_grK=w=Pp|${apk_SLQwECDaJi}j$dUs zq_Ayqd-LxnwwIVP821RiP}#=d;w;1Hq*&Bo(Ba=8(2>tjbwrZE^pQ@3SR!M9(i#RU z7tRK*K&}OjR~Rw`wsIbvB%l+^G;za!+qZk%BctcL@IQEIyJAVp)6?xT>!$>H-Q6sy zeRmH}h2>g4pu<&5Tq8Hb>+6@~7U<_Dre`K+ d>zW(71{u1ByYM$<^#JuSc)I$ztaD0e0sw$6n)?6% literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_arrow_top_left_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_arrow_top_left_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..db578cab9eaea2867b9fc4c52666df450747b034 GIT binary patch literal 500 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTCmUKs7M+SzC{oH>NS%G}U;vjb? zhIQv;UIIA^$sR$z3=CCj3=9n|3=F@3LJcn%7)pVryh>nTu$sZZAYL$MSD+10f-TA0 z-33Sk!B6Mi^+1ZVz$3C4NPB>>+sSM@AY-eii(^Q}y|>p5`I-#`TmogDcAW4%=RQ@M zZOKB<#sdPkBi`uDyx%xsM!ME6Kh336g34O&urn@r+3kFy?t5VWHT9xWrX8HWeHr4e z{XWM~qad{S_>s~r_ad2IFxK3u>HPZZy{&zR$N|wL{s(M@ECr1}SQofIVOSx!lOf85 zvq313Yk~6>h7|%^8KjO#GVm@ssL0_sQ9$P|tKi1Jwz6x=rz%a0f5iJBbMHzvK}H_E z>`X#vq k`nieenaSC@5hdZ}ArZlTr+>{_3Dm>j>FVdQ&MBb@0DXj_ZvX%Q literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..566b5c5d3a8ab9360f3aa48e743fa9bc717cc45f GIT binary patch literal 570 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!Ea{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaL-l0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YPV z+ua371Hn({-St3hV4g#(hm$!br&+`9@ z6UUF-u#Fo84d3N#I;~>--RabU+lMEq2?;_#;0iwN`}50o-M(}2Wy5aH1x^g2Oe+K& z=FaXp?|kWI^_yvpmz1tDEOlAM>eX)2ZXhbeR&s!Mp z@u22wC(AjX=6m<&bbl96f`CQ6-!C8<`)MX5lF!N|bS zT-VT0*U%)y(89{d0En~=46F#UX>ItDnm{r-UW|QUSgU literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_arrow_top_left_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..89d726f6caf5ccaf2af95e40a989a91cc4136b56 GIT binary patch literal 573 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!Ea{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaL-l0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YPV z+ua371Hn({-St3+# zD1N*-r;oeY&?(w$Z^irn>sy|D@jmQyT@VU(u3BFiImyTEd+pVCll;Wk|14+lVhK=c z5MsPy^z{3Ll8yJOQx?qdXm$8F!HnUkQRdP`(kYX@0 zFf`XSG}JXT2{E*=GBN-nZ36=<0|Vvn7eAqB$jwj5OsmALA!t>mA5en^$cEywbgQJq z;#A$zqD+Rg%$!s!eSQ6s+yedF#PrPMY+d8f%w+$v0G}_Or!s(g7(8A5T-G@yGywp5 C0mMWA literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_arrow_top_left_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_arrow_top_left_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..d536127b5539a902072bbeeb5a5a1879901954e6 GIT binary patch literal 675 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGoEa{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaL-l0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YPV z+ua371Hn({-St3w(+=}`CtE2=T;s2ELti$LB(?t6urIb+{w) zd89R@zzJEaP#gIJ-rpWn2MQnHXv|`kQ1tL-P-e;CO=xk;K3%JC@wqhb43_TZ)PGd-DDTron5Olf<6l__^%izXwQ3xor#*{%~ zp{EOjfz#F%Ks8zu84qyGc4cQ!&bg!vl!;gm6jZVWY7G0z$KbXj3#jtYem7PIcrvS~YInBl3*3i`bz3jW-CZPId2`!uwiA-)Y8U)oanA}h0`Q$dY-(5Y) z{Gn*YDY=sK>s$+dHpg^5_{9EO^59eTNQ?gu>`X#vq`nieenaSC@{#Ch!QI$E4*R)ff Q0QE3!lvI6;x#X;^) z4C~IxyaaL-l0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YPV z+ua371Hn({-St3X>)PK*Tk0x%7fpep(CP z?M>ys>ls@1Va6WERxXQ=<@-F}Nm_6Fyq;qzP&W*0%j&upFlkf#t9RV~!9T3GSDf5; z;GUp@B;zDFvCZxD9M#&C`?bPiYzj_O+8A6qE=VMl3%dOgwwn^P@0*aK@`0U6XBSTS zr1^42!T#rAA3H0je>wbo#bkHkuTn~1f`kve?zrHb%dlS6X^SP}o_QP-pRs)~cInup z(lB4ysbwkSA05G{tt=ltyJTFHI#4Z;xUz%cUOR`k3+snCml@hd4d0ayooQ@k`!LUC zhT)nI4ELsUOl^K8bf8*zVUovPriywc8;OAH40g>NOHtd=s>#Q!}$x> zh#hz?_%KUhHQR@oEcJn8aS90 z4l$rJ9WDi4%1> - + android:layout_height="wrap_content"> - - - + + + + + + + - \ No newline at end of file + android:src="?attr/search_add" + android:background="?attr/selectableItemBackgroundBorderless" + tools:ignore="ContentDescription,RtlHardcoded"/> + diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index abf7c7b09..e51ab9ffd 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -20,6 +20,7 @@ + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d69bba254..d41b3fe31 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -27,6 +27,7 @@ @drawable/ic_history_black_24dp @drawable/ic_drag_handle_black_24dp @drawable/ic_fiber_manual_record_black_24dp + @drawable/ic_arrow_top_left_black_24dp @color/light_separator_color @color/light_contrast_background_color @@ -65,6 +66,7 @@ @drawable/ic_history_white_24dp @drawable/ic_drag_handle_white_24dp @drawable/ic_fiber_manual_record_white_24dp + @drawable/ic_arrow_top_left_white_24dp @color/dark_separator_color @color/dark_contrast_background_color From 0fe5a44e5a2b8c917eebe1c7e37643a26c6af34b Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Tue, 14 Nov 2017 10:58:01 -0800 Subject: [PATCH 4/8] -Removed todo for timeout feature on info cache. --- app/src/main/java/org/schabi/newpipe/util/InfoCache.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/org/schabi/newpipe/util/InfoCache.java b/app/src/main/java/org/schabi/newpipe/util/InfoCache.java index a3fd7805a..794c3dd78 100644 --- a/app/src/main/java/org/schabi/newpipe/util/InfoCache.java +++ b/app/src/main/java/org/schabi/newpipe/util/InfoCache.java @@ -42,7 +42,6 @@ public final class InfoCache { private static final int TRIM_CACHE_TO = 30; private static final int DEFAULT_TIMEOUT_HOURS = 4; - // TODO: Replace to one with timeout (like the one from guava) private static final LruCache lruCache = new LruCache<>(MAX_ITEMS_ON_CACHE); private InfoCache() { From 5e16969d61b19c7bb4cf3fdfe7fc1a502c008abd Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Tue, 14 Nov 2017 11:32:50 -0800 Subject: [PATCH 5/8] -Increased search item insert arrow click space. --- .../res/layout/item_search_suggestion.xml | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/app/src/main/res/layout/item_search_suggestion.xml b/app/src/main/res/layout/item_search_suggestion.xml index f6facf29e..374339bbc 100644 --- a/app/src/main/res/layout/item_search_suggestion.xml +++ b/app/src/main/res/layout/item_search_suggestion.xml @@ -3,7 +3,8 @@ 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:layout_height="wrap_content" + android:orientation="horizontal"> @@ -44,17 +44,28 @@ tools:text="Search query"/> - + android:layout_alignParentRight="true" + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingBottom="8dp" + android:paddingTop="8dp"> + + + + + From 69374e25fec2cd3478186ddcfa1fe70daaedbecc Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Tue, 14 Nov 2017 15:58:13 -0800 Subject: [PATCH 6/8] -Fixed cursor position to point to end after search text insert. -Reduced and slightly changed offset of search text insert image. --- .../newpipe/fragments/list/search/SearchFragment.java | 1 + app/src/main/res/layout/item_search_suggestion.xml | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java index 597c8d74f..fb54a15c3 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/search/SearchFragment.java @@ -449,6 +449,7 @@ public class SearchFragment extends BaseListFragment + android:paddingTop="10dp"> From d6e4f3c80982c41f5f3c2546fd3d5c0b32511332 Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Wed, 15 Nov 2017 20:09:01 -0800 Subject: [PATCH 7/8] -Saves the recovery timestamp when player source fails during a valid stream playback. --- .../org/schabi/newpipe/player/BasePlayer.java | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java index 3da976991..427c97741 100644 --- a/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java +++ b/app/src/main/java/org/schabi/newpipe/player/BasePlayer.java @@ -134,6 +134,7 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen protected final static int FAST_FORWARD_REWIND_AMOUNT = 10000; // 10 Seconds protected final static int PLAY_PREV_ACTIVATION_LIMIT = 5000; // 5 seconds protected final static int PROGRESS_LOOP_INTERVAL = 500; + protected final static int RECOVERY_SKIP_THRESHOLD = 3000; // 3 seconds protected SimpleExoPlayer simpleExoPlayer; protected AudioReactor audioReactor; @@ -453,16 +454,20 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen final PlayQueueItem currentSourceItem = playQueue.getItem(); // Check if already playing correct window - final boolean isCurrentWindowCorrect = simpleExoPlayer.getCurrentWindowIndex() == currentSourceIndex; + final boolean isCurrentWindowCorrect = + simpleExoPlayer.getCurrentWindowIndex() == currentSourceIndex; // Check if recovering - if (isCurrentWindowCorrect && currentSourceItem != null && - currentSourceItem.getRecoveryPosition() != PlayQueueItem.RECOVERY_UNSET) { + if (isCurrentWindowCorrect && currentSourceItem != null) { /* Recovering with sub-second position may cause a long buffer delay in ExoPlayer, * rounding this position to the nearest second will help alleviate this.*/ final long position = currentSourceItem.getRecoveryPosition(); - if (DEBUG) Log.d(TAG, "Rewinding to recovery window: " + currentSourceIndex + " at: " + getTimeString((int)position)); + /* Skip recovering if the recovery position is not set.*/ + if (position == PlayQueueItem.RECOVERY_UNSET) return; + + if (DEBUG) Log.d(TAG, "Rewinding to recovery window: " + currentSourceIndex + + " at: " + getTimeString((int)position)); simpleExoPlayer.seekTo(currentSourceItem.getRecoveryPosition()); playQueue.unsetRecovery(currentSourceIndex); } @@ -514,10 +519,10 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen } break; case Player.STATE_READY: //3 + recover(); if (!isPrepared) { isPrepared = true; onPrepared(playWhenReady); - recover(); break; } if (currentState == STATE_PAUSED_SEEK) break; @@ -544,14 +549,18 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen * an error to the play queue based on if the current error can be skipped. * * This is done because ExoPlayer reports the source exceptions before window is - * transitioned on seamless playback. + * transitioned on seamless playback. Because player error causes ExoPlayer to go + * back to {@link Player#STATE_IDLE STATE_IDLE}, we reset and prepare the media source + * again to resume playback. * - * Because player error causes ExoPlayer to go back to {@link Player#STATE_IDLE STATE_IDLE}, - * we reset and prepare the media source again to resume playback.

+ * In the event that this error is produced during a valid stream playback, we save the + * current position so the playback may be recovered and resumed manually by the user. This + * happens only if the playback is {@link #RECOVERY_SKIP_THRESHOLD} milliseconds until complete. + *

* * {@link ExoPlaybackException#TYPE_UNEXPECTED TYPE_UNEXPECTED}:

* If a runtime error occurred, then we can try to recover it by restarting the playback - * after setting the timestamp recovery. + * after setting the timestamp recovery.

* * {@link ExoPlaybackException#TYPE_RENDERER TYPE_RENDERER}:

* If the renderer failed, treat the error as unrecoverable. @@ -568,6 +577,10 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen switch (error.type) { case ExoPlaybackException.TYPE_SOURCE: + if (simpleExoPlayer.getCurrentPosition() < + simpleExoPlayer.getDuration() - RECOVERY_SKIP_THRESHOLD) { + setRecovery(); + } playQueue.error(isCurrentWindowValid()); showStreamError(error); break; From 2da411c1ecd3995c5f2afb9a361cd1efcd5aab44 Mon Sep 17 00:00:00 2001 From: John Zhen Mo Date: Wed, 15 Nov 2017 20:42:05 -0800 Subject: [PATCH 8/8] -#836: Modified notifications texts to use custom colors instead of device-specific styles. --- app/src/main/res/layout/player_notification.xml | 4 ++-- app/src/main/res/layout/player_notification_expanded.xml | 6 +++--- app/src/main/res/layout/player_popup_notification.xml | 4 ++-- app/src/main/res/values/colors.xml | 3 +++ 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/src/main/res/layout/player_notification.xml b/app/src/main/res/layout/player_notification.xml index 157615bb7..2a3e7aff3 100644 --- a/app/src/main/res/layout/player_notification.xml +++ b/app/src/main/res/layout/player_notification.xml @@ -34,22 +34,22 @@ diff --git a/app/src/main/res/layout/player_notification_expanded.xml b/app/src/main/res/layout/player_notification_expanded.xml index d37087312..7d59720e0 100644 --- a/app/src/main/res/layout/player_notification_expanded.xml +++ b/app/src/main/res/layout/player_notification_expanded.xml @@ -46,22 +46,22 @@ @@ -80,7 +80,6 @@ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 3750bdb78..b77a2d229 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -39,7 +39,10 @@ #EEFFFFFF #ffffff #66000000 + #323232 + #ffffff + #999999 #e53935 #fff