-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())) {
uploaderTextView.setText(info.getUploaderName());
uploaderTextView.setVisibility(View.VISIBLE);
uploaderTextView.setSelected(true);
} else {
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.fragments.BaseStateFragment;
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.InfoListAdapter;
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.StateSaver;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
@ -283,4 +285,20 @@ public abstract class BaseListFragment<I, N> extends BaseStateFragment<I> implem
public void handleNextItems(N result) {
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 MenuItem menuRssButton;
private MenuItem playlistAppendButton;
public static ChannelFragment getInstance(int serviceId, String url, String name) {
ChannelFragment instance = new ChannelFragment();
@ -194,17 +195,20 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
ActionBar supportActionBar = activity.getSupportActionBar();
if(useAsFrontPage) {
if(useAsFrontPage && supportActionBar != null) {
supportActionBar.setDisplayHomeAsUpEnabled(false);
} else {
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);
playlistAppendButton = menu.findItem(R.id.menu_append_playlist);
if (currentInfo != null) {
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:
openUrlInBrowser(url);
break;
case R.id.menu_item_share: {
case R.id.menu_item_share:
shareUrl(name, url);
break;
}
case R.id.menu_append_playlist:
appendToPlaylist(getFragmentManager(), TAG);
break;
default:
return super.onOptionsItemSelected(item);
}
@ -428,6 +434,9 @@ public class ChannelFragment extends BaseListInfoFragment<ChannelInfo> {
} else headerSubscribersTextView.setVisibility(View.GONE);
if (menuRssButton != null) menuRssButton.setVisible(!TextUtils.isEmpty(result.getFeedUrl()));
if (playlistAppendButton != null) playlistAppendButton
.setVisible(!currentInfo.getRelatedStreams().isEmpty());
playlistCtrl.setVisibility(View.VISIBLE);
if (!result.errors.isEmpty()) {

View File

@ -54,6 +54,8 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
private View headerPopupButton;
private View headerBackgroundButton;
private MenuItem playlistAppendButton;
public static PlaylistFragment getInstance(int serviceId, String url, String name) {
PlaylistFragment instance = new PlaylistFragment();
instance.setInitialData(serviceId, url, name);
@ -141,9 +143,15 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
@Override
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);
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:
openUrlInBrowser(url);
break;
case R.id.menu_item_share: {
case R.id.menu_item_share:
shareUrl(name, url);
break;
}
case R.id.menu_append_playlist:
appendToPlaylist(getFragmentManager(), TAG);
break;
default:
return super.onOptionsItemSelected(item);
}
@ -215,6 +225,9 @@ public class PlaylistFragment extends BaseListInfoFragment<PlaylistInfo> {
imageLoader.displayImage(result.getUploaderAvatarUrl(), headerUploaderAvatar, DISPLAY_AVATAR_OPTIONS);
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()) {
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 footer = null;
public LocalItemListAdapter(Activity activity) {
localItemBuilder = new LocalItemBuilder(activity);
localItems = new ArrayList<>();
@ -99,21 +98,16 @@ public class LocalItemListAdapter extends RecyclerView.Adapter<RecyclerView.View
}
}
public void addInfoItem(LocalItem data) {
addInfoItemList(Collections.singletonList(data));
}
public void removeItem(final LocalItem data) {
final int index = localItems.indexOf(data);
public void removeItemAt(final int infoListPosition) {
if (infoListPosition < 0 || infoListPosition >= localItems.size()) return;
localItems.remove(infoListPosition);
notifyItemRemoved(infoListPosition + (header != null ? 1 : 0));
localItems.remove(index);
notifyItemRemoved(index + (header != null ? 1 : 0));
}
public boolean swapItems(int fromAdapterPosition, int toAdapterPosition) {
final int actualFrom = offsetWithoutHeader(fromAdapterPosition);
final int actualTo = offsetWithoutHeader(toAdapterPosition);
final int actualFrom = adapterOffsetWithoutHeader(fromAdapterPosition);
final int actualTo = adapterOffsetWithoutHeader(toAdapterPosition);
if (actualFrom < 0 || actualTo < 0) 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());
}
private int offsetWithoutHeader(final int offset) {
private int adapterOffsetWithoutHeader(final int offset) {
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.List;
import java.util.concurrent.TimeUnit;
import icepick.State;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.subjects.PublishSubject;
import static org.schabi.newpipe.util.AnimationUtils.animateView;
public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistStreamEntry>, Void> {
private static final long SAVE_DEBOUNCE_MILLIS = 1000;
private View headerRootLayout;
private TextView headerTitleView;
private TextView headerStreamCount;
@ -66,6 +71,9 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
private Subscription databaseSubscription;
private LocalPlaylistManager playlistManager;
private PublishSubject<Long> debouncedSaveSignal;
private Disposable debouncedSaver;
public static LocalPlaylistFragment getInstance(long playlistId, String name) {
LocalPlaylistFragment instance = new LocalPlaylistFragment();
instance.setInitialData(playlistId, name);
@ -89,11 +97,22 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
return inflater.inflate(R.layout.fragment_playlist, container, false);
}
@Override
public void onResume() {
super.onResume();
debouncedSaveSignal = PublishSubject.create();
debouncedSaver = getDebouncedSaver();
}
@Override
public void onPause() {
super.onPause();
saveJoin();
if (debouncedSaveSignal != null) debouncedSaveSignal.onComplete();
if (debouncedSaver != null) debouncedSaver.dispose();
debouncedSaveSignal = null;
debouncedSaver = null;
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_background),
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)
};
@ -217,8 +236,9 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
changeThumbnailUrl(item.thumbnailUrl);
break;
case 6:
itemListAdapter.removeItemAt(index);
itemListAdapter.removeItem(item);
setVideoCount(itemListAdapter.getItemsList().size());
saveDebounced();
break;
default:
break;
@ -241,7 +261,9 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
final int sourceIndex = source.getAdapterPosition();
final int targetIndex = target.getAdapterPosition();
return itemListAdapter.swapItems(sourceIndex, targetIndex);
final boolean isSwapped = itemListAdapter.swapItems(sourceIndex, targetIndex);
if (isSwapped) saveDebounced();
return isSwapped;
}
@Override
@ -418,7 +440,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
final LocalPlaylistManager playlistManager =
new LocalPlaylistManager(NewPipeDatabase.getInstance(getContext()));
final Toast successToast = Toast.makeText(getActivity(),
"Playlist renamed",
R.string.playlist_rename_success,
Toast.LENGTH_SHORT);
playlistManager.renamePlaylist(playlistId, name)
@ -431,7 +453,7 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
private void changeThumbnailUrl(final String thumbnailUrl) {
final Toast successToast = Toast.makeText(getActivity(),
"Playlist thumbnail changed",
R.string.playlist_thumbnail_change_success,
Toast.LENGTH_SHORT);
playlistManager.changePlaylistThumbnail(playlistId, thumbnailUrl)
@ -439,6 +461,18 @@ public class LocalPlaylistFragment extends BaseLocalListFragment<List<PlaylistSt
.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() {
final List<LocalItem> items = itemListAdapter.getItemsList();
List<Long> streamIds = new ArrayList<>(items.size());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -159,112 +159,175 @@
android:baselineAligned="false"
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 -->
<TextView
android:id="@+id/detail_view_count_view"
<RelativeLayout
android:id="@+id/details_panel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginBottom="6dp"
android:layout_marginTop="6dp"
android:lines="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_detail_views_text_size"
tools:ignore="RtlHardcoded"
tools:text="2,816,821,505 views"/>
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:paddingLeft="6dp"
android:paddingRight="6dp">
<TextView
android:id="@+id/detail_view_count_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="6dp"
android:layout_marginTop="6dp"
android:lines="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_detail_views_text_size"
tools:ignore="RtlHardcoded"
tools:text="2,816,821,505 views"/>
<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/detail_view_count_view"
android:contentDescription="@string/detail_likes_img_view_description"
android:src="?attr/thumbs_up"/>
<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/detail_view_count_view"
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/detail_view_count_view"
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"/>
<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/detail_view_count_view"
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/detail_view_count_view"
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"/>
<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/detail_view_count_view"
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/detail_view_count_view"
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"/>
<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/detail_view_count_view"
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"/>
<TextView
android:id="@+id/detail_thumbs_disabled_view"
android:layout_width="wrap_content"
android:layout_height="@dimen/video_item_detail_like_image_height"
android:layout_below="@id/detail_view_count_view"
android:layout_marginLeft="12dp"
android:layout_toRightOf="@id/detail_thumbs_down_img_view"
android:gravity="center_vertical"
android:text="@string/disabled"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_detail_likes_text_size"
android:textStyle="bold"
android:visibility="gone"
tools:ignore="RtlHardcoded"
tools:visibility="visible"/>
<TextView
android:id="@+id/detail_thumbs_disabled_view"
android:layout_width="wrap_content"
android:layout_height="@dimen/video_item_detail_like_image_height"
android:layout_below="@id/detail_view_count_view"
android:layout_marginLeft="12dp"
android:layout_toRightOf="@id/detail_thumbs_down_img_view"
android:gravity="center_vertical"
android:text="@string/disabled"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_detail_likes_text_size"
android:textStyle="bold"
android:visibility="gone"
tools:ignore="RtlHardcoded"
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 -->
<TextView
android:id="@+id/detail_controls_popup"
android:id="@+id/detail_controls_playlist_append"
android:layout_width="80dp"
android:layout_height="55dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:contentDescription="@string/open_in_popup_mode"
android:drawableTop="?attr/popup"
android:contentDescription="@string/append_playlist"
android:drawableTop="?attr/playlist_add"
android:gravity="center"
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:text="@string/controls_popup_title"
android:text="@string/controls_add_to_playlist_title"
android:textSize="12sp"/>
<TextView
android:id="@+id/detail_controls_background"
android:layout_width="80dp"
android:layout_height="55dp"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical"
android:layout_toLeftOf="@id/detail_controls_popup"
android:layout_toStartOf="@id/detail_controls_popup"
android:background="?attr/selectableItemBackgroundBorderless"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:contentDescription="@string/play_audio"
@ -276,70 +339,21 @@
android:textSize="12sp"/>
<TextView
android:id="@+id/detail_controls_playlist_append"
android:layout_width="60dp"
android:id="@+id/detail_controls_popup"
android:layout_width="80dp"
android:layout_height="55dp"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical"
android:layout_toLeftOf="@id/detail_controls_background"
android:layout_toStartOf="@id/detail_controls_background"
android:background="?attr/selectableItemBackgroundBorderless"
android:layout_weight="1"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:contentDescription="@string/append_playlist"
android:drawableTop="?attr/playlist_add"
android:contentDescription="@string/open_in_popup_mode"
android:drawableTop="?attr/popup"
android:gravity="center"
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:text="@string/controls_add_to_playlist_title"
android:text="@string/controls_popup_title"
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>
<View

View File

@ -22,4 +22,12 @@
android:icon="?attr/share"
android:title="@string/share"
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>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<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
android:id="@+id/menu_item_openInBrowser"
@ -12,4 +13,12 @@
android:icon="?attr/share"
android:title="@string/share"
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>

View File

@ -384,5 +384,12 @@
<string name="rename_playlist">Rename Playlist</string>
<string name="playlist_name_input">Name</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="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>