-Redone control panel in video detail fragment.

-Added playlist append menu item to channel and playlist fragments.
-Added debouncing to local playlist fragment to allow saving join when list is reordered or item is deleted.
-Extracted hardcoded strings.
This commit is contained in:
John Zhen Mo 2018-01-28 23:01:06 -08:00
parent d31eeac49e
commit 9b4a07de34
15 changed files with 279 additions and 172 deletions

View File

@ -1031,6 +1031,7 @@ public class VideoDetailFragment extends BaseStateFragment<StreamInfo> implement
if (!TextUtils.isEmpty(info.getUploaderName())) { if (!TextUtils.isEmpty(info.getUploaderName())) {
uploaderTextView.setText(info.getUploaderName()); uploaderTextView.setText(info.getUploaderName());
uploaderTextView.setVisibility(View.VISIBLE); uploaderTextView.setVisibility(View.VISIBLE);
uploaderTextView.setSelected(true);
} else { } else {
uploaderTextView.setVisibility(View.GONE); uploaderTextView.setVisibility(View.GONE);
} }

View File

@ -20,6 +20,7 @@ import org.schabi.newpipe.extractor.playlist.PlaylistInfoItem;
import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.fragments.BaseStateFragment; import org.schabi.newpipe.fragments.BaseStateFragment;
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener; import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
import org.schabi.newpipe.fragments.local.PlaylistAppendDialog;
import org.schabi.newpipe.info_list.InfoItemDialog; import org.schabi.newpipe.info_list.InfoItemDialog;
import org.schabi.newpipe.info_list.InfoListAdapter; import org.schabi.newpipe.info_list.InfoListAdapter;
import org.schabi.newpipe.info_list.OnInfoItemGesture; import org.schabi.newpipe.info_list.OnInfoItemGesture;
@ -27,6 +28,7 @@ import org.schabi.newpipe.playlist.SinglePlayQueue;
import org.schabi.newpipe.util.NavigationHelper; import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.StateSaver; import org.schabi.newpipe.util.StateSaver;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Queue; import java.util.Queue;
@ -283,4 +285,20 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
public void handleNextItems(N result) { public void handleNextItems(N result) {
isLoading.set(false); isLoading.set(false);
} }
/*//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////*/
protected void appendToPlaylist(final android.support.v4.app.FragmentManager manager,
final String tag) {
if (infoListAdapter == null) return;
List<StreamInfoItem> streams = new ArrayList<>();
for (final InfoItem item : infoListAdapter.getItemsList()) {
if (item instanceof StreamInfoItem) {
streams.add((StreamInfoItem) item);
}
}
PlaylistAppendDialog.fromStreamInfoItems(streams).show(manager, tag);
}
} }

View File

@ -84,6 +84,7 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
private LinearLayout headerBackgroundButton; private LinearLayout headerBackgroundButton;
private MenuItem menuRssButton; private MenuItem menuRssButton;
private MenuItem playlistAppendButton;
public static ChannelFragment getInstance(int serviceId, String url, String name) { public static ChannelFragment getInstance(int serviceId, String url, String name) {
ChannelFragment instance = new ChannelFragment(); ChannelFragment instance = new ChannelFragment();
@ -194,17 +195,20 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
ActionBar supportActionBar = activity.getSupportActionBar(); ActionBar supportActionBar = activity.getSupportActionBar();
if(useAsFrontPage) { if(useAsFrontPage && supportActionBar != null) {
supportActionBar.setDisplayHomeAsUpEnabled(false); supportActionBar.setDisplayHomeAsUpEnabled(false);
} else { } else {
inflater.inflate(R.menu.menu_channel, menu); inflater.inflate(R.menu.menu_channel, menu);
if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "], inflater = [" + inflater + "]"); if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu +
"], inflater = [" + inflater + "]");
menuRssButton = menu.findItem(R.id.menu_item_rss); menuRssButton = menu.findItem(R.id.menu_item_rss);
playlistAppendButton = menu.findItem(R.id.menu_append_playlist);
if (currentInfo != null) { if (currentInfo != null) {
menuRssButton.setVisible(!TextUtils.isEmpty(currentInfo.getFeedUrl())); menuRssButton.setVisible(!TextUtils.isEmpty(currentInfo.getFeedUrl()));
playlistAppendButton.setVisible(!currentInfo.getRelatedStreams().isEmpty());
} }
} }
} }
@ -225,10 +229,12 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
case R.id.menu_item_openInBrowser: case R.id.menu_item_openInBrowser:
openUrlInBrowser(url); openUrlInBrowser(url);
break; break;
case R.id.menu_item_share: { case R.id.menu_item_share:
shareUrl(name, url); shareUrl(name, url);
break; break;
} case R.id.menu_append_playlist:
appendToPlaylist(getFragmentManager(), TAG);
break;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -428,6 +434,9 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
} else headerSubscribersTextView.setVisibility(View.GONE); } else headerSubscribersTextView.setVisibility(View.GONE);
if (menuRssButton != null) menuRssButton.setVisible(!TextUtils.isEmpty(result.getFeedUrl())); if (menuRssButton != null) menuRssButton.setVisible(!TextUtils.isEmpty(result.getFeedUrl()));
if (playlistAppendButton != null) playlistAppendButton
.setVisible(!currentInfo.getRelatedStreams().isEmpty());
playlistCtrl.setVisibility(View.VISIBLE); playlistCtrl.setVisibility(View.VISIBLE);
if (!result.errors.isEmpty()) { if (!result.errors.isEmpty()) {

View File

@ -54,6 +54,8 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
private View headerPopupButton; private View headerPopupButton;
private View headerBackgroundButton; private View headerBackgroundButton;
private MenuItem playlistAppendButton;
public static PlaylistFragment getInstance(int serviceId, String url, String name) { public static PlaylistFragment getInstance(int serviceId, String url, String name) {
PlaylistFragment instance = new PlaylistFragment(); PlaylistFragment instance = new PlaylistFragment();
instance.setInitialData(serviceId, url, name); instance.setInitialData(serviceId, url, name);
@ -141,9 +143,15 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu + "], inflater = [" + inflater + "]"); if (DEBUG) Log.d(TAG, "onCreateOptionsMenu() called with: menu = [" + menu +
"], inflater = [" + inflater + "]");
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_playlist, menu); inflater.inflate(R.menu.menu_playlist, menu);
playlistAppendButton = menu.findItem(R.id.menu_append_playlist);
if (currentInfo != null) {
playlistAppendButton.setVisible(!currentInfo.getRelatedStreams().isEmpty());
}
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
@ -166,10 +174,12 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
case R.id.menu_item_openInBrowser: case R.id.menu_item_openInBrowser:
openUrlInBrowser(url); openUrlInBrowser(url);
break; break;
case R.id.menu_item_share: { case R.id.menu_item_share:
shareUrl(name, url); shareUrl(name, url);
break; break;
} case R.id.menu_append_playlist:
appendToPlaylist(getFragmentManager(), TAG);
break;
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -215,6 +225,9 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
imageLoader.displayImage(result.getUploaderAvatarUrl(), headerUploaderAvatar, DISPLAY_AVATAR_OPTIONS); imageLoader.displayImage(result.getUploaderAvatarUrl(), headerUploaderAvatar, DISPLAY_AVATAR_OPTIONS);
headerStreamCount.setText(getResources().getQuantityString(R.plurals.videos, (int) result.stream_count, (int) result.stream_count)); headerStreamCount.setText(getResources().getQuantityString(R.plurals.videos, (int) result.stream_count, (int) result.stream_count));
if (playlistAppendButton != null) playlistAppendButton
.setVisible(!currentInfo.getRelatedStreams().isEmpty());
if (!result.getErrors().isEmpty()) { if (!result.getErrors().isEmpty()) {
showSnackBarError(result.getErrors(), UserAction.REQUESTED_PLAYLIST, NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0); showSnackBarError(result.getErrors(), UserAction.REQUESTED_PLAYLIST, NewPipe.getNameOfService(result.getServiceId()), result.getUrl(), 0);
} }

View File

@ -58,7 +58,6 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
private View header = null; private View header = null;
private View footer = null; private View footer = null;
public LocalItemListAdapter(Activity activity) { public LocalItemListAdapter(Activity activity) {
localItemBuilder = new LocalItemBuilder(activity); localItemBuilder = new LocalItemBuilder(activity);
localItems = new ArrayList<>(); localItems = new ArrayList<>();
@ -99,21 +98,16 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
} }
} }
public void addInfoItem(LocalItem data) { public void removeItem(final LocalItem data) {
addInfoItemList(Collections.singletonList(data)); final int index = localItems.indexOf(data);
}
public void removeItemAt(final int infoListPosition) { localItems.remove(index);
if (infoListPosition < 0 || infoListPosition >= localItems.size()) return; notifyItemRemoved(index + (header != null ? 1 : 0));
localItems.remove(infoListPosition);
notifyItemRemoved(infoListPosition + (header != null ? 1 : 0));
} }
public boolean swapItems(int fromAdapterPosition, int toAdapterPosition) { public boolean swapItems(int fromAdapterPosition, int toAdapterPosition) {
final int actualFrom = offsetWithoutHeader(fromAdapterPosition); final int actualFrom = adapterOffsetWithoutHeader(fromAdapterPosition);
final int actualTo = offsetWithoutHeader(toAdapterPosition); final int actualTo = adapterOffsetWithoutHeader(toAdapterPosition);
if (actualFrom < 0 || actualTo < 0) return false; if (actualFrom < 0 || actualTo < 0) return false;
if (actualFrom >= localItems.size() || actualTo >= localItems.size()) return false; if (actualFrom >= localItems.size() || actualTo >= localItems.size()) return false;
@ -150,7 +144,7 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
else notifyItemRemoved(sizeConsideringHeader()); else notifyItemRemoved(sizeConsideringHeader());
} }
private int offsetWithoutHeader(final int offset) { private int adapterOffsetWithoutHeader(final int offset) {
return offset - (header != null ? 1 : 0); return offset - (header != null ? 1 : 0);
} }

View File

@ -34,15 +34,20 @@ import org.schabi.newpipe.util.NavigationHelper;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import icepick.State; import icepick.State;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.subjects.PublishSubject;
import static org.schabi.newpipe.util.AnimationUtils.animateView; import static org.schabi.newpipe.util.AnimationUtils.animateView;
public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void> { public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void> {
private static final long SAVE_DEBOUNCE_MILLIS = 1000;
private View headerRootLayout; private View headerRootLayout;
private TextView headerTitleView; private TextView headerTitleView;
private TextView headerStreamCount; private TextView headerStreamCount;
@ -66,6 +71,9 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
private Subscription databaseSubscription; private Subscription databaseSubscription;
private LocalPlaylistManager playlistManager; private LocalPlaylistManager playlistManager;
private PublishSubject<Long> debouncedSaveSignal;
private Disposable debouncedSaver;
public static LocalPlaylistFragment getInstance(long playlistId, String name) { public static LocalPlaylistFragment getInstance(long playlistId, String name) {
LocalPlaylistFragment instance = new LocalPlaylistFragment(); LocalPlaylistFragment instance = new LocalPlaylistFragment();
instance.setInitialData(playlistId, name); instance.setInitialData(playlistId, name);
@ -89,11 +97,22 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
return inflater.inflate(R.layout.fragment_playlist, container, false); return inflater.inflate(R.layout.fragment_playlist, container, false);
} }
@Override
public void onResume() {
super.onResume();
debouncedSaveSignal = PublishSubject.create();
debouncedSaver = getDebouncedSaver();
}
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
saveJoin(); if (debouncedSaveSignal != null) debouncedSaveSignal.onComplete();
if (debouncedSaver != null) debouncedSaver.dispose();
debouncedSaveSignal = null;
debouncedSaver = null;
itemsListState = itemsList.getLayoutManager().onSaveInstanceState(); itemsListState = itemsList.getLayoutManager().onSaveInstanceState();
} }
@ -189,7 +208,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
context.getResources().getString(R.string.start_here_on_main), context.getResources().getString(R.string.start_here_on_main),
context.getResources().getString(R.string.start_here_on_background), context.getResources().getString(R.string.start_here_on_background),
context.getResources().getString(R.string.start_here_on_popup), context.getResources().getString(R.string.start_here_on_popup),
"Set as Thumbnail", context.getResources().getString(R.string.set_as_playlist_thumbnail),
context.getResources().getString(R.string.delete) context.getResources().getString(R.string.delete)
}; };
@ -217,8 +236,9 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
changeThumbnailUrl(item.thumbnailUrl); changeThumbnailUrl(item.thumbnailUrl);
break; break;
case 6: case 6:
itemListAdapter.removeItemAt(index); itemListAdapter.removeItem(item);
setVideoCount(itemListAdapter.getItemsList().size()); setVideoCount(itemListAdapter.getItemsList().size());
saveDebounced();
break; break;
default: default:
break; break;
@ -241,7 +261,9 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
final int sourceIndex = source.getAdapterPosition(); final int sourceIndex = source.getAdapterPosition();
final int targetIndex = target.getAdapterPosition(); final int targetIndex = target.getAdapterPosition();
return itemListAdapter.swapItems(sourceIndex, targetIndex); final boolean isSwapped = itemListAdapter.swapItems(sourceIndex, targetIndex);
if (isSwapped) saveDebounced();
return isSwapped;
} }
@Override @Override
@ -418,7 +440,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
final LocalPlaylistManager playlistManager = final LocalPlaylistManager playlistManager =
new LocalPlaylistManager(NewPipeDatabase.getInstance(getContext())); new LocalPlaylistManager(NewPipeDatabase.getInstance(getContext()));
final Toast successToast = Toast.makeText(getActivity(), final Toast successToast = Toast.makeText(getActivity(),
"Playlist renamed", R.string.playlist_rename_success,
Toast.LENGTH_SHORT); Toast.LENGTH_SHORT);
playlistManager.renamePlaylist(playlistId, name) playlistManager.renamePlaylist(playlistId, name)
@ -431,7 +453,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
private void changeThumbnailUrl(final String thumbnailUrl) { private void changeThumbnailUrl(final String thumbnailUrl) {
final Toast successToast = Toast.makeText(getActivity(), final Toast successToast = Toast.makeText(getActivity(),
"Playlist thumbnail changed", R.string.playlist_thumbnail_change_success,
Toast.LENGTH_SHORT); Toast.LENGTH_SHORT);
playlistManager.changePlaylistThumbnail(playlistId, thumbnailUrl) playlistManager.changePlaylistThumbnail(playlistId, thumbnailUrl)
@ -439,6 +461,18 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
.subscribe(ignore -> successToast.show()); .subscribe(ignore -> successToast.show());
} }
private void saveDebounced() {
debouncedSaveSignal.onNext(System.currentTimeMillis());
}
private Disposable getDebouncedSaver() {
return debouncedSaveSignal
.debounce(SAVE_DEBOUNCE_MILLIS, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnDispose(this::saveJoin)
.subscribe(ignored -> saveJoin());
}
private void saveJoin() { private void saveJoin() {
final List<LocalItem> items = itemListAdapter.getItemsList(); final List<LocalItem> items = itemListAdapter.getItemsList();
List<Long> streamIds = new ArrayList<>(items.size()); List<Long> streamIds = new ArrayList<>(items.size());

View File

@ -99,8 +99,8 @@ public final class PlaylistAppendDialog extends PlaylistDialog {
return; return;
final long playlistId = ((PlaylistMetadataEntry) selectedItem).uid; final long playlistId = ((PlaylistMetadataEntry) selectedItem).uid;
final Toast successToast = final Toast successToast = Toast.makeText(getContext(),
Toast.makeText(getContext(), "Added", Toast.LENGTH_SHORT); R.string.playlist_add_stream_success, Toast.LENGTH_SHORT);
playlistManager.appendToPlaylist(playlistId, getStreams()) playlistManager.appendToPlaylist(playlistId, getStreams())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())

View File

@ -48,7 +48,7 @@ public final class PlaylistCreationDialog extends PlaylistDialog {
final LocalPlaylistManager playlistManager = final LocalPlaylistManager playlistManager =
new LocalPlaylistManager(NewPipeDatabase.getInstance(getContext())); new LocalPlaylistManager(NewPipeDatabase.getInstance(getContext()));
final Toast successToast = Toast.makeText(getActivity(), final Toast successToast = Toast.makeText(getActivity(),
"Playlist successfully created", R.string.playlist_creation_success,
Toast.LENGTH_SHORT); Toast.LENGTH_SHORT);
playlistManager.createPlaylist(name, getStreams()) playlistManager.createPlaylist(name, getStreams())

View File

@ -174,8 +174,8 @@ public class BookmarkFragment extends BaseStateFragment<List<PlaylistMetadataEnt
.setMessage(R.string.delete_playlist_prompt) .setMessage(R.string.delete_playlist_prompt)
.setCancelable(true) .setCancelable(true)
.setPositiveButton(R.string.delete, (dialog, i) -> { .setPositiveButton(R.string.delete, (dialog, i) -> {
final Toast deleteSuccessful = final Toast deleteSuccessful = Toast.makeText(getContext(),
Toast.makeText(getContext(), "Deleted", Toast.LENGTH_SHORT); R.string.playlist_delete_success, Toast.LENGTH_SHORT);
disposables.add(localPlaylistManager.deletePlaylist(item.uid) disposables.add(localPlaylistManager.deletePlaylist(item.uid)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(ignored -> deleteSuccessful.show())); .subscribe(ignored -> deleteSuccessful.show()));

View File

@ -275,7 +275,7 @@ public abstract class StatisticsPlaylistFragment
if (super.onError(exception)) return true; if (super.onError(exception)) return true;
onUnrecoverableError(exception, UserAction.SOMETHING_ELSE, onUnrecoverableError(exception, UserAction.SOMETHING_ELSE,
"none", "History", R.string.general_error); "none", "History Statistics", R.string.general_error);
return true; return true;
} }

View File

@ -28,7 +28,7 @@
android:layout_height="50dp" android:layout_height="50dp"
android:layout_toRightOf="@+id/newPlaylistIcon" android:layout_toRightOf="@+id/newPlaylistIcon"
android:gravity="left|center" android:gravity="left|center"
android:text="Create New Playlist" android:text="@string/create_playlist"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="15sp" android:textSize="15sp"
android:textStyle="bold" android:textStyle="bold"

View File

@ -159,12 +159,70 @@
android:baselineAligned="false" android:baselineAligned="false"
android:orientation="horizontal"> android:orientation="horizontal">
<!--UPLOADER-->
<LinearLayout
android:id="@+id/detail_uploader_root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
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">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/detail_uploader_thumbnail_view"
android:layout_width="@dimen/video_item_detail_uploader_image_size"
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"/>
<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"
tools:ignore="RtlHardcoded"
tools:text="Uploader"/>
<!--<Button
android:id="@+id/detail_uploader_subscribe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:layout_marginRight="12dp"
android:text="@string/rss_button_title"
android:textSize="12sp"
android:theme="@style/RedButton"
android:drawableLeft="@drawable/ic_rss_feed_white_24dp"
tools:ignore="RtlHardcoded"
android:visibility="gone"/>-->
</LinearLayout>
<!-- VIEW & THUMBS --> <!-- VIEW & THUMBS -->
<RelativeLayout
android:id="@+id/details_panel"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:paddingLeft="6dp"
android:paddingRight="6dp">
<TextView <TextView
android:id="@+id/detail_view_count_view" android:id="@+id/detail_view_count_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_centerHorizontal="true"
android:layout_marginBottom="6dp" android:layout_marginBottom="6dp"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:lines="1" android:lines="1"
@ -235,36 +293,41 @@
android:visibility="gone" android:visibility="gone"
tools:ignore="RtlHardcoded" tools:ignore="RtlHardcoded"
tools:visibility="visible"/> tools:visibility="visible"/>
</RelativeLayout>
</RelativeLayout>
<LinearLayout
android:id="@+id/detail_control_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="6dp">
<!-- CONTROLS --> <!-- CONTROLS -->
<TextView <TextView
android:id="@+id/detail_controls_popup" android:id="@+id/detail_controls_playlist_append"
android:layout_width="80dp" android:layout_width="80dp"
android:layout_height="55dp" android:layout_height="55dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless" android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:contentDescription="@string/open_in_popup_mode" android:contentDescription="@string/append_playlist"
android:drawableTop="?attr/popup" android:drawableTop="?attr/playlist_add"
android:gravity="center" android:gravity="center"
android:paddingBottom="6dp" android:paddingBottom="6dp"
android:paddingTop="6dp" android:paddingTop="6dp"
android:text="@string/controls_popup_title" android:text="@string/controls_add_to_playlist_title"
android:textSize="12sp"/> android:textSize="12sp"/>
<TextView <TextView
android:id="@+id/detail_controls_background" android:id="@+id/detail_controls_background"
android:layout_width="80dp" android:layout_width="80dp"
android:layout_height="55dp" android:layout_height="55dp"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_toLeftOf="@id/detail_controls_popup" android:layout_weight="1"
android:layout_toStartOf="@id/detail_controls_popup" android:background="?attr/selectableItemBackground"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:contentDescription="@string/play_audio" android:contentDescription="@string/play_audio"
@ -276,70 +339,21 @@
android:textSize="12sp"/> android:textSize="12sp"/>
<TextView <TextView
android:id="@+id/detail_controls_playlist_append" android:id="@+id/detail_controls_popup"
android:layout_width="60dp" android:layout_width="80dp"
android:layout_height="55dp" android:layout_height="55dp"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_toLeftOf="@id/detail_controls_background" android:layout_weight="1"
android:layout_toStartOf="@id/detail_controls_background" android:background="?attr/selectableItemBackground"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:contentDescription="@string/append_playlist" android:contentDescription="@string/open_in_popup_mode"
android:drawableTop="?attr/playlist_add" android:drawableTop="?attr/popup"
android:gravity="center" android:gravity="center"
android:paddingBottom="6dp" android:paddingBottom="6dp"
android:paddingTop="6dp" android:paddingTop="6dp"
android:text="@string/controls_add_to_playlist_title" android:text="@string/controls_popup_title"
android:textSize="12sp"/> android:textSize="12sp"/>
</RelativeLayout>
<!--UPLOADER-->
<LinearLayout
android:id="@+id/detail_uploader_root_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="8dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingTop="8dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/detail_uploader_thumbnail_view"
android:layout_width="@dimen/video_item_detail_uploader_image_size"
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"/>
<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"
tools:ignore="RtlHardcoded"
tools:text="Uploader"/>
<!--<Button
android:id="@+id/detail_uploader_subscribe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:layout_marginRight="12dp"
android:text="@string/rss_button_title"
android:textSize="12sp"
android:theme="@style/RedButton"
android:drawableLeft="@drawable/ic_rss_feed_white_24dp"
tools:ignore="RtlHardcoded"
android:visibility="gone"/>-->
</LinearLayout> </LinearLayout>
<View <View

View File

@ -22,4 +22,12 @@
android:icon="?attr/share" android:icon="?attr/share"
android:title="@string/share" android:title="@string/share"
app:showAsAction="ifRoom"/> app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_append_playlist"
android:icon="?attr/playlist_add"
android:title="@string/append_playlist"
android:visible="false"
app:showAsAction="ifRoom"
tools:visible="true"/>
</menu> </menu>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<item <item
android:id="@+id/menu_item_openInBrowser" android:id="@+id/menu_item_openInBrowser"
@ -12,4 +13,12 @@
android:icon="?attr/share" android:icon="?attr/share"
android:title="@string/share" android:title="@string/share"
app:showAsAction="ifRoom"/> app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_append_playlist"
android:icon="?attr/playlist_add"
android:title="@string/append_playlist"
android:visible="false"
app:showAsAction="ifRoom"
tools:visible="true"/>
</menu> </menu>

View File

@ -384,5 +384,12 @@
<string name="rename_playlist">Rename Playlist</string> <string name="rename_playlist">Rename Playlist</string>
<string name="playlist_name_input">Name</string> <string name="playlist_name_input">Name</string>
<string name="append_playlist">Add To Playlist</string> <string name="append_playlist">Add To Playlist</string>
<string name="set_as_playlist_thumbnail">Set as Playlist Thumbnail</string>
<string name="delete_playlist_prompt">Do you want to delete this playlist?</string> <string name="delete_playlist_prompt">Do you want to delete this playlist?</string>
<string name="playlist_creation_success">Playlist successfully created</string>
<string name="playlist_add_stream_success">Added to playlist</string>
<string name="playlist_thumbnail_change_success">Playlist thumbnail changed</string>
<string name="playlist_rename_success">Playlist renamed</string>
<string name="playlist_delete_success">Playlist deleted</string>
</resources> </resources>