From 08127e5806c2234034af9b61650b8f7f9aae3b9d Mon Sep 17 00:00:00 2001
From: Ritvik Saraf <13ritvik@gmail.com>
Date: Mon, 3 Sep 2018 04:52:59 +0530
Subject: [PATCH] added basic/crappy comments support

---
 app/build.gradle                              |   2 +-
 .../java/org/schabi/newpipe/Downloader.java   | 101 +++++++-
 .../fragments/detail/VideoDetailFragment.java | 222 +++++++++++++++---
 .../fragments/list/BaseListFragment.java      |   8 +
 .../newpipe/info_list/InfoItemBuilder.java    |  14 ++
 .../newpipe/info_list/InfoListAdapter.java    |   5 +
 .../holder/CommentsInfoItemHolder.java        |  53 +++++
 .../holder/CommentsMiniInfoItemHolder.java    |  92 ++++++++
 .../schabi/newpipe/util/ExtractorHelper.java  |  34 +--
 .../main/res/layout/fragment_video_detail.xml | 206 ++++++++++------
 .../main/res/layout/list_comments_item.xml    | 112 +++++++++
 .../res/layout/list_comments_mini_item.xml    | 112 +++++++++
 app/src/main/res/values/settings_keys.xml     |   1 +
 app/src/main/res/values/strings.xml           |   1 +
 14 files changed, 834 insertions(+), 129 deletions(-)
 create mode 100644 app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsInfoItemHolder.java
 create mode 100644 app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java
 create mode 100644 app/src/main/res/layout/list_comments_item.xml
 create mode 100644 app/src/main/res/layout/list_comments_mini_item.xml

diff --git a/app/build.gradle b/app/build.gradle
index 4ae9f0fb7..d409532bb 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -55,7 +55,7 @@ dependencies {
         exclude module: 'support-annotations'
     }
 
-    implementation 'com.github.TeamNewPipe:NewPipeExtractor:217d13b1028'
+    implementation 'com.github.yausername:NewPipeExtractor:5242bda'
 
     testImplementation 'junit:junit:4.12'
     testImplementation 'org.mockito:mockito-core:2.8.9'
diff --git a/app/src/main/java/org/schabi/newpipe/Downloader.java b/app/src/main/java/org/schabi/newpipe/Downloader.java
index 17dc5859d..d51d31e11 100644
--- a/app/src/main/java/org/schabi/newpipe/Downloader.java
+++ b/app/src/main/java/org/schabi/newpipe/Downloader.java
@@ -3,17 +3,22 @@ package org.schabi.newpipe;
 import android.support.annotation.Nullable;
 import android.text.TextUtils;
 
+import org.schabi.newpipe.extractor.DownloadResponse;
 import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.Serializable;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
+import okhttp3.MediaType;
 import okhttp3.OkHttpClient;
 import okhttp3.Request;
+import okhttp3.RequestBody;
 import okhttp3.Response;
 import okhttp3.ResponseBody;
 
@@ -137,13 +142,16 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
 
     private ResponseBody getBody(String siteUrl, Map<String, String> customProperties) throws IOException, ReCaptchaException {
         final Request.Builder requestBuilder = new Request.Builder()
-                .method("GET", null).url(siteUrl)
-                .addHeader("User-Agent", USER_AGENT);
+                .method("GET", null).url(siteUrl);
 
         for (Map.Entry<String, String> header : customProperties.entrySet()) {
             requestBuilder.addHeader(header.getKey(), header.getValue());
         }
 
+        if (!customProperties.containsKey("User-Agent")) {
+            requestBuilder.header("User-Agent", USER_AGENT);
+        }
+
         if (!TextUtils.isEmpty(mCookies)) {
             requestBuilder.addHeader("Cookie", mCookies);
         }
@@ -175,4 +183,91 @@ public class Downloader implements org.schabi.newpipe.extractor.Downloader {
     public String download(String siteUrl) throws IOException, ReCaptchaException {
         return download(siteUrl, Collections.emptyMap());
     }
-}
+
+
+    @Override
+    public DownloadResponse get(String siteUrl, Map<String, List<String>> requestHeaders) throws IOException, ReCaptchaException {
+        final Request.Builder requestBuilder = new Request.Builder()
+                .method("GET", null).url(siteUrl);
+
+        // set custom headers in request
+        for (Map.Entry<String, List<String>> pair : requestHeaders.entrySet()) {
+            for(String value : pair.getValue()){
+                requestBuilder.addHeader(pair.getKey(), value);
+            }
+        }
+
+        if (!requestHeaders.containsKey("User-Agent")) {
+            requestBuilder.header("User-Agent", USER_AGENT);
+        }
+
+        if (!TextUtils.isEmpty(mCookies)) {
+            requestBuilder.addHeader("Cookie", mCookies);
+        }
+
+        final Request request = requestBuilder.build();
+        final Response response = client.newCall(request).execute();
+        final ResponseBody body = response.body();
+
+        if (response.code() == 429) {
+            throw new ReCaptchaException("reCaptcha Challenge requested");
+        }
+
+        if (body == null) {
+            response.close();
+            return null;
+        }
+
+        return new DownloadResponse(body.string(), response.headers().toMultimap());
+    }
+
+    @Override
+    public DownloadResponse get(String siteUrl) throws IOException, ReCaptchaException {
+        return get(siteUrl, Collections.emptyMap());
+    }
+
+    @Override
+    public DownloadResponse post(String siteUrl, String requestBody, Map<String, List<String>> requestHeaders) throws IOException, ReCaptchaException {
+
+        if(null == requestHeaders.get("Content-Type") || requestHeaders.get("Content-Type").isEmpty()){
+            // content type header is required. maybe throw an exception here
+            return null;
+        }
+
+        String contentType = requestHeaders.get("Content-Type").get(0);
+
+        RequestBody okRequestBody = RequestBody.create(MediaType.parse(contentType), requestBody);
+        final Request.Builder requestBuilder = new Request.Builder()
+                .method("POST",  okRequestBody).url(siteUrl);
+
+        // set custom headers in request
+        for (Map.Entry<String, List<String>> pair : requestHeaders.entrySet()) {
+            for(String value : pair.getValue()){
+                requestBuilder.addHeader(pair.getKey(), value);
+            }
+        }
+
+        if (!requestHeaders.containsKey("User-Agent")) {
+            requestBuilder.header("User-Agent", USER_AGENT);
+        }
+
+        if (!TextUtils.isEmpty(mCookies)) {
+            requestBuilder.addHeader("Cookie", mCookies);
+        }
+
+        final Request request = requestBuilder.build();
+        final Response response = client.newCall(request).execute();
+        final ResponseBody body = response.body();
+
+        if (response.code() == 429) {
+            throw new ReCaptchaException("reCaptcha Challenge requested");
+        }
+
+        if (body == null) {
+            response.close();
+            return null;
+        }
+
+        return new DownloadResponse(body.string(), response.headers().toMultimap());
+    }
+}
\ No newline at end of file
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 c726f8cee..cbea6803e 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
@@ -40,6 +40,7 @@ import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 import android.widget.Spinner;
+import android.widget.TabHost;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -53,6 +54,7 @@ import org.schabi.newpipe.ReCaptchaActivity;
 import org.schabi.newpipe.download.DownloadDialog;
 import org.schabi.newpipe.extractor.InfoItem;
 import org.schabi.newpipe.extractor.NewPipe;
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
 import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
 import org.schabi.newpipe.extractor.exceptions.ParsingException;
 import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor;
@@ -64,19 +66,17 @@ import org.schabi.newpipe.extractor.stream.StreamType;
 import org.schabi.newpipe.extractor.stream.VideoStream;
 import org.schabi.newpipe.fragments.BackPressable;
 import org.schabi.newpipe.fragments.BaseStateFragment;
-import org.schabi.newpipe.local.history.HistoryRecordManager;
-import org.schabi.newpipe.report.ErrorActivity;
-import org.schabi.newpipe.util.StreamItemAdapter;
-import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper;
-import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
 import org.schabi.newpipe.info_list.InfoItemBuilder;
 import org.schabi.newpipe.info_list.InfoItemDialog;
+import org.schabi.newpipe.local.dialog.PlaylistAppendDialog;
+import org.schabi.newpipe.local.history.HistoryRecordManager;
 import org.schabi.newpipe.player.MainVideoPlayer;
 import org.schabi.newpipe.player.PopupVideoPlayer;
 import org.schabi.newpipe.player.helper.PlayerHelper;
 import org.schabi.newpipe.player.old.PlayVideoActivity;
 import org.schabi.newpipe.player.playqueue.PlayQueue;
 import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
+import org.schabi.newpipe.report.ErrorActivity;
 import org.schabi.newpipe.report.UserAction;
 import org.schabi.newpipe.util.Constants;
 import org.schabi.newpipe.util.ExtractorHelper;
@@ -87,6 +87,8 @@ import org.schabi.newpipe.util.Localization;
 import org.schabi.newpipe.util.NavigationHelper;
 import org.schabi.newpipe.util.OnClickGesture;
 import org.schabi.newpipe.util.PermissionHelper;
+import org.schabi.newpipe.util.StreamItemAdapter;
+import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper;
 import org.schabi.newpipe.util.ThemeHelper;
 
 import java.io.Serializable;
@@ -114,6 +116,8 @@ public class VideoDetailFragment
 
     // Amount of videos to show on start
     private static final int INITIAL_RELATED_VIDEOS = 8;
+    // Amount of comments to show on start
+    private static final int INITIAL_COMMENTS = 8;
 
     private InfoItemBuilder infoItemBuilder = null;
 
@@ -121,18 +125,24 @@ public class VideoDetailFragment
     private static final int RELATED_STREAMS_UPDATE_FLAG = 0x1;
     private static final int RESOLUTIONS_MENU_UPDATE_FLAG = 0x2;
     private static final int TOOLBAR_ITEMS_UPDATE_FLAG = 0x4;
+    private static final int COMMENTS_UPDATE_FLAG = 0x4;
 
     private boolean autoPlayEnabled;
     private boolean showRelatedStreams;
+    private boolean showComments;
     private boolean wasRelatedStreamsExpanded = false;
 
-    @State protected int serviceId = Constants.NO_SERVICE_ID;
-    @State protected String name;
-    @State protected String url;
+    @State
+    protected int serviceId = Constants.NO_SERVICE_ID;
+    @State
+    protected String name;
+    @State
+    protected String url;
 
     private StreamInfo currentInfo;
     private Disposable currentWorker;
-    @NonNull private CompositeDisposable disposables = new CompositeDisposable();
+    @NonNull
+    private CompositeDisposable disposables = new CompositeDisposable();
 
     private List<VideoStream> sortedVideoStreams;
     private int selectedVideoStreamIndex = -1;
@@ -183,6 +193,16 @@ public class VideoDetailFragment
     private LinearLayout relatedStreamsView;
     private ImageButton relatedStreamExpandButton;
 
+    private LinearLayout commentsRootLayout;
+    private LinearLayout commentsView;
+    private ImageButton commentsExpandButton;
+    private Disposable commentsDisposable;
+
+    private TabHost tabHost;
+    private static final String COMMENTS_TAB_TAG = "CommentsTab";
+    private static final String RELATED_TAB_TAG = "RelatedTab";
+
+
 
     /*////////////////////////////////////////////////////////////////////////*/
 
@@ -197,12 +217,17 @@ public class VideoDetailFragment
     //////////////////////////////////////////////////////////////////////////*/
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
+    public void
+    onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setHasOptionsMenu(true);
 
         showRelatedStreams = PreferenceManager.getDefaultSharedPreferences(activity)
                 .getBoolean(getString(R.string.show_next_video_key), true);
+
+        showComments = PreferenceManager.getDefaultSharedPreferences(activity)
+                .getBoolean(getString(R.string.show_comments), true);
+
         PreferenceManager.getDefaultSharedPreferences(activity)
                 .registerOnSharedPreferenceChangeListener(this);
     }
@@ -224,14 +249,17 @@ public class VideoDetailFragment
 
         if (updateFlags != 0) {
             if (!isLoading.get() && currentInfo != null) {
-                if ((updateFlags & RELATED_STREAMS_UPDATE_FLAG) != 0) initRelatedVideos(currentInfo);
+                if ((updateFlags & RELATED_STREAMS_UPDATE_FLAG) != 0)
+                    initRelatedVideos(currentInfo);
                 if ((updateFlags & RESOLUTIONS_MENU_UPDATE_FLAG) != 0) setupActionBar(currentInfo);
+                if ((updateFlags & COMMENTS_UPDATE_FLAG) != 0) initComments(currentInfo);
             }
 
             if ((updateFlags & TOOLBAR_ITEMS_UPDATE_FLAG) != 0
                     && menu != null) {
                 updateMenuItemVisibility();
             }
+
             updateFlags = 0;
         }
 
@@ -288,6 +316,9 @@ public class VideoDetailFragment
             updateFlags |= RESOLUTIONS_MENU_UPDATE_FLAG;
         } else if (key.equals(getString(R.string.show_play_with_kodi_key))) {
             updateFlags |= TOOLBAR_ITEMS_UPDATE_FLAG;
+        } else if (key.equals(R.string.show_comments)) {
+            showComments = sharedPreferences.getBoolean(key, true);
+            updateFlags |= COMMENTS_UPDATE_FLAG;
         }
     }
 
@@ -312,7 +343,8 @@ public class VideoDetailFragment
         }
 
         if (!isLoading.get() && currentInfo != null && isVisible()) {
-            outState.putSerializable(INFO_KEY, currentInfo);
+            //TODO fix this. it should not be commented
+            //outState.putSerializable(INFO_KEY, currentInfo);
         }
 
         outState.putSerializable(STACK_KEY, stack);
@@ -392,6 +424,9 @@ public class VideoDetailFragment
             case R.id.detail_related_streams_expand:
                 toggleExpandRelatedVideos(currentInfo);
                 break;
+            case R.id.detail_comments_expand:
+                toggleExpandComments(currentInfo);
+                break;
         }
     }
 
@@ -452,6 +487,46 @@ public class VideoDetailFragment
                         ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.collapse)));
     }
 
+
+    private void toggleExpandComments(StreamInfo info) {
+        if (DEBUG) Log.d(TAG, "toggleExpandComments() called with: info = [" + info + "]");
+        if (!showComments) return;
+
+        int initialCount = INITIAL_COMMENTS;
+
+        if (commentsView.getChildCount() > initialCount && commentsView.getChildCount() >= info.getComments().size() && !info.hasMoreComments()) {
+            commentsView.removeViews(initialCount,
+                    commentsView.getChildCount() - (initialCount));
+            commentsExpandButton.setImageDrawable(ContextCompat.getDrawable(
+                    activity, ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.expand)));
+            return;
+        }
+
+        //Log.d(TAG, "toggleExpandRelatedVideos() called with: info = [" + info + "], from = [" + INITIAL_RELATED_VIDEOS + "]");
+        int currentCount = commentsView.getChildCount();
+        for (int i = currentCount; i < info.getComments().size(); i++) {
+            CommentsInfoItem item = info.getComments().get(i);
+            //Log.d(TAG, "i = " + i);
+            commentsView.addView(infoItemBuilder.buildView(commentsView, item));
+        }
+
+        if (info.hasMoreComments()) {
+            loadMoreComments(info);
+        } else {
+            commentsExpandButton.setImageDrawable(
+                    ContextCompat.getDrawable(activity,
+                            ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.collapse)));
+        }
+    }
+
+    private void loadMoreComments(StreamInfo info) {
+        if (commentsDisposable != null) commentsDisposable.dispose();
+
+        commentsDisposable = Single.fromCallable(() -> {
+            StreamInfo.loadMoreComments(info);
+            return info.getComments();
+        }).subscribeOn(Schedulers.io()).doOnError(e -> info.addError(e)).subscribe();
+    }
     /*//////////////////////////////////////////////////////////////////////////
     // Init
     //////////////////////////////////////////////////////////////////////////*/
@@ -498,14 +573,37 @@ public class VideoDetailFragment
         uploaderTextView = rootView.findViewById(R.id.detail_uploader_text_view);
         uploaderThumb = rootView.findViewById(R.id.detail_uploader_thumbnail_view);
 
+        tabHost = (TabHost) rootView.findViewById(R.id.tab_host);
+        tabHost.setup();
+
+        TabHost.TabSpec commentsTab = tabHost.newTabSpec(COMMENTS_TAB_TAG);
+        commentsTab.setContent(R.id.detail_comments_root_layout);
+        commentsTab.setIndicator(getString(R.string.comments));
+
+
+        TabHost.TabSpec relatedVideosTab = tabHost.newTabSpec(RELATED_TAB_TAG);
+        relatedVideosTab.setContent(R.id.detail_related_streams_root_layout);
+        relatedVideosTab.setIndicator(getString(R.string.next_video_title));
+
+        tabHost.addTab(commentsTab);
+        tabHost.addTab(relatedVideosTab);
+
+        //show comments tab by default
+        tabHost.setCurrentTabByTag(COMMENTS_TAB_TAG);
+
         relatedStreamRootLayout = rootView.findViewById(R.id.detail_related_streams_root_layout);
         nextStreamTitle = rootView.findViewById(R.id.detail_next_stream_title);
         relatedStreamsView = rootView.findViewById(R.id.detail_related_streams_view);
-
         relatedStreamExpandButton = rootView.findViewById(R.id.detail_related_streams_expand);
 
+        commentsRootLayout = rootView.findViewById(R.id.detail_comments_root_layout);
+        commentsView = rootView.findViewById(R.id.detail_comments_view);
+        commentsExpandButton = rootView.findViewById(R.id.detail_comments_expand);
+
         infoItemBuilder = new InfoItemBuilder(activity);
         setHeightThumbnail();
+
+
     }
 
     @Override
@@ -532,6 +630,7 @@ public class VideoDetailFragment
         detailControlsDownload.setOnClickListener(this);
         detailControlsDownload.setOnLongClickListener(this);
         relatedStreamExpandButton.setOnClickListener(this);
+        commentsExpandButton.setOnClickListener(this);
 
         detailControlsBackground.setLongClickable(true);
         detailControlsPopup.setLongClickable(true);
@@ -622,7 +721,7 @@ public class VideoDetailFragment
             relatedStreamsView.addView(
                     infoItemBuilder.buildView(relatedStreamsView, info.getNextVideo()));
             relatedStreamsView.addView(getSeparatorView());
-            relatedStreamRootLayout.setVisibility(View.VISIBLE);
+            showRelatedStreamsIfSelected();
         } else nextStreamTitle.setVisibility(View.GONE);
 
         if (info.getRelatedStreams() != null
@@ -639,7 +738,7 @@ public class VideoDetailFragment
             }
             //if (DEBUG) Log.d(TAG, "Total time " + ((System.nanoTime() - first) / 1000000L) + "ms");
 
-            relatedStreamRootLayout.setVisibility(View.VISIBLE);
+            showRelatedStreamsIfSelected();
             relatedStreamExpandButton.setVisibility(View.VISIBLE);
 
             relatedStreamExpandButton.setImageDrawable(ContextCompat.getDrawable(
@@ -648,6 +747,47 @@ public class VideoDetailFragment
             if (info.getNextVideo() == null) relatedStreamRootLayout.setVisibility(View.GONE);
             relatedStreamExpandButton.setVisibility(View.GONE);
         }
+
+    }
+
+    private void showRelatedStreamsIfSelected() {
+        if (tabHost.getCurrentTabTag().contentEquals(RELATED_TAB_TAG)) {
+            relatedStreamRootLayout.setVisibility(View.VISIBLE);
+        }
+    }
+
+    private void initComments(StreamInfo info) {
+        if (commentsView.getChildCount() > 0) commentsView.removeAllViews();
+
+        if (info.getComments() != null
+                && !info.getComments().isEmpty() && showComments) {
+            //long first = System.nanoTime(), each;
+            int to = info.getComments().size() >= INITIAL_RELATED_VIDEOS
+                    ? INITIAL_RELATED_VIDEOS
+                    : info.getComments().size();
+            for (int i = 0; i < to; i++) {
+                InfoItem item = info.getComments().get(i);
+                //each = System.nanoTime();
+                commentsView.addView(infoItemBuilder.buildView(commentsView, item));
+                //if (DEBUG) Log.d(TAG, "each took " + ((System.nanoTime() - each) / 1000000L) + "ms");
+            }
+            //if (DEBUG) Log.d(TAG, "Total time " + ((System.nanoTime() - first) / 1000000L) + "ms");
+
+            showCommentsIfSelected();
+            commentsExpandButton.setVisibility(View.VISIBLE);
+
+            commentsExpandButton.setImageDrawable(ContextCompat.getDrawable(
+                    activity, ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.expand)));
+        } else {
+            commentsRootLayout.setVisibility(View.GONE);
+        }
+
+    }
+
+    private void showCommentsIfSelected() {
+        if (tabHost.getCurrentTabTag().contentEquals(COMMENTS_TAB_TAG)) {
+            commentsRootLayout.setVisibility(View.VISIBLE);
+        }
     }
 
     /*//////////////////////////////////////////////////////////////////////////
@@ -682,7 +822,7 @@ public class VideoDetailFragment
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        if(isLoading.get()) {
+        if (isLoading.get()) {
             // if is still loading block menu
             return true;
         }
@@ -706,7 +846,7 @@ public class VideoDetailFragment
                     NavigationHelper.playWithKore(activity, Uri.parse(
                             url.replace("https", "http")));
                 } catch (Exception e) {
-                    if(DEBUG) Log.i(TAG, "Failed to start kore", e);
+                    if (DEBUG) Log.i(TAG, "Failed to start kore", e);
                     showInstallKoreDialog(activity);
                 }
                 return true;
@@ -720,7 +860,8 @@ public class VideoDetailFragment
         builder.setMessage(R.string.kore_not_found)
                 .setPositiveButton(R.string.install, (DialogInterface dialog, int which) ->
                         NavigationHelper.installKore(context))
-                .setNegativeButton(R.string.cancel, (DialogInterface dialog, int which) -> {});
+                .setNegativeButton(R.string.cancel, (DialogInterface dialog, int which) -> {
+                });
         builder.create().show();
     }
 
@@ -823,7 +964,8 @@ public class VideoDetailFragment
     }
 
     public void prepareAndHandleInfo(final StreamInfo info, boolean scrollToTop) {
-        if (DEBUG) Log.d(TAG, "prepareAndHandleInfo() called with: info = [" + info + "], scrollToTop = [" + scrollToTop + "]");
+        if (DEBUG)
+            Log.d(TAG, "prepareAndHandleInfo() called with: info = [" + info + "], scrollToTop = [" + scrollToTop + "]");
 
         setInitialData(info.getServiceId(), info.getOriginalUrl(), info.getName());
         pushToStack(serviceId, url, name);
@@ -1057,7 +1199,7 @@ public class VideoDetailFragment
                 .setInterpolator(new FastOutSlowInInterpolator())
                 .start();
 
-        if (showRelatedStreams) {
+        if (showRelatedStreams && tabHost.getCurrentTabTag().contentEquals(RELATED_TAB_TAG)) {
             relatedStreamRootLayout.animate().setListener(null).cancel();
             relatedStreamRootLayout.setAlpha(0f);
             relatedStreamRootLayout.setTranslationY(translationY);
@@ -1070,6 +1212,20 @@ public class VideoDetailFragment
                     .setInterpolator(new FastOutSlowInInterpolator())
                     .start();
         }
+
+        if (showComments && tabHost.getCurrentTabTag().contentEquals(COMMENTS_TAB_TAG)) {
+            commentsRootLayout.animate().setListener(null).cancel();
+            commentsRootLayout.setAlpha(0f);
+            commentsRootLayout.setTranslationY(translationY);
+            commentsRootLayout.setVisibility(View.VISIBLE);
+            commentsRootLayout.animate()
+                    .alpha(1f)
+                    .translationY(0)
+                    .setStartDelay((long) (duration * .8f) + delay)
+                    .setDuration(duration)
+                    .setInterpolator(new FastOutSlowInInterpolator())
+                    .start();
+        }
     }
 
     protected void setInitialData(int serviceId, String url, String name) {
@@ -1204,6 +1360,8 @@ public class VideoDetailFragment
         setupActionBar(info);
         initThumbnailViews(info);
         initRelatedVideos(info);
+        initComments(info);
+
         if (wasRelatedStreamsExpanded) {
             toggleExpandRelatedVideos(currentInfo);
             wasRelatedStreamsExpanded = false;
@@ -1246,19 +1404,19 @@ public class VideoDetailFragment
 
 
     public void openDownloadDialog() {
-            try {
-                DownloadDialog downloadDialog = DownloadDialog.newInstance(currentInfo);
-                downloadDialog.setVideoStreams(sortedVideoStreams);
-                downloadDialog.setAudioStreams(currentInfo.getAudioStreams());
-                downloadDialog.setSelectedVideoStream(selectedVideoStreamIndex);
+        try {
+            DownloadDialog downloadDialog = DownloadDialog.newInstance(currentInfo);
+            downloadDialog.setVideoStreams(sortedVideoStreams);
+            downloadDialog.setAudioStreams(currentInfo.getAudioStreams());
+            downloadDialog.setSelectedVideoStream(selectedVideoStreamIndex);
 
-                downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog");
-            } catch (Exception e) {
-                Toast.makeText(activity,
-                        R.string.could_not_setup_download_menu,
-                        Toast.LENGTH_LONG).show();
-                e.printStackTrace();
-            }
+            downloadDialog.show(activity.getSupportFragmentManager(), "downloadDialog");
+        } catch (Exception e) {
+            Toast.makeText(activity,
+                    R.string.could_not_setup_download_menu,
+                    Toast.LENGTH_LONG).show();
+            e.printStackTrace();
+        }
     }
 
     /*//////////////////////////////////////////////////////////////////////////
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 c70ea2b19..cd557c931 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
@@ -17,6 +17,7 @@ import android.view.View;
 import org.schabi.newpipe.R;
 import org.schabi.newpipe.extractor.InfoItem;
 import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
 import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
 import org.schabi.newpipe.extractor.stream.StreamInfoItem;
 import org.schabi.newpipe.fragments.BaseStateFragment;
@@ -181,6 +182,13 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
             }
         });
 
+        infoListAdapter.setOnCommentsSelectedListener(new OnClickGesture<CommentsInfoItem>() {
+            @Override
+            public void selected(CommentsInfoItem selectedItem) {
+                //Log.d("comments" , "this comment was clicked" + selectedItem.getCommentText());
+            }
+        });
+
         itemsList.clearOnScrollListeners();
         itemsList.addOnScrollListener(new OnScrollBelowItemsListener() {
             @Override
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java
index 78867c81f..dbb91bbb2 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoItemBuilder.java
@@ -10,10 +10,13 @@ import com.nostra13.universalimageloader.core.ImageLoader;
 
 import org.schabi.newpipe.extractor.InfoItem;
 import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
 import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
 import org.schabi.newpipe.extractor.stream.StreamInfoItem;
 import org.schabi.newpipe.info_list.holder.ChannelInfoItemHolder;
 import org.schabi.newpipe.info_list.holder.ChannelMiniInfoItemHolder;
+import org.schabi.newpipe.info_list.holder.CommentsInfoItemHolder;
+import org.schabi.newpipe.info_list.holder.CommentsMiniInfoItemHolder;
 import org.schabi.newpipe.info_list.holder.InfoItemHolder;
 import org.schabi.newpipe.info_list.holder.PlaylistInfoItemHolder;
 import org.schabi.newpipe.info_list.holder.PlaylistMiniInfoItemHolder;
@@ -50,6 +53,7 @@ public class InfoItemBuilder {
     private OnClickGesture<StreamInfoItem> onStreamSelectedListener;
     private OnClickGesture<ChannelInfoItem> onChannelSelectedListener;
     private OnClickGesture<PlaylistInfoItem> onPlaylistSelectedListener;
+    private OnClickGesture<CommentsInfoItem> onCommentsSelectedListener;
 
     public InfoItemBuilder(Context context) {
         this.context = context;
@@ -73,6 +77,8 @@ public class InfoItemBuilder {
                 return useMiniVariant ? new ChannelMiniInfoItemHolder(this, parent) : new ChannelInfoItemHolder(this, parent);
             case PLAYLIST:
                 return useMiniVariant ? new PlaylistMiniInfoItemHolder(this, parent) : new PlaylistInfoItemHolder(this, parent);
+            case COMMENT:
+                return useMiniVariant ? new CommentsMiniInfoItemHolder(this, parent) : new CommentsInfoItemHolder(this, parent);
             default:
                 Log.e(TAG, "Trollolo");
                 throw new RuntimeException("InfoType not expected = " + infoType.name());
@@ -111,4 +117,12 @@ public class InfoItemBuilder {
         this.onPlaylistSelectedListener = listener;
     }
 
+    public OnClickGesture<CommentsInfoItem> getOnCommentsSelectedListener() {
+        return onCommentsSelectedListener;
+    }
+
+    public void setOnCommentsSelectedListener(OnClickGesture<CommentsInfoItem> onCommentsSelectedListener) {
+        this.onCommentsSelectedListener = onCommentsSelectedListener;
+    }
+
 }
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java
index cf12deb6f..49bd2bdf1 100644
--- a/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java
+++ b/app/src/main/java/org/schabi/newpipe/info_list/InfoListAdapter.java
@@ -8,6 +8,7 @@ import android.view.ViewGroup;
 
 import org.schabi.newpipe.extractor.InfoItem;
 import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
 import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
 import org.schabi.newpipe.extractor.stream.StreamInfoItem;
 import org.schabi.newpipe.info_list.holder.ChannelInfoItemHolder;
@@ -90,6 +91,10 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
         infoItemBuilder.setOnPlaylistSelectedListener(listener);
     }
 
+    public void setOnCommentsSelectedListener(OnClickGesture<CommentsInfoItem> listener) {
+        infoItemBuilder.setOnCommentsSelectedListener(listener);
+    }
+
     public void useMiniItemVariants(boolean useMiniVariant) {
         this.useMiniVariant = useMiniVariant;
     }
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsInfoItemHolder.java
new file mode 100644
index 000000000..46e4b4563
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsInfoItemHolder.java
@@ -0,0 +1,53 @@
+package org.schabi.newpipe.info_list.holder;
+
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import org.schabi.newpipe.R;
+import org.schabi.newpipe.extractor.InfoItem;
+import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
+import org.schabi.newpipe.info_list.InfoItemBuilder;
+import org.schabi.newpipe.util.Localization;
+
+/*
+ * Created by Christian Schabesberger on 12.02.17.
+ *
+ * Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
+ * ChannelInfoItemHolder .java is part of NewPipe.
+ *
+ * NewPipe is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NewPipe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with NewPipe.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public class CommentsInfoItemHolder extends CommentsMiniInfoItemHolder {
+
+    public final TextView itemTitleView;
+
+    public CommentsInfoItemHolder(InfoItemBuilder infoItemBuilder, ViewGroup parent) {
+        super(infoItemBuilder, R.layout.list_comments_item, parent);
+
+        itemTitleView = itemView.findViewById(R.id.itemTitleView);
+    }
+
+    @Override
+    public void updateFromItem(final InfoItem infoItem) {
+        super.updateFromItem(infoItem);
+
+        if (!(infoItem instanceof CommentsInfoItem)) return;
+        final CommentsInfoItem item = (CommentsInfoItem) infoItem;
+
+        itemTitleView.setText(item.getAuthorName());
+    }
+
+}
diff --git a/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java
new file mode 100644
index 000000000..046cadc3f
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/info_list/holder/CommentsMiniInfoItemHolder.java
@@ -0,0 +1,92 @@
+package org.schabi.newpipe.info_list.holder;
+
+import android.support.v7.app.AppCompatActivity;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import org.schabi.newpipe.R;
+import org.schabi.newpipe.extractor.InfoItem;
+import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
+import org.schabi.newpipe.info_list.InfoItemBuilder;
+import org.schabi.newpipe.report.ErrorActivity;
+import org.schabi.newpipe.util.ImageDisplayConstants;
+import org.schabi.newpipe.util.Localization;
+import org.schabi.newpipe.util.NavigationHelper;
+
+import de.hdodenhof.circleimageview.CircleImageView;
+
+public class CommentsMiniInfoItemHolder extends InfoItemHolder {
+    public final CircleImageView itemThumbnailView;
+    private final TextView itemContentView;
+    private final TextView itemLikesCountView;
+    private final TextView itemDislikesCountView;
+
+    private static final int commentDefaultLines = 2;
+    private static final int commentExpandedLines = 1000;
+
+    CommentsMiniInfoItemHolder(InfoItemBuilder infoItemBuilder, int layoutId, ViewGroup parent) {
+        super(infoItemBuilder, layoutId, parent);
+
+        itemThumbnailView = itemView.findViewById(R.id.itemThumbnailView);
+        itemContentView = itemView.findViewById(R.id.itemCommentContentView);
+        itemLikesCountView = itemView.findViewById(R.id.detail_thumbs_up_count_view);
+        itemDislikesCountView = itemView.findViewById(R.id.detail_thumbs_down_count_view);
+    }
+
+    public CommentsMiniInfoItemHolder(InfoItemBuilder infoItemBuilder, ViewGroup parent) {
+        this(infoItemBuilder, R.layout.list_comments_mini_item, parent);
+    }
+
+    @Override
+    public void updateFromItem(final InfoItem infoItem) {
+        if (!(infoItem instanceof CommentsInfoItem)) return;
+        final CommentsInfoItem item = (CommentsInfoItem) infoItem;
+
+        itemBuilder.getImageLoader()
+                .displayImage(item.getAuthorThumbnail(),
+                        itemThumbnailView,
+                        ImageDisplayConstants.DISPLAY_THUMBNAIL_OPTIONS);
+
+        itemThumbnailView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                try {
+                    final AppCompatActivity activity = (AppCompatActivity) itemBuilder.getContext();
+                    NavigationHelper.openChannelFragment(
+                            activity.getSupportFragmentManager(),
+                            item.getServiceId(),
+                            item.getAuthorEndpoint(),
+                            item.getAuthorName());
+                } catch (Exception e) {
+                    ErrorActivity.reportUiError((AppCompatActivity) itemBuilder.getContext(), e);
+                }
+            }
+        });
+
+        itemContentView.setText(item.getCommentText());
+        if (null != item.getLikeCount()) {
+            itemLikesCountView.setText(String.valueOf(item.getLikeCount()));
+        }
+
+        itemView.setOnClickListener(view -> {
+            toggleEllipsize(item.getCommentText());
+            if (itemBuilder.getOnCommentsSelectedListener() != null) {
+                itemBuilder.getOnCommentsSelectedListener().selected(item);
+            }
+        });
+    }
+
+    private void toggleEllipsize(String text) {
+        // toggle ellipsize
+        if (null == itemContentView.getEllipsize()) {
+            itemContentView.setEllipsize(TextUtils.TruncateAt.END);
+            itemContentView.setMaxLines(commentDefaultLines);
+        } else {
+            itemContentView.setEllipsize(null);
+            itemContentView.setMaxLines(commentExpandedLines);
+        }
+    }
+}
diff --git a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
index e445233c3..42d746eae 100644
--- a/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
+++ b/app/src/main/java/org/schabi/newpipe/util/ExtractorHelper.java
@@ -59,7 +59,7 @@ public final class ExtractorHelper {
     }
 
     private static void checkServiceId(int serviceId) {
-        if(serviceId == Constants.NO_SERVICE_ID) {
+        if (serviceId == Constants.NO_SERVICE_ID) {
             throw new IllegalArgumentException("serviceId is NO_SERVICE_ID");
         }
     }
@@ -122,8 +122,8 @@ public final class ExtractorHelper {
     }
 
     public static Single<InfoItemsPage> getMoreChannelItems(final int serviceId,
-                                                              final String url,
-                                                              final String nextStreamsUrl) {
+                                                            final String url,
+                                                            final String nextStreamsUrl) {
         checkServiceId(serviceId);
         return Single.fromCallable(() ->
                 ChannelInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl));
@@ -138,8 +138,8 @@ public final class ExtractorHelper {
     }
 
     public static Single<InfoItemsPage> getMorePlaylistItems(final int serviceId,
-                                                               final String url,
-                                                               final String nextStreamsUrl) {
+                                                             final String url,
+                                                             final String nextStreamsUrl) {
         checkServiceId(serviceId);
         return Single.fromCallable(() ->
                 PlaylistInfo.getMoreItems(NewPipe.getService(serviceId), url, nextStreamsUrl));
@@ -154,9 +154,9 @@ public final class ExtractorHelper {
     }
 
     public static Single<InfoItemsPage> getMoreKioskItems(final int serviceId,
-                                                            final String url,
-                                                            final String nextStreamsUrl,
-                                                            final String contentCountry) {
+                                                          final String url,
+                                                          final String nextStreamsUrl,
+                                                          final String contentCountry) {
         return Single.fromCallable(() ->
                 KioskInfo.getMoreItems(NewPipe.getService(serviceId),
                         url, nextStreamsUrl, contentCountry));
@@ -198,17 +198,17 @@ public final class ExtractorHelper {
     public static <I extends Info> Maybe<I> loadFromCache(final int serviceId, final String url) {
         checkServiceId(serviceId);
         return Maybe.defer(() -> {
-                //noinspection unchecked
-                I info = (I) cache.getFromKey(serviceId, url);
-                if (MainActivity.DEBUG) Log.d(TAG, "loadFromCache() called, info > " + info);
+            //noinspection unchecked
+            I info = (I) cache.getFromKey(serviceId, url);
+            if (MainActivity.DEBUG) Log.d(TAG, "loadFromCache() called, info > " + info);
 
-                // Only return info if it's not null (it is cached)
-                if (info != null) {
-                    return Maybe.just(info);
-                }
+            // Only return info if it's not null (it is cached)
+            if (info != null) {
+                return Maybe.just(info);
+            }
 
-                return Maybe.empty();
-            });
+            return Maybe.empty();
+        });
     }
 
     /**
diff --git a/app/src/main/res/layout/fragment_video_detail.xml b/app/src/main/res/layout/fragment_video_detail.xml
index 7c6568b67..185f7d380 100644
--- a/app/src/main/res/layout/fragment_video_detail.xml
+++ b/app/src/main/res/layout/fragment_video_detail.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/video_item_detail"
@@ -40,7 +39,7 @@
                     android:scaleType="fitCenter"
                     tools:ignore="RtlHardcoded"
                     tools:layout_height="200dp"
-                    tools:src="@drawable/dummy_thumbnail"/>
+                    tools:src="@drawable/dummy_thumbnail" />
 
                 <ImageView
                     android:id="@+id/detail_thumbnail_play_button"
@@ -51,25 +50,25 @@
                     android:src="@drawable/new_play_arrow"
                     android:visibility="invisible"
                     tools:ignore="ContentDescription"
-                    tools:visibility="visible"/>
+                    tools:visibility="visible" />
 
                 <TextView
                     android:id="@+id/touch_append_detail"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
+                    android:layout_gravity="center"
                     android:background="#64000000"
                     android:paddingBottom="10dp"
                     android:paddingLeft="30dp"
                     android:paddingRight="30dp"
                     android:paddingTop="10dp"
-                    android:layout_gravity="center"
+                    android:text="@string/hold_to_append"
                     android:textColor="@android:color/white"
                     android:textSize="20sp"
                     android:textStyle="bold"
-                    android:text="@string/hold_to_append"
                     android:visibility="gone"
                     tools:ignore="RtlHardcoded"
-                    tools:visibility="visible"/>
+                    tools:visibility="visible" />
 
                 <TextView
                     android:id="@+id/detail_duration_view"
@@ -94,7 +93,7 @@
                     android:visibility="gone"
                     tools:ignore="RtlHardcoded"
                     tools:text="12:38"
-                    tools:visibility="visible"/>
+                    tools:visibility="visible" />
             </FrameLayout>
 
             <!-- CONTENT -->
@@ -127,7 +126,7 @@
                         android:textAppearance="?android:attr/textAppearanceLarge"
                         android:textSize="@dimen/video_item_detail_title_text_size"
                         tools:ignore="RtlHardcoded"
-                        tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a ultricies ex. Integer sit amet sodales risus. Duis non mi et urna pretium bibendum. Nunc eleifend est quis ipsum porttitor egestas. Sed facilisis, nisl quis eleifend pellentesque, orci metus egestas dolor, at accumsan eros metus quis libero."/>
+                        tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a ultricies ex. Integer sit amet sodales risus. Duis non mi et urna pretium bibendum. Nunc eleifend est quis ipsum porttitor egestas. Sed facilisis, nisl quis eleifend pellentesque, orci metus egestas dolor, at accumsan eros metus quis libero." />
 
                     <ImageView
                         android:id="@+id/detail_toggle_description_view"
@@ -136,7 +135,7 @@
                         android:layout_gravity="center_vertical|right"
                         android:layout_marginLeft="5dp"
                         android:src="@drawable/arrow_down"
-                        tools:ignore="ContentDescription,RtlHardcoded"/>
+                        tools:ignore="ContentDescription,RtlHardcoded" />
 
                 </FrameLayout>
 
@@ -150,7 +149,7 @@
                     android:layout_marginTop="@dimen/video_item_detail_error_panel_margin"
                     android:indeterminate="true"
                     android:visibility="gone"
-                    tools:visibility="visible"/>
+                    tools:visibility="visible" />
 
                 <!--ERROR PANEL-->
                 <include
@@ -161,7 +160,7 @@
                     android:layout_below="@id/detail_title_root_layout"
                     android:layout_marginTop="@dimen/video_item_detail_error_panel_margin"
                     android:visibility="gone"
-                    tools:visibility="visible"/>
+                    tools:visibility="visible" />
 
                 <!--HIDING ROOT-->
                 <LinearLayout
@@ -189,12 +188,12 @@
                             android:id="@+id/detail_uploader_root_layout"
                             android:layout_width="match_parent"
                             android:layout_height="match_parent"
+                            android:layout_toLeftOf="@id/details_panel"
+                            android:layout_toStartOf="@id/details_panel"
                             android:background="?attr/selectableItemBackground"
                             android:gravity="center_vertical"
                             android:orientation="horizontal"
-                            android:padding="6dp"
-                            android:layout_toLeftOf="@id/details_panel"
-                            android:layout_toStartOf="@id/details_panel">
+                            android:padding="6dp">
 
                             <de.hdodenhof.circleimageview.CircleImageView
                                 android:id="@+id/detail_uploader_thumbnail_view"
@@ -202,23 +201,23 @@
                                 android:layout_height="@dimen/video_item_detail_uploader_image_size"
                                 android:contentDescription="@string/detail_uploader_thumbnail_view_description"
                                 android:src="@drawable/buddy"
-                                tools:ignore="RtlHardcoded"/>
+                                tools:ignore="RtlHardcoded" />
 
                             <TextView
                                 android:id="@+id/detail_uploader_text_view"
                                 android:layout_width="match_parent"
                                 android:layout_height="wrap_content"
                                 android:layout_marginLeft="15dp"
-                                android:textAppearance="?android:attr/textAppearanceLarge"
-                                android:textSize="@dimen/video_item_detail_uploader_text_size"
-                                android:textStyle="bold"
                                 android:ellipsize="marquee"
                                 android:fadingEdge="horizontal"
                                 android:marqueeRepeatLimit="marquee_forever"
                                 android:scrollHorizontally="true"
                                 android:singleLine="true"
+                                android:textAppearance="?android:attr/textAppearanceLarge"
+                                android:textSize="@dimen/video_item_detail_uploader_text_size"
+                                android:textStyle="bold"
                                 tools:ignore="RtlHardcoded"
-                                tools:text="Uploader"/>
+                                tools:text="Uploader" />
 
                             <!--<Button
                                 android:id="@+id/detail_uploader_subscribe"
@@ -239,10 +238,11 @@
                             android:id="@+id/details_panel"
                             android:layout_width="wrap_content"
                             android:layout_height="match_parent"
-                            android:layout_alignParentRight="true"
                             android:layout_alignParentEnd="true"
+                            android:layout_alignParentRight="true"
                             android:paddingLeft="6dp"
                             android:paddingRight="6dp">
+
                             <TextView
                                 android:id="@+id/detail_view_count_view"
                                 android:layout_width="wrap_content"
@@ -254,7 +254,7 @@
                                 android:textAppearance="?android:attr/textAppearanceLarge"
                                 android:textSize="@dimen/video_item_detail_views_text_size"
                                 tools:ignore="RtlHardcoded"
-                                tools:text="2,816,821,505 views"/>
+                                tools:text="2,816,821,505 views" />
 
                             <ImageView
                                 android:id="@+id/detail_thumbs_up_img_view"
@@ -262,7 +262,7 @@
                                 android:layout_height="@dimen/video_item_detail_like_image_height"
                                 android:layout_below="@id/detail_view_count_view"
                                 android:contentDescription="@string/detail_likes_img_view_description"
-                                android:src="?attr/thumbs_up"/>
+                                android:src="?attr/thumbs_up" />
 
                             <TextView
                                 android:id="@+id/detail_thumbs_up_count_view"
@@ -276,7 +276,7 @@
                                 android:textAppearance="?android:attr/textAppearanceMedium"
                                 android:textSize="@dimen/video_item_detail_likes_text_size"
                                 tools:ignore="RtlHardcoded"
-                                tools:text="12M"/>
+                                tools:text="12M" />
 
                             <ImageView
                                 android:id="@+id/detail_thumbs_down_img_view"
@@ -287,7 +287,7 @@
                                 android:layout_toRightOf="@id/detail_thumbs_up_count_view"
                                 android:contentDescription="@string/detail_dislikes_img_view_description"
                                 android:src="?attr/thumbs_down"
-                                tools:ignore="RtlHardcoded"/>
+                                tools:ignore="RtlHardcoded" />
 
                             <TextView
                                 android:id="@+id/detail_thumbs_down_count_view"
@@ -301,7 +301,7 @@
                                 android:textAppearance="?android:attr/textAppearanceMedium"
                                 android:textSize="@dimen/video_item_detail_likes_text_size"
                                 tools:ignore="RtlHardcoded"
-                                tools:text="10K"/>
+                                tools:text="10K" />
 
                             <TextView
                                 android:id="@+id/detail_thumbs_disabled_view"
@@ -317,7 +317,7 @@
                                 android:textStyle="bold"
                                 android:visibility="gone"
                                 tools:ignore="RtlHardcoded"
-                                tools:visibility="visible"/>
+                                tools:visibility="visible" />
                         </RelativeLayout>
                     </RelativeLayout>
 
@@ -337,14 +337,14 @@
                             android:layout_weight="1"
                             android:background="?attr/selectableItemBackgroundBorderless"
                             android:clickable="true"
-                            android:focusable="true"
                             android:contentDescription="@string/append_playlist"
                             android:drawableTop="?attr/ic_playlist_add"
+                            android:focusable="true"
                             android:gravity="center"
                             android:paddingBottom="6dp"
                             android:paddingTop="6dp"
                             android:text="@string/controls_add_to_playlist_title"
-                            android:textSize="12sp"/>
+                            android:textSize="12sp" />
 
                         <TextView
                             android:id="@+id/detail_controls_background"
@@ -354,14 +354,14 @@
                             android:layout_weight="1"
                             android:background="?attr/selectableItemBackgroundBorderless"
                             android:clickable="true"
-                            android:focusable="true"
                             android:contentDescription="@string/play_audio"
                             android:drawableTop="?attr/audio"
+                            android:focusable="true"
                             android:gravity="center"
                             android:paddingBottom="6dp"
                             android:paddingTop="6dp"
                             android:text="@string/controls_background_title"
-                            android:textSize="12sp"/>
+                            android:textSize="12sp" />
 
                         <TextView
                             android:id="@+id/detail_controls_popup"
@@ -371,14 +371,14 @@
                             android:layout_weight="1"
                             android:background="?attr/selectableItemBackgroundBorderless"
                             android:clickable="true"
-                            android:focusable="true"
                             android:contentDescription="@string/open_in_popup_mode"
                             android:drawableTop="?attr/popup"
+                            android:focusable="true"
                             android:gravity="center"
                             android:paddingBottom="6dp"
                             android:paddingTop="6dp"
                             android:text="@string/controls_popup_title"
-                            android:textSize="12sp"/>
+                            android:textSize="12sp" />
 
                         <TextView
                             android:id="@+id/detail_controls_download"
@@ -388,14 +388,14 @@
                             android:layout_weight="1"
                             android:background="?attr/selectableItemBackgroundBorderless"
                             android:clickable="true"
-                            android:focusable="true"
                             android:contentDescription="@string/controls_download_desc"
                             android:drawableTop="?attr/download"
+                            android:focusable="true"
                             android:gravity="center"
                             android:paddingBottom="6dp"
                             android:paddingTop="6dp"
                             android:text="@string/download"
-                            android:textSize="12sp"/>
+                            android:textSize="12sp" />
 
                     </LinearLayout>
 
@@ -404,7 +404,7 @@
                         android:layout_height="1px"
                         android:layout_marginLeft="8dp"
                         android:layout_marginRight="8dp"
-                        android:background="?attr/separator_color"/>
+                        android:background="?attr/separator_color" />
 
                     <!--DESCRIPTIONS-->
                     <LinearLayout
@@ -425,7 +425,7 @@
                             android:textAppearance="?android:attr/textAppearanceMedium"
                             android:textSize="@dimen/video_item_detail_upload_date_text_size"
                             android:textStyle="bold"
-                            tools:text="Published on Oct 2, 2009"/>
+                            tools:text="Published on Oct 2, 2009" />
 
                         <TextView
                             android:id="@+id/detail_description_view"
@@ -438,57 +438,111 @@
                             android:textAppearance="?android:attr/textAppearanceMedium"
                             android:textIsSelectable="true"
                             android:textSize="@dimen/video_item_detail_description_text_size"
-                            tools:text="Description Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a ultricies ex. Integer sit amet sodales risus. Duis non mi et urna pretium bibendum."/>
+                            tools:text="Description Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a ultricies ex. Integer sit amet sodales risus. Duis non mi et urna pretium bibendum." />
 
                         <View
                             android:layout_width="match_parent"
                             android:layout_height="1px"
                             android:layout_marginLeft="8dp"
                             android:layout_marginRight="8dp"
-                            android:background="?attr/separator_color"/>
+                            android:background="?attr/separator_color" />
 
                     </LinearLayout>
 
-                    <!--NEXT AND RELATED VIDEOS-->
-                    <LinearLayout
-                        android:id="@+id/detail_related_streams_root_layout"
-                        android:layout_width="match_parent"
-                        android:layout_height="wrap_content"
-                        android:layout_gravity="center_horizontal|bottom"
-                        android:layout_marginTop="14dp"
-                        android:orientation="vertical">
-
-                        <TextView
-                            android:id="@+id/detail_next_stream_title"
-                            android:layout_width="wrap_content"
-                            android:layout_height="wrap_content"
-                            android:layout_marginLeft="12dp"
-                            android:text="@string/next_video_title"
-                            android:textAllCaps="true"
-                            android:textAppearance="?android:attr/textAppearanceMedium"
-                            android:textSize="@dimen/video_item_detail_next_text_size"
-                            tools:ignore="RtlHardcoded"/>
+                    <TabHost
+                        android:id="@+id/tab_host"
+                        android:layout_width="fill_parent"
+                        android:layout_height="wrap_content">
 
                         <LinearLayout
-                            android:id="@+id/detail_related_streams_view"
-                            android:layout_width="match_parent"
-                            android:layout_height="match_parent"
-                            android:layout_marginTop="2dp"
-                            android:orientation="vertical"
-                            tools:minHeight="50dp"/>
-
-                        <ImageButton
-                            android:id="@+id/detail_related_streams_expand"
-                            android:layout_width="match_parent"
+                            android:layout_width="fill_parent"
                             android:layout_height="wrap_content"
-                            android:background="?attr/selectableItemBackground"
-                            android:paddingBottom="10dp"
-                            android:paddingTop="4dp"
-                            android:src="?attr/expand"
-                            android:textAlignment="center"
-                            android:textAllCaps="true"
-                            tools:ignore="ContentDescription"/>
-                    </LinearLayout>
+                            android:orientation="vertical">
+
+                            <TabWidget
+                                android:id="@android:id/tabs"
+                                android:layout_width="fill_parent"
+                                android:layout_height="wrap_content" />
+
+                            <FrameLayout
+                                android:id="@android:id/tabcontent"
+                                android:layout_width="fill_parent"
+                                android:layout_height="wrap_content">
+                                <!--COMMENTS-->
+                                <LinearLayout
+                                    android:id="@+id/detail_comments_root_layout"
+                                    android:layout_width="match_parent"
+                                    android:layout_height="wrap_content"
+                                    android:layout_gravity="center_horizontal|bottom"
+                                    android:layout_marginTop="14dp"
+                                    android:orientation="vertical">
+
+                                    <LinearLayout
+                                        android:id="@+id/detail_comments_view"
+                                        android:layout_width="match_parent"
+                                        android:layout_height="match_parent"
+                                        android:layout_marginTop="2dp"
+                                        android:orientation="vertical"
+                                        tools:minHeight="50dp" />
+
+                                    <ImageButton
+                                        android:id="@+id/detail_comments_expand"
+                                        android:layout_width="match_parent"
+                                        android:layout_height="wrap_content"
+                                        android:background="?attr/selectableItemBackground"
+                                        android:paddingBottom="10dp"
+                                        android:paddingTop="4dp"
+                                        android:src="?attr/expand"
+                                        android:textAlignment="center"
+                                        android:textAllCaps="true"
+                                        tools:ignore="ContentDescription" />
+
+                                </LinearLayout>
+
+                                <!--NEXT AND RELATED VIDEOS-->
+                                <LinearLayout
+                                    android:id="@+id/detail_related_streams_root_layout"
+                                    android:layout_width="match_parent"
+                                    android:layout_height="wrap_content"
+                                    android:layout_gravity="center_horizontal|bottom"
+                                    android:layout_marginTop="14dp"
+                                    android:orientation="vertical">
+
+                                    <TextView
+                                        android:id="@+id/detail_next_stream_title"
+                                        android:layout_width="wrap_content"
+                                        android:layout_height="wrap_content"
+                                        android:layout_marginLeft="12dp"
+                                        android:text="@string/next_video_title"
+                                        android:textAllCaps="true"
+                                        android:textAppearance="?android:attr/textAppearanceMedium"
+                                        android:textSize="@dimen/video_item_detail_next_text_size"
+                                        tools:ignore="RtlHardcoded" />
+
+                                    <LinearLayout
+                                        android:id="@+id/detail_related_streams_view"
+                                        android:layout_width="match_parent"
+                                        android:layout_height="match_parent"
+                                        android:layout_marginTop="2dp"
+                                        android:orientation="vertical"
+                                        tools:minHeight="50dp" />
+
+                                    <ImageButton
+                                        android:id="@+id/detail_related_streams_expand"
+                                        android:layout_width="match_parent"
+                                        android:layout_height="wrap_content"
+                                        android:background="?attr/selectableItemBackground"
+                                        android:paddingBottom="10dp"
+                                        android:paddingTop="4dp"
+                                        android:src="?attr/expand"
+                                        android:textAlignment="center"
+                                        android:textAllCaps="true"
+                                        tools:ignore="ContentDescription" />
+                                </LinearLayout>
+                            </FrameLayout>
+                        </LinearLayout>
+                    </TabHost>
+
                 </LinearLayout>
             </RelativeLayout>
         </LinearLayout>
diff --git a/app/src/main/res/layout/list_comments_item.xml b/app/src/main/res/layout/list_comments_item.xml
new file mode 100644
index 000000000..16b6107c5
--- /dev/null
+++ b/app/src/main/res/layout/list_comments_item.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/itemRoot"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?attr/selectableItemBackground"
+    android:clickable="true"
+    android:focusable="true"
+    android:padding="@dimen/video_item_search_padding">
+
+    <de.hdodenhof.circleimageview.CircleImageView
+        android:id="@+id/itemThumbnailView"
+        android:layout_width="48dp"
+        android:layout_height="42dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginRight="@dimen/video_item_search_image_right_margin"
+        android:contentDescription="@string/list_thumbnail_view_description"
+        android:src="@drawable/buddy"
+        tools:ignore="RtlHardcoded" />
+
+    <TextView
+        android:id="@+id/itemTitleView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_marginBottom="@dimen/video_item_search_image_right_margin"
+        android:layout_toEndOf="@+id/itemThumbnailView"
+        android:layout_toRightOf="@+id/itemThumbnailView"
+        android:ellipsize="end"
+        android:lines="1"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textSize="@dimen/video_item_search_title_text_size"
+        tools:text="Author Name, Lorem ipsum" />
+
+    <TextView
+        android:id="@+id/itemCommentContentView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/itemTitleView"
+        android:layout_marginBottom="@dimen/channel_item_description_to_details_margin"
+        android:layout_toEndOf="@+id/itemThumbnailView"
+        android:layout_toRightOf="@+id/itemThumbnailView"
+        android:ellipsize="end"
+        android:lines="2"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:textSize="@dimen/video_item_search_uploader_text_size"
+        tools:text="Comment Content, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blandit" />
+
+    <!--TextView
+        android:id="@+id/itemAdditionalDetails"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_toEndOf="@+id/itemThumbnailView"
+        android:layout_toRightOf="@+id/itemThumbnailView"
+        android:lines="1"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textSize="@dimen/video_item_search_upload_date_text_size"
+        tools:text="10M subscribers • 1000 videos" /-->
+
+    <ImageView
+        android:id="@+id/detail_thumbs_up_img_view"
+        android:layout_width="@dimen/video_item_detail_like_image_width"
+        android:layout_height="@dimen/video_item_detail_like_image_height"
+        android:layout_below="@id/itemCommentContentView"
+        android:layout_toRightOf="@+id/itemThumbnailView"
+        android:contentDescription="@string/detail_likes_img_view_description"
+        android:src="?attr/thumbs_up" />
+
+    <TextView
+        android:id="@+id/detail_thumbs_up_count_view"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/video_item_detail_like_image_height"
+        android:layout_below="@id/itemCommentContentView"
+        android:layout_marginLeft="@dimen/video_item_detail_like_margin"
+        android:layout_toRightOf="@id/detail_thumbs_up_img_view"
+        android:gravity="center_vertical"
+        android:lines="1"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="@dimen/video_item_detail_likes_text_size"
+        tools:ignore="RtlHardcoded"
+        tools:text="12M" />
+
+    <ImageView
+        android:id="@+id/detail_thumbs_down_img_view"
+        android:layout_width="@dimen/video_item_detail_like_image_width"
+        android:layout_height="@dimen/video_item_detail_like_image_height"
+        android:layout_below="@id/itemCommentContentView"
+        android:layout_marginLeft="12dp"
+        android:layout_toRightOf="@id/detail_thumbs_up_count_view"
+        android:contentDescription="@string/detail_dislikes_img_view_description"
+        android:src="?attr/thumbs_down"
+        tools:ignore="RtlHardcoded" />
+
+    <TextView
+        android:id="@+id/detail_thumbs_down_count_view"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/video_item_detail_like_image_height"
+        android:layout_below="@id/itemCommentContentView"
+        android:layout_marginLeft="@dimen/video_item_detail_like_margin"
+        android:layout_toRightOf="@id/detail_thumbs_down_img_view"
+        android:gravity="center_vertical"
+        android:lines="1"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="@dimen/video_item_detail_likes_text_size"
+        tools:ignore="RtlHardcoded"
+        tools:text="10K" />
+
+</RelativeLayout>
diff --git a/app/src/main/res/layout/list_comments_mini_item.xml b/app/src/main/res/layout/list_comments_mini_item.xml
new file mode 100644
index 000000000..7e8ce1a87
--- /dev/null
+++ b/app/src/main/res/layout/list_comments_mini_item.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/itemRoot"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="?attr/selectableItemBackground"
+    android:clickable="true"
+    android:focusable="true"
+    android:padding="@dimen/video_item_search_padding">
+
+    <de.hdodenhof.circleimageview.CircleImageView
+        android:id="@+id/itemThumbnailView"
+        android:layout_width="48dp"
+        android:layout_height="42dp"
+        android:layout_centerVertical="true"
+        android:layout_marginRight="12dp"
+        android:contentDescription="@string/list_thumbnail_view_description"
+        android:src="@drawable/buddy_channel_item"
+        tools:ignore="RtlHardcoded"/>
+
+    <!--TextView
+        android:id="@+id/itemTitleView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_marginBottom="2dp"
+        android:layout_marginTop="3dp"
+        android:layout_toRightOf="@+id/itemThumbnailView"
+        android:ellipsize="end"
+        android:lines="1"
+        android:textAppearance="?android:attr/textAppearanceLarge"
+        android:textSize="@dimen/video_item_search_title_text_size"
+        tools:ignore="RtlHardcoded"
+        tools:text="Channel Title, Lorem ipsum"/-->
+
+
+    <TextView
+        android:id="@+id/itemCommentContentView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_marginBottom="@dimen/channel_item_description_to_details_margin"
+        android:layout_toRightOf="@+id/itemThumbnailView"
+        android:ellipsize="end"
+        android:lines="2"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textSize="@dimen/video_item_search_uploader_text_size"
+        tools:text="Channel description, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blandit" />
+
+    <!--TextView
+        android:id="@+id/itemAdditionalDetails"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/itemTitleView"
+        android:layout_toRightOf="@+id/itemThumbnailView"
+        android:lines="1"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:textSize="@dimen/video_item_search_upload_date_text_size"
+        tools:ignore="RtlHardcoded"
+        tools:text="10M subscribers"/-->
+
+    <ImageView
+        android:id="@+id/detail_thumbs_up_img_view"
+        android:layout_width="@dimen/video_item_detail_like_image_width"
+        android:layout_height="@dimen/video_item_detail_like_image_height"
+        android:layout_below="@id/itemCommentContentView"
+        android:layout_toRightOf="@+id/itemThumbnailView"
+        android:contentDescription="@string/detail_likes_img_view_description"
+        android:src="?attr/thumbs_up" />
+
+    <TextView
+        android:id="@+id/detail_thumbs_up_count_view"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/video_item_detail_like_image_height"
+        android:layout_below="@id/itemCommentContentView"
+        android:layout_marginLeft="@dimen/video_item_detail_like_margin"
+        android:layout_toRightOf="@id/detail_thumbs_up_img_view"
+        android:gravity="center_vertical"
+        android:lines="1"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="@dimen/video_item_detail_likes_text_size"
+        tools:ignore="RtlHardcoded"
+        tools:text="12M" />
+
+    <ImageView
+        android:id="@+id/detail_thumbs_down_img_view"
+        android:layout_width="@dimen/video_item_detail_like_image_width"
+        android:layout_height="@dimen/video_item_detail_like_image_height"
+        android:layout_below="@id/itemCommentContentView"
+        android:layout_marginLeft="12dp"
+        android:layout_toRightOf="@id/detail_thumbs_up_count_view"
+        android:contentDescription="@string/detail_dislikes_img_view_description"
+        android:src="?attr/thumbs_down"
+        tools:ignore="RtlHardcoded" />
+
+    <TextView
+        android:id="@+id/detail_thumbs_down_count_view"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/video_item_detail_like_image_height"
+        android:layout_below="@id/itemCommentContentView"
+        android:layout_marginLeft="@dimen/video_item_detail_like_margin"
+        android:layout_toRightOf="@id/detail_thumbs_down_img_view"
+        android:gravity="center_vertical"
+        android:lines="1"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="@dimen/video_item_detail_likes_text_size"
+        tools:ignore="RtlHardcoded"
+        tools:text="10K" />
+
+</RelativeLayout>
diff --git a/app/src/main/res/values/settings_keys.xml b/app/src/main/res/values/settings_keys.xml
index 9b39fec26..b110a6aa3 100644
--- a/app/src/main/res/values/settings_keys.xml
+++ b/app/src/main/res/values/settings_keys.xml
@@ -135,6 +135,7 @@
     <string name="show_search_suggestions_key" translatable="false">show_search_suggestions</string>
     <string name="show_play_with_kodi_key" translatable="false">show_play_with_kodi</string>
     <string name="show_next_video_key" translatable="false">show_next_video</string>
+    <string name="show_comments" translatable="false">show_comments</string>
     <string name="show_hold_to_append_key" translatable="false">show_hold_to_append</string>
     <string name="default_language_value">en</string>
     <string name="default_country_value">GB</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 0dc837ae8..64ff4ec74 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -129,6 +129,7 @@
     <string name="playlist">Playlist</string>
     <string name="playlists">Playlists</string>
     <string name="videos">Videos</string>
+    <string name="comments">Comments</string>
     <string name="tracks">Tracks</string>
     <string name="users">Users</string>
     <string name="yes">Yes</string>