mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 07:13:00 +00:00 
			
		
		
		
	-Modified InfoItem LRU cache expire to allow expiration (current default 4 hours).
-Modified info type display on InfoItemDialog to show uploader name if exists.
This commit is contained in:
		| @@ -485,6 +485,8 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement | |||||||
|  |  | ||||||
|     private void showStreamDialog(final StreamInfoItem item) { |     private void showStreamDialog(final StreamInfoItem item) { | ||||||
|         final Context context = getContext(); |         final Context context = getContext(); | ||||||
|  |         if (context == null || context.getResources() == null || getActivity() == null) return; | ||||||
|  |  | ||||||
|         final String[] commands = new String[]{ |         final String[] commands = new String[]{ | ||||||
|                 context.getResources().getString(R.string.enqueue_on_background), |                 context.getResources().getString(R.string.enqueue_on_background), | ||||||
|                 context.getResources().getString(R.string.enqueue_on_popup) |                 context.getResources().getString(R.string.enqueue_on_popup) | ||||||
|   | |||||||
| @@ -192,6 +192,8 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem | |||||||
|  |  | ||||||
|     protected void showStreamDialog(final StreamInfoItem item) { |     protected void showStreamDialog(final StreamInfoItem item) { | ||||||
|         final Context context = getContext(); |         final Context context = getContext(); | ||||||
|  |         if (context == null || context.getResources() == null || getActivity() == null) return; | ||||||
|  |  | ||||||
|         final String[] commands = new String[]{ |         final String[] commands = new String[]{ | ||||||
|                 context.getResources().getString(R.string.enqueue_on_background), |                 context.getResources().getString(R.string.enqueue_on_background), | ||||||
|                 context.getResources().getString(R.string.enqueue_on_popup) |                 context.getResources().getString(R.string.enqueue_on_popup) | ||||||
|   | |||||||
| @@ -154,6 +154,8 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> { | |||||||
|     @Override |     @Override | ||||||
|     protected void showStreamDialog(final StreamInfoItem item) { |     protected void showStreamDialog(final StreamInfoItem item) { | ||||||
|         final Context context = getContext(); |         final Context context = getContext(); | ||||||
|  |         if (context == null || context.getResources() == null || getActivity() == null) return; | ||||||
|  |  | ||||||
|         final String[] commands = new String[]{ |         final String[] commands = new String[]{ | ||||||
|                 context.getResources().getString(R.string.enqueue_on_background), |                 context.getResources().getString(R.string.enqueue_on_background), | ||||||
|                 context.getResources().getString(R.string.enqueue_on_popup), |                 context.getResources().getString(R.string.enqueue_on_popup), | ||||||
|   | |||||||
| @@ -15,7 +15,6 @@ import android.view.MenuInflater; | |||||||
| import android.view.View; | import android.view.View; | ||||||
| import android.view.ViewGroup; | import android.view.ViewGroup; | ||||||
| import android.widget.ImageView; | import android.widget.ImageView; | ||||||
| import android.widget.LinearLayout; |  | ||||||
| import android.widget.TextView; | import android.widget.TextView; | ||||||
| import android.widget.Toast; | import android.widget.Toast; | ||||||
|  |  | ||||||
| @@ -109,6 +108,8 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> { | |||||||
|     @Override |     @Override | ||||||
|     protected void showStreamDialog(final StreamInfoItem item) { |     protected void showStreamDialog(final StreamInfoItem item) { | ||||||
|         final Context context = getContext(); |         final Context context = getContext(); | ||||||
|  |         if (context == null || context.getResources() == null || getActivity() == null) return; | ||||||
|  |  | ||||||
|         final String[] commands = new String[]{ |         final String[] commands = new String[]{ | ||||||
|                 context.getResources().getString(R.string.enqueue_on_background), |                 context.getResources().getString(R.string.enqueue_on_background), | ||||||
|                 context.getResources().getString(R.string.enqueue_on_popup), |                 context.getResources().getString(R.string.enqueue_on_popup), | ||||||
|   | |||||||
| @@ -4,28 +4,44 @@ import android.app.Activity; | |||||||
| import android.app.AlertDialog; | import android.app.AlertDialog; | ||||||
| import android.content.DialogInterface; | import android.content.DialogInterface; | ||||||
| import android.support.annotation.NonNull; | import android.support.annotation.NonNull; | ||||||
|  | import android.support.annotation.Nullable; | ||||||
| import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||||
| import android.view.View; | import android.view.View; | ||||||
| import android.widget.TextView; | import android.widget.TextView; | ||||||
|  |  | ||||||
| import org.schabi.newpipe.R; | import org.schabi.newpipe.R; | ||||||
| import org.schabi.newpipe.extractor.InfoItem; | import org.schabi.newpipe.extractor.stream.StreamInfoItem; | ||||||
|  |  | ||||||
| public class InfoItemDialog { | public class InfoItemDialog { | ||||||
|     private final AlertDialog dialog; |     private final AlertDialog dialog; | ||||||
|  |  | ||||||
|     public InfoItemDialog(@NonNull final Activity activity, |     public InfoItemDialog(@NonNull final Activity activity, | ||||||
|                           @NonNull final InfoItem item, |                           @NonNull final StreamInfoItem info, | ||||||
|                           @NonNull final String[] commands, |                           @NonNull final String[] commands, | ||||||
|                           @NonNull final DialogInterface.OnClickListener actions) { |                           @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 LayoutInflater inflater = activity.getLayoutInflater(); | ||||||
|         final View bannerView = inflater.inflate(R.layout.dialog_title, null); |         final View bannerView = inflater.inflate(R.layout.dialog_title, null); | ||||||
|         bannerView.setSelected(true); |         bannerView.setSelected(true); | ||||||
|  |  | ||||||
|         TextView titleView = bannerView.findViewById(R.id.itemTitleView); |         TextView titleView = bannerView.findViewById(R.id.itemTitleView); | ||||||
|         titleView.setText(item.name); |         titleView.setText(title); | ||||||
|         TextView typeView = bannerView.findViewById(R.id.itemTypeView); |  | ||||||
|         typeView.setText(item.info_type.name()); |         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) |         dialog = new AlertDialog.Builder(activity) | ||||||
|                 .setCustomTitle(bannerView) |                 .setCustomTitle(bannerView) | ||||||
|   | |||||||
| @@ -26,6 +26,9 @@ import android.util.Log; | |||||||
| import org.schabi.newpipe.MainActivity; | import org.schabi.newpipe.MainActivity; | ||||||
| import org.schabi.newpipe.extractor.Info; | import org.schabi.newpipe.extractor.Info; | ||||||
|  |  | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.concurrent.TimeUnit; | ||||||
|  |  | ||||||
|  |  | ||||||
| public final class InfoCache { | public final class InfoCache { | ||||||
|     private static final boolean DEBUG = MainActivity.DEBUG; |     private static final boolean DEBUG = MainActivity.DEBUG; | ||||||
| @@ -37,9 +40,10 @@ public final class InfoCache { | |||||||
|      * Trim the cache to this size |      * Trim the cache to this size | ||||||
|      */ |      */ | ||||||
|     private static final int TRIM_CACHE_TO = 30; |     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) |     // TODO: Replace to one with timeout (like the one from guava) | ||||||
|     private static final LruCache<String, Info> lruCache = new LruCache<>(MAX_ITEMS_ON_CACHE); |     private static final LruCache<String, CacheData> lruCache = new LruCache<>(MAX_ITEMS_ON_CACHE); | ||||||
|  |  | ||||||
|     private InfoCache() { |     private InfoCache() { | ||||||
|         //no instance |         //no instance | ||||||
| @@ -52,28 +56,29 @@ public final class InfoCache { | |||||||
|     public Info getFromKey(int serviceId, @NonNull String url) { |     public Info getFromKey(int serviceId, @NonNull String url) { | ||||||
|         if (DEBUG) Log.d(TAG, "getFromKey() called with: serviceId = [" + serviceId + "], url = [" + url + "]"); |         if (DEBUG) Log.d(TAG, "getFromKey() called with: serviceId = [" + serviceId + "], url = [" + url + "]"); | ||||||
|         synchronized (lruCache) { |         synchronized (lruCache) { | ||||||
|             return lruCache.get(serviceId + url); |             return getInfo(lruCache, keyOf(serviceId, url)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void putInfo(@NonNull Info info) { |     public void putInfo(@NonNull Info info) { | ||||||
|         if (DEBUG) Log.d(TAG, "putInfo() called with: info = [" + info + "]"); |         if (DEBUG) Log.d(TAG, "putInfo() called with: info = [" + info + "]"); | ||||||
|         synchronized (lruCache) { |         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) { |     public void removeInfo(@NonNull Info info) { | ||||||
|         if (DEBUG) Log.d(TAG, "removeInfo() called with: info = [" + info + "]"); |         if (DEBUG) Log.d(TAG, "removeInfo() called with: info = [" + info + "]"); | ||||||
|         synchronized (lruCache) { |         synchronized (lruCache) { | ||||||
|             lruCache.remove(info.service_id + info.url); |             lruCache.remove(keyOf(info)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void removeInfo(int serviceId, @NonNull String url) { |     public void removeInfo(int serviceId, @NonNull String url) { | ||||||
|         if (DEBUG) Log.d(TAG, "removeInfo() called with: serviceId = [" + serviceId + "], url = [" + url + "]"); |         if (DEBUG) Log.d(TAG, "removeInfo() called with: serviceId = [" + serviceId + "], url = [" + url + "]"); | ||||||
|         synchronized (lruCache) { |         synchronized (lruCache) { | ||||||
|             lruCache.remove(serviceId + url); |             lruCache.remove(keyOf(serviceId, url)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -87,6 +92,7 @@ public final class InfoCache { | |||||||
|     public void trimCache() { |     public void trimCache() { | ||||||
|         if (DEBUG) Log.d(TAG, "trimCache() called"); |         if (DEBUG) Log.d(TAG, "trimCache() called"); | ||||||
|         synchronized (lruCache) { |         synchronized (lruCache) { | ||||||
|  |             removeStaleCache(lruCache); | ||||||
|             lruCache.trimToSize(TRIM_CACHE_TO); |             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<String, CacheData> cache) { | ||||||
|  |         for (Map.Entry<String, CacheData> 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<String, CacheData> 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; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,7 +6,9 @@ | |||||||
|     android:layout_width="match_parent" |     android:layout_width="match_parent" | ||||||
|     android:layout_height="wrap_content" |     android:layout_height="wrap_content" | ||||||
|     android:clickable="false" |     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"> | ||||||
|  |  | ||||||
|     <TextView |     <TextView | ||||||
|         android:id="@+id/itemTitleView" |         android:id="@+id/itemTitleView" | ||||||
| @@ -19,11 +21,11 @@ | |||||||
|         android:scrollHorizontally="true" |         android:scrollHorizontally="true" | ||||||
|         android:singleLine="true" |         android:singleLine="true" | ||||||
|         android:textAppearance="?android:attr/textAppearanceLarge" |         android:textAppearance="?android:attr/textAppearanceLarge" | ||||||
|         android:textSize="@dimen/video_item_search_title_text_size" |         android:textSize="@dimen/channel_item_detail_title_text_size" | ||||||
|         tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. "/> |         tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. "/> | ||||||
|  |  | ||||||
|     <TextView |     <TextView | ||||||
|         android:id="@+id/itemTypeView" |         android:id="@+id/itemAdditionalDetails" | ||||||
|         android:layout_width="wrap_content" |         android:layout_width="wrap_content" | ||||||
|         android:layout_height="wrap_content" |         android:layout_height="wrap_content" | ||||||
|         android:layout_below="@+id/itemTitleView" |         android:layout_below="@+id/itemTitleView" | ||||||
| @@ -32,5 +34,7 @@ | |||||||
|         android:singleLine="true" |         android:singleLine="true" | ||||||
|         android:textAppearance="?android:attr/textAppearanceSmall" |         android:textAppearance="?android:attr/textAppearanceSmall" | ||||||
|         android:textSize="@dimen/video_item_search_uploader_text_size" |         android:textSize="@dimen/video_item_search_uploader_text_size" | ||||||
|  |         android:visibility="gone" | ||||||
|  |         tools:visibility="visible" | ||||||
|         tools:text="TYPE" /> |         tools:text="TYPE" /> | ||||||
| </RelativeLayout> | </RelativeLayout> | ||||||
		Reference in New Issue
	
	Block a user
	 John Zhen Mo
					John Zhen Mo