mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-29 14:27:39 +00:00 
			
		
		
		
	git channel item running
This commit is contained in:
		| @@ -1,18 +1,24 @@ | ||||
| package org.schabi.newpipe; | ||||
|  | ||||
| import android.annotation.TargetApi; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.net.Uri; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.preference.PreferenceManager; | ||||
| import android.support.design.widget.CollapsingToolbarLayout; | ||||
| import android.support.design.widget.FloatingActionButton; | ||||
| import android.support.v4.content.ContextCompat; | ||||
| import android.support.v7.app.AppCompatActivity; | ||||
| import android.support.v7.widget.LinearLayoutManager; | ||||
| import android.support.v7.widget.RecyclerView; | ||||
| import android.support.v7.widget.Toolbar; | ||||
| import android.util.Log; | ||||
| import android.view.View; | ||||
| import android.view.Window; | ||||
| import android.view.WindowManager; | ||||
| import android.widget.ImageView; | ||||
| import android.widget.ProgressBar; | ||||
| import android.widget.Toast; | ||||
| @@ -34,6 +40,9 @@ import org.schabi.newpipe.report.ErrorActivity; | ||||
| import java.io.IOException; | ||||
| import java.util.Objects; | ||||
|  | ||||
| import static android.os.Build.VERSION.SDK; | ||||
| import static android.os.Build.VERSION.SDK_INT; | ||||
|  | ||||
| /** | ||||
|  * Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org> | ||||
|  * ChannelActivity.java is part of NewPipe. | ||||
| @@ -87,15 +96,17 @@ public class ChannelActivity extends AppCompatActivity { | ||||
|         channelUrl = i.getStringExtra(CHANNEL_URL); | ||||
|         serviceId = i.getIntExtra(SERVICE_ID, -1); | ||||
|  | ||||
|         setTranslucentStatusBar(getWindow()); | ||||
|  | ||||
|         infoListAdapter = new InfoListAdapter(this, rootView); | ||||
|         RecyclerView recyclerView = (RecyclerView) findViewById(R.id.channel_streams_view); | ||||
|         final LinearLayoutManager layoutManager = new LinearLayoutManager(this); | ||||
|         recyclerView.setLayoutManager(layoutManager); | ||||
|         recyclerView.setAdapter(infoListAdapter); | ||||
|         infoListAdapter.setOnStreamItemSelectedListener( | ||||
|         infoListAdapter.setOnStreamInfoItemSelectedListener( | ||||
|                 new InfoItemBuilder.OnInfoItemSelectedListener() { | ||||
|             @Override | ||||
|             public void selected(String url) { | ||||
|             public void selected(String url, int serviceId) { | ||||
|                 Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class); | ||||
|                 detailIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, url); | ||||
|                 detailIntent.putExtra( | ||||
| @@ -245,9 +256,13 @@ public class ChannelActivity extends AppCompatActivity { | ||||
|                     }); | ||||
|                     pe.printStackTrace(); | ||||
|                 } catch(ExtractionException ex) { | ||||
|                     String name = "none"; | ||||
|                     if(service != null) { | ||||
|                         name = service.getServiceInfo().name; | ||||
|                     } | ||||
|                     ErrorActivity.reportError(h, ChannelActivity.this, ex, VideoItemDetailFragment.class, null, | ||||
|                             ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_CHANNEL, | ||||
|                                     service.getServiceInfo().name, channelUrl, R.string.parsing_error)); | ||||
|                                     name, channelUrl, R.string.parsing_error)); | ||||
|                     h.post(new Runnable() { | ||||
|                         @Override | ||||
|                         public void run() { | ||||
| @@ -273,4 +288,28 @@ public class ChannelActivity extends AppCompatActivity { | ||||
|         channelExtractorThread.start(); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     // fix transparent statusbar fuckup (fuck google why can't they just leave something that worked | ||||
|     // as it is, and everyone gets happy) | ||||
|     public static void setTranslucentStatusBar(Window window) { | ||||
|         if (window == null) return; | ||||
|         int sdkInt = Build.VERSION.SDK_INT; | ||||
|         if (sdkInt >= Build.VERSION_CODES.LOLLIPOP) { | ||||
|             setTranslucentStatusBarLollipop(window); | ||||
|         } else if (sdkInt >= Build.VERSION_CODES.KITKAT) { | ||||
|             setTranslucentStatusBarKiKat(window); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @TargetApi(Build.VERSION_CODES.LOLLIPOP) | ||||
|     private static void setTranslucentStatusBarLollipop(Window window) { | ||||
|         window.setStatusBarColor( | ||||
|                 ContextCompat.getColor(window.getContext(), android.R.color.transparent)); | ||||
|     } | ||||
|  | ||||
|     @TargetApi(Build.VERSION_CODES.KITKAT) | ||||
|     private static void setTranslucentStatusBarKiKat(Window window) { | ||||
|         window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -543,7 +543,7 @@ public class VideoItemDetailFragment extends Fragment { | ||||
|         infoItemBuilder.setOnStreamInfoItemSelectedListener( | ||||
|                 new InfoItemBuilder.OnInfoItemSelectedListener() { | ||||
|             @Override | ||||
|             public void selected(String url) { | ||||
|             public void selected(String url, int serviceId) { | ||||
|                 openStreamUrl(url); | ||||
|             } | ||||
|         }); | ||||
|   | ||||
| @@ -26,17 +26,19 @@ public class ChannelInfoItem implements InfoItem { | ||||
|  | ||||
|     public int serviceId = -1; | ||||
|     public String channelName = ""; | ||||
|     public String thumbnailUrl = ""; | ||||
|     public String webPageUrl = ""; | ||||
|     public int subscriberCount = -1; | ||||
|     public String description = ""; | ||||
|     public long subscriberCount = -1; | ||||
|     public int videoAmount = -1; | ||||
|  | ||||
|     public InfoType infoType() { | ||||
|         return InfoType.CHANNEL; | ||||
|     } | ||||
|     public String getTitle() { | ||||
|         return ""; | ||||
|         return channelName; | ||||
|     } | ||||
|     public String getLink() { | ||||
|         return ""; | ||||
|         return webPageUrl; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -52,6 +52,16 @@ public class ChannelInfoItemCollector extends InfoItemCollector { | ||||
|             } catch (Exception e) { | ||||
|                 addError(e); | ||||
|             } | ||||
|             try { | ||||
|                 resultItem.thumbnailUrl = extractor.getThumbnailUrl(); | ||||
|             } catch (Exception e) { | ||||
|                 addError(e); | ||||
|             } | ||||
|             try { | ||||
|                 resultItem.description = extractor.getDescription(); | ||||
|             } catch (Exception e) { | ||||
|                 addError(e); | ||||
|             } | ||||
|  | ||||
|             addItem(resultItem); | ||||
|         } catch (Exception e) { | ||||
|   | ||||
| @@ -23,8 +23,10 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException; | ||||
|  */ | ||||
|  | ||||
| public interface ChannelInfoItemExtractor { | ||||
|     String getThumbnailUrl() throws ParsingException; | ||||
|     String getChannelName() throws ParsingException; | ||||
|     String getWebPageUrl() throws ParsingException; | ||||
|     int getSubscriberCount() throws ParsingException; | ||||
|     String getDescription() throws ParsingException; | ||||
|     long getSubscriberCount() throws ParsingException; | ||||
|     int getVideoAmount() throws ParsingException; | ||||
| } | ||||
|   | ||||
| @@ -39,7 +39,9 @@ public class SearchResult { | ||||
|                 .getSearchResult(); | ||||
|         if(result.resultList.isEmpty()) { | ||||
|             if(result.suggestion.isEmpty()) { | ||||
|                 throw new ExtractionException("Empty result despite no error"); | ||||
|                 if(result.errors.isEmpty()) { | ||||
|                     throw new ExtractionException("Empty result despite no error"); | ||||
|                 } | ||||
|             } else { | ||||
|                 // This is used as a fallback. Do not relay on it !!! | ||||
|                 throw new SearchEngine.NothingFoundException(result.suggestion); | ||||
|   | ||||
| @@ -136,8 +136,9 @@ public class YoutubeChannelExtractor extends ChannelExtractor { | ||||
|             if(!isAjaxPage) { | ||||
|                 Element el = doc.select("div[id=\"gh-banner\"]").first().select("style").first(); | ||||
|                 String cssContent = el.html(); | ||||
|                 String url = "https:" + Parser.matchGroup1("url\\(([^)]+)\\)", cssContent); | ||||
|                 if (url.contains("s.ytimg.com")) { | ||||
|                 String url = Parser.matchGroup1("url\\(([^)]+)\\)", cssContent); | ||||
|  | ||||
|                 if (url.contains("s.ytimg.com") || url.contains("default_banner")) { | ||||
|                     bannerUrl = null; | ||||
|                 } else { | ||||
|                     bannerUrl = url; | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| package org.schabi.newpipe.extractor.services.youtube; | ||||
|  | ||||
| import org.schabi.newpipe.extractor.Parser; | ||||
| import org.schabi.newpipe.extractor.channel.ChannelInfoItemExtractor; | ||||
| import org.schabi.newpipe.extractor.exceptions.ParsingException; | ||||
| import org.jsoup.nodes.Element; | ||||
| @@ -31,19 +32,48 @@ public class YoutubeChannelInfoItemExtractor implements ChannelInfoItemExtractor | ||||
|         this.el = el; | ||||
|     } | ||||
|  | ||||
|     public String getThumbnailUrl() throws ParsingException { | ||||
|         Element img = el.select("span[class*=\"yt-thumb-simple\"]").first() | ||||
|                 .select("img").first(); | ||||
|  | ||||
|         String url = img.attr("abs:src"); | ||||
|  | ||||
|         if(url.contains("gif")) { | ||||
|             url = img.attr("abs:data-thumb"); | ||||
|         } | ||||
|         return url; | ||||
|     } | ||||
|  | ||||
|     public String getChannelName() throws ParsingException { | ||||
|         return ""; | ||||
|         return el.select("a[class*=\"yt-uix-tile-link\"]").first() | ||||
|                 .text(); | ||||
|     } | ||||
|  | ||||
|     public String getWebPageUrl() throws ParsingException { | ||||
|         return ""; | ||||
|         return el.select("a[class*=\"yt-uix-tile-link\"]").first() | ||||
|                 .attr("abs:href"); | ||||
|     } | ||||
|  | ||||
|     public int getSubscriberCount() throws ParsingException { | ||||
|         return 0; | ||||
|     public long getSubscriberCount() throws ParsingException { | ||||
|         return Long.parseLong(el.select("span[class*=\"yt-subscriber-count\"]").first() | ||||
|                 .text().replaceAll("\\D+","")); | ||||
|     } | ||||
|  | ||||
|     public int getVideoAmount() throws ParsingException { | ||||
|         return 0; | ||||
|         Element metaEl = el.select("ul[class*=\"yt-lockup-meta-info\"]").first(); | ||||
|         if(metaEl == null) { | ||||
|             return 0; | ||||
|         } else { | ||||
|             return Integer.parseInt(metaEl.text().replaceAll("\\D+","")); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public String getDescription() throws ParsingException { | ||||
|         Element desEl = el.select("div[class*=\"yt-lockup-description\"]").first(); | ||||
|         if(desEl == null) { | ||||
|             return ""; | ||||
|         } else { | ||||
|             return desEl.text(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -109,7 +109,7 @@ public class YoutubeSearchEngine extends SearchEngine { | ||||
|                 collector.commit(new YoutubeChannelInfoItemExtractor(el)); | ||||
|             } else { | ||||
|                 //noinspection ConstantConditions | ||||
|                 throw new ExtractionException("unexpected element found:\"" + el + "\""); | ||||
|                 throw new ExtractionException("unexpected element found: \"" + el + "\""); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -32,12 +32,18 @@ import de.hdodenhof.circleimageview.CircleImageView; | ||||
| public class ChannelInfoItemHolder extends InfoItemHolder { | ||||
|     public final CircleImageView itemThumbnailView; | ||||
|     public final TextView itemChannelTitleView; | ||||
|     public final TextView itemSubscriberCountView; | ||||
|     public final TextView itemVideoCountView; | ||||
|     public final TextView itemChannelDescriptionView; | ||||
|     public final Button itemButton; | ||||
|  | ||||
|     ChannelInfoItemHolder(View v) { | ||||
|         super(v); | ||||
|         itemThumbnailView = (CircleImageView) v.findViewById(R.id.itemThumbnailView); | ||||
|         itemChannelTitleView = (TextView) v.findViewById(R.id.itemChannelTitleView); | ||||
|         itemSubscriberCountView = (TextView) v.findViewById(R.id.itemSubscriberCountView); | ||||
|         itemVideoCountView = (TextView) v.findViewById(R.id.itemVideoCountView); | ||||
|         itemChannelDescriptionView = (TextView) v.findViewById(R.id.itemChannelDescriptionView); | ||||
|         itemButton = (Button) v.findViewById(R.id.item_button); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -39,9 +39,17 @@ import org.schabi.newpipe.extractor.stream_info.StreamInfoItem; | ||||
|  | ||||
| public class InfoItemBuilder { | ||||
|  | ||||
|     final String viewsS; | ||||
|     final String videosS; | ||||
|     final String subsS; | ||||
|  | ||||
|     final String thousand; | ||||
|     final String million; | ||||
|     final String billion; | ||||
|  | ||||
|     private static final String TAG = InfoItemBuilder.class.toString(); | ||||
|     public interface OnInfoItemSelectedListener { | ||||
|         void selected(String url); | ||||
|         void selected(String url, int serviceId); | ||||
|     } | ||||
|  | ||||
|     private Activity activity = null; | ||||
| @@ -55,6 +63,12 @@ public class InfoItemBuilder { | ||||
|     public InfoItemBuilder(Activity a, View rootView) { | ||||
|         activity = a; | ||||
|         this.rootView = rootView; | ||||
|         viewsS = a.getString(R.string.views); | ||||
|         videosS = a.getString(R.string.videos); | ||||
|         subsS = a.getString(R.string.subscriber); | ||||
|         thousand = a.getString(R.string.short_thousand); | ||||
|         million = a.getString(R.string.short_million); | ||||
|         billion = a.getString(R.string.short_billion); | ||||
|     } | ||||
|  | ||||
|     public void setOnStreamInfoItemSelectedListener( | ||||
| @@ -146,32 +160,55 @@ public class InfoItemBuilder { | ||||
|         holder.itemButton.setOnClickListener(new View.OnClickListener() { | ||||
|             @Override | ||||
|             public void onClick(View view) { | ||||
|                 onStreamInfoItemSelectedListener.selected(info.webpage_url); | ||||
|                 onStreamInfoItemSelectedListener.selected(info.webpage_url, info.service_id); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private void buildChannelInfoItem(ChannelInfoItemHolder holder, final ChannelInfoItem info) { | ||||
|         holder.itemChannelTitleView.setText(info.getTitle()); | ||||
|         holder.itemSubscriberCountView.setText(shortSubscriber(info.subscriberCount) + " • "); | ||||
|         holder.itemVideoCountView.setText(info.videoAmount + " " + videosS); | ||||
|         holder.itemChannelDescriptionView.setText(info.description); | ||||
|  | ||||
|         holder.itemThumbnailView.setImageResource(R.drawable.buddy_channel_item); | ||||
|         if(info.thumbnailUrl != null && !info.thumbnailUrl.isEmpty()) { | ||||
|             imageLoader.displayImage(info.thumbnailUrl, | ||||
|                     holder.itemThumbnailView, | ||||
|                     displayImageOptions, | ||||
|                     new ImageErrorLoadingListener(activity, rootView, info.serviceId)); | ||||
|         } | ||||
|  | ||||
|         holder.itemButton.setOnClickListener(new View.OnClickListener() { | ||||
|             @Override | ||||
|             public void onClick(View view) { | ||||
|                 onChannelInfoItemSelectedListener.selected(info.getLink()); | ||||
|                 onChannelInfoItemSelectedListener.selected(info.getLink(), info.serviceId); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     public static String shortViewCount(Long viewCount){ | ||||
|     public String shortViewCount(Long viewCount){ | ||||
|         if(viewCount >= 1000000000){ | ||||
|             return Long.toString(viewCount/1000000000)+"B views"; | ||||
|             return Long.toString(viewCount/1000000000)+ billion + " " + viewsS; | ||||
|         }else if(viewCount>=1000000){ | ||||
|             return Long.toString(viewCount/1000000)+"M views"; | ||||
|             return Long.toString(viewCount/1000000)+ million + " " + viewsS; | ||||
|         }else if(viewCount>=1000){ | ||||
|             return Long.toString(viewCount/1000)+"K views"; | ||||
|             return Long.toString(viewCount/1000)+ thousand + " " + viewsS; | ||||
|         }else { | ||||
|             return Long.toString(viewCount)+" views"; | ||||
|             return Long.toString(viewCount)+ " " + viewsS; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public String shortSubscriber(Long viewCount){ | ||||
|         if(viewCount >= 1000000000){ | ||||
|             return Long.toString(viewCount/1000000000)+ billion + " " + subsS; | ||||
|         }else if(viewCount>=1000000){ | ||||
|             return Long.toString(viewCount/1000000)+ million + " " + subsS; | ||||
|         }else if(viewCount>=1000){ | ||||
|             return Long.toString(viewCount/1000)+ thousand + " " + subsS; | ||||
|         }else { | ||||
|             return Long.toString(viewCount)+ " " + subsS; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -44,9 +44,14 @@ public class InfoListAdapter extends RecyclerView.Adapter<InfoItemHolder> { | ||||
|         infoItemList = new Vector<>(); | ||||
|     } | ||||
|  | ||||
|     public void setOnStreamItemSelectedListener | ||||
|             (InfoItemBuilder.OnInfoItemSelectedListener onItemSelectedListener) { | ||||
|         infoItemBuilder.setOnStreamInfoItemSelectedListener(onItemSelectedListener); | ||||
|     public void setOnStreamInfoItemSelectedListener | ||||
|             (InfoItemBuilder.OnInfoItemSelectedListener listener) { | ||||
|         infoItemBuilder.setOnStreamInfoItemSelectedListener(listener); | ||||
|     } | ||||
|  | ||||
|     public void setOnChannelInfoItemSelectedListener | ||||
|             (InfoItemBuilder.OnInfoItemSelectedListener listener) { | ||||
|         infoItemBuilder.setOnChannelInfoItemSelectedListener(listener); | ||||
|     } | ||||
|  | ||||
|     public void addInfoItemList(List<InfoItem> videos) { | ||||
|   | ||||
| @@ -19,6 +19,7 @@ import android.view.inputmethod.InputMethodManager; | ||||
| import android.widget.ProgressBar; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import org.schabi.newpipe.ChannelActivity; | ||||
| import org.schabi.newpipe.ReCaptchaActivity; | ||||
| import org.schabi.newpipe.extractor.NewPipe; | ||||
| import org.schabi.newpipe.extractor.search.SearchEngine; | ||||
| @@ -216,13 +217,19 @@ public class SearchInfoItemFragment extends Fragment { | ||||
|  | ||||
|         infoListAdapter = new InfoListAdapter(getActivity(), | ||||
|                 getActivity().findViewById(android.R.id.content)); | ||||
|         infoListAdapter.setOnStreamItemSelectedListener( | ||||
|         infoListAdapter.setOnStreamInfoItemSelectedListener( | ||||
|                 new InfoItemBuilder.OnInfoItemSelectedListener() { | ||||
|             @Override | ||||
|             public void selected(String url) { | ||||
|             public void selected(String url, int serviceId) { | ||||
|                 startDetailActivity(url); | ||||
|             } | ||||
|         }); | ||||
|         infoListAdapter.setOnChannelInfoItemSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener() { | ||||
|             @Override | ||||
|             public void selected(String url, int serviceId) { | ||||
|                 startChannelActivity(url, serviceId); | ||||
|             } | ||||
|         }); | ||||
|         recyclerView.setAdapter(infoListAdapter); | ||||
|         recyclerView.clearOnScrollListeners(); | ||||
|         recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { | ||||
| @@ -254,6 +261,13 @@ public class SearchInfoItemFragment extends Fragment { | ||||
|         getActivity().startActivity(i); | ||||
|     } | ||||
|  | ||||
|     private void startChannelActivity(String url, int serviceId) { | ||||
|         Intent i = new Intent(getActivity(), ChannelActivity.class); | ||||
|         i.putExtra(ChannelActivity.CHANNEL_URL, url); | ||||
|         i.putExtra(ChannelActivity.SERVICE_ID, serviceId); | ||||
|         startActivity(i); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onStart() { | ||||
|         super.onStart(); | ||||
|   | ||||
| @@ -117,6 +117,7 @@ public class SearchWorker { | ||||
|  | ||||
|                 // look for errors during extraction | ||||
|                 // soft errors: | ||||
|                 View rootView = a.findViewById(android.R.id.content); | ||||
|                 if(result != null && | ||||
|                         !result.errors.isEmpty()) { | ||||
|                     Log.e(TAG, "OCCURRED ERRORS DURING SEARCH EXTRACTION:"); | ||||
| @@ -125,11 +126,17 @@ public class SearchWorker { | ||||
|                         Log.e(TAG, "------"); | ||||
|                     } | ||||
|  | ||||
|                     View rootView = a.findViewById(android.R.id.content); | ||||
|                     ErrorActivity.reportError(h, a, result.errors, null, rootView, | ||||
|                             ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED, | ||||
|                             serviceName, query, R.string.light_parsing_error)); | ||||
|  | ||||
|                     if(result.resultList.isEmpty()&& !result.errors.isEmpty()) { | ||||
|                         // if it compleatly failes dont show snackbar, instead show error directlry | ||||
|                         ErrorActivity.reportError(h, a, result.errors, null, null, | ||||
|                                 ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED, | ||||
|                                         serviceName, query, R.string.parsing_error)); | ||||
|                     } else { | ||||
|                         // if it partly show snackbar | ||||
|                         ErrorActivity.reportError(h, a, result.errors, null, rootView, | ||||
|                                 ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED, | ||||
|                                         serviceName, query, R.string.light_parsing_error)); | ||||
|                     } | ||||
|                 } | ||||
|                 // hard errors: | ||||
|             } catch (ReCaptchaException e) { | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
|  | ||||
| <FrameLayout | ||||
|     android:id="@+id/item_main_layout" | ||||
| <FrameLayout android:id="@+id/item_main_layout" | ||||
|     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" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto"> | ||||
|     <LinearLayout | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="wrap_content" > | ||||
| @@ -46,13 +46,35 @@ | ||||
|                     android:layout_width="fill_parent" | ||||
|                     android:layout_height="0dp" | ||||
|                     android:textAppearance="?android:attr/textAppearanceLarge" | ||||
|                     android:textSize="@dimen/video_item_search_title_text_size"/> | ||||
|                     android:textSize="@dimen/channel_item_detail_title_text_size"/> | ||||
|  | ||||
|                 <TextView android:id="@+id/itemChannelDescriptionView" | ||||
|                     android:layout_weight="2" | ||||
|                     android:layout_width="fill_parent" | ||||
|                     android:layout_height="0dp" | ||||
|                     android:textAppearance="?android:attr/textAppearanceSmall" | ||||
|                     android:textSize="@dimen/video_item_search_uploader_text_size"/> | ||||
|  | ||||
|                 <LinearLayout | ||||
|                     android:orientation="horizontal" | ||||
|                     android:layout_width="match_parent" | ||||
|                     android:layout_height="wrap_content"> | ||||
|  | ||||
|                     <TextView android:id="@+id/itemSubscriberCountView" | ||||
|                         android:layout_width="wrap_content" | ||||
|                         android:layout_height="wrap_content" | ||||
|                         android:singleLine="true" | ||||
|                         android:textAppearance="?android:attr/textAppearanceSmall" | ||||
|                         android:textSize="@dimen/video_item_search_upload_date_text_size" | ||||
|                         android:text="1000 subs"/> | ||||
|  | ||||
|                     <TextView android:id="@+id/itemVideoCountView" | ||||
|                         android:layout_width="wrap_content" | ||||
|                         android:layout_height="wrap_content" | ||||
|                         android:singleLine="true" | ||||
|                         android:textAppearance="?android:attr/textAppearanceSmall" | ||||
|                         android:textSize="@dimen/video_item_search_upload_date_text_size" | ||||
|                         android:text="1000 vids"/> | ||||
|                 </LinearLayout> | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -138,6 +138,12 @@ | ||||
|  | ||||
|     <string name="switch_mode">Zwischen Liste und Gitter umschalten</string> | ||||
|  | ||||
|     <string name="videos">Videos</string> | ||||
|     <string name="subscriber">Abonenten</string> | ||||
|     <string name="views">Aufrufe</string> | ||||
|     <string name="short_thousand">Tsd.</string> | ||||
|     <string name="short_million">Mio.</string> | ||||
|     <string name="short_billion">Mrd.</string> | ||||
|  | ||||
|     <string name="msg_url">Download-URL</string> | ||||
|     <string name="msg_name">Dateiname</string> | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|  | ||||
|     <!-- Video Item Search View Dimensions--> | ||||
|     <!-- Text Size --> | ||||
|     <dimen name="channel_item_detail_title_text_size">33sp</dimen> | ||||
|     <dimen name="video_item_search_title_text_size">22sp</dimen> | ||||
|     <dimen name="video_item_search_duration_text_size">16sp</dimen> | ||||
|     <dimen name="video_item_search_uploader_text_size">18sp</dimen> | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|  | ||||
|     <!-- Video Item Search View Dimensions--> | ||||
|     <!-- Text Size --> | ||||
|     <dimen name="channel_item_detail_title_text_size">21sp</dimen> | ||||
|     <dimen name="video_item_search_title_text_size">14sp</dimen> | ||||
|     <dimen name="video_item_search_duration_text_size">11sp</dimen> | ||||
|     <dimen name="video_item_search_uploader_text_size">12sp</dimen> | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|  | ||||
|     <!-- Video Item Detail View Dimensions--> | ||||
|     <!-- Text Size --> | ||||
|     <dimen name="channel_item_detail_title_text_size">30sp</dimen> | ||||
|     <dimen name="video_item_detail_title_text_size">20sp</dimen> | ||||
|     <dimen name="video_item_detail_views_text_size">16sp</dimen> | ||||
|     <dimen name="video_item_detail_likes_text_size">14sp</dimen> | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| <resources> | ||||
|     <!-- Video Item Search View Dimensions--> | ||||
|     <!-- Text Size --> | ||||
|     <dimen name="channel_item_detail_title_text_size">21sp</dimen> | ||||
|     <dimen name="video_item_search_title_text_size">14sp</dimen> | ||||
|     <dimen name="video_item_search_duration_text_size">11sp</dimen> | ||||
|     <dimen name="video_item_search_uploader_text_size">12sp</dimen> | ||||
|   | ||||
| @@ -147,6 +147,12 @@ | ||||
|     <string name="storage_permission_denied">Permission to access storage was denied</string> | ||||
|     <string name="use_exoplayer_title">Use ExoPlayer</string> | ||||
|     <string name="use_exoplayer_summary">Experimental</string> | ||||
|     <string name="videos">videos</string> | ||||
|     <string name="subscriber">subscriber</string> | ||||
|     <string name="views">views</string> | ||||
|     <string name="short_thousand">T</string> | ||||
|     <string name="short_million">M</string> | ||||
|     <string name="short_billion">B</string> | ||||
|  | ||||
|     <!-- Missions --> | ||||
|     <string name="start">Start</string> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Christian Schabesberger
					Christian Schabesberger