mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2026-05-16 04:52:39 +02:00
Library UI, artists listing, new album layout, etc
This commit is contained in:
+77
-51
@@ -1,31 +1,25 @@
|
||||
package com.futo.platformplayer.fragment.mainactivity.main
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.futo.platformplayer.R
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.futo.platformplayer.UISlideOverlays
|
||||
import com.futo.platformplayer.activities.IWithResultLauncher
|
||||
import com.futo.platformplayer.activities.MainActivity
|
||||
import com.futo.platformplayer.api.media.models.video.IPlatformVideo
|
||||
import com.futo.platformplayer.models.Playlist
|
||||
import com.futo.platformplayer.api.media.structures.AdhocPager
|
||||
import com.futo.platformplayer.api.media.structures.EmptyPager
|
||||
import com.futo.platformplayer.api.media.structures.IPager
|
||||
import com.futo.platformplayer.states.Album
|
||||
import com.futo.platformplayer.states.StateApp
|
||||
import com.futo.platformplayer.states.StateDownloads
|
||||
import com.futo.platformplayer.states.StateLibrary
|
||||
import com.futo.platformplayer.states.StatePlayer
|
||||
import com.futo.platformplayer.states.StatePlaylists
|
||||
import com.futo.platformplayer.views.buttons.BigButton
|
||||
import com.futo.platformplayer.views.overlays.slideup.SlideUpMenuOverlay
|
||||
import com.futo.platformplayer.views.overlays.slideup.SlideUpMenuTextInput
|
||||
import com.futo.platformplayer.toHumanDuration
|
||||
import com.futo.platformplayer.views.AlbumHeaderView
|
||||
import com.futo.platformplayer.views.FeedStyle
|
||||
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
|
||||
import com.futo.platformplayer.views.adapters.viewholders.TrackViewHolder
|
||||
|
||||
|
||||
class LibraryAlbumFragment : MainFragment() {
|
||||
@@ -57,20 +51,34 @@ class LibraryAlbumFragment : MainFragment() {
|
||||
}
|
||||
|
||||
|
||||
class FragView: VideoListEditorView {
|
||||
val fragment: LibraryAlbumFragment;
|
||||
class FragView : FeedView<LibraryAlbumFragment, IPlatformVideo, IPlatformVideo, IPager<IPlatformVideo>, TrackViewHolder> {
|
||||
override val feedStyle: FeedStyle = FeedStyle.THUMBNAIL; //R.layout.list_creator;
|
||||
|
||||
private val _header: AlbumHeaderView;
|
||||
|
||||
private var _album: Album? = null;
|
||||
private var _tracks: List<IPlatformVideo>? = null;
|
||||
private var _url: String? = null;
|
||||
|
||||
constructor(fragment: LibraryAlbumFragment, inflater: LayoutInflater) : super(inflater) {
|
||||
this.fragment = fragment;
|
||||
constructor(fragment: LibraryAlbumFragment, inflater: LayoutInflater) : super(fragment, inflater) {
|
||||
_header = AlbumHeaderView(context);
|
||||
_toolbarContentView.addView(_header);
|
||||
|
||||
_header.onPlayAll.subscribe {
|
||||
val playlist = _album?.toPlaylist(_tracks);
|
||||
if (playlist != null) {
|
||||
StatePlayer.instance.setPlaylist(playlist, focus = true);
|
||||
}
|
||||
}
|
||||
_header.onShuffle.subscribe {
|
||||
val playlist = _album?.toPlaylist(_tracks);
|
||||
if (playlist != null) {
|
||||
StatePlayer.instance.setPlaylist(playlist, focus = true, shuffle = true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onShown(parameter: Any? = null) {
|
||||
|
||||
fun onShown(parameter: Any?) {
|
||||
val album = if(parameter is String)
|
||||
StateLibrary.instance.getAlbum(parameter);
|
||||
else if(parameter is Long)
|
||||
@@ -81,43 +89,61 @@ class LibraryAlbumFragment : MainFragment() {
|
||||
if(album == null) {
|
||||
_album = null;
|
||||
_tracks = null;
|
||||
setVideos(listOf(), false);
|
||||
setPager(EmptyPager());
|
||||
return;
|
||||
}
|
||||
setName(album.name);
|
||||
_header.setName(album.name);
|
||||
_header.setThumbnail(album.thumbnail);
|
||||
val tracks = album.getTracks();
|
||||
_album = album;
|
||||
_tracks = tracks;
|
||||
setMetadata(tracks.size, if(tracks.size > 0) tracks.sumOf { it.duration } else -1);
|
||||
setVideos(tracks, false, album.thumbnail);
|
||||
_header.setMetadata("${tracks.size} tracks" + if(tracks.size > 0) (" • " + tracks.sumOf { it.duration }.toHumanDuration(false)) else "");
|
||||
setPager(AdhocPager({listOf()}, tracks));
|
||||
}
|
||||
|
||||
override fun onPlayAllClick() {
|
||||
val playlist = _album?.toPlaylist(_tracks);
|
||||
if (playlist != null) {
|
||||
StatePlayer.instance.setPlaylist(playlist, focus = true);
|
||||
override fun createAdapter(recyclerResults: RecyclerView, context: Context, dataset: ArrayList<IPlatformVideo>): InsertedViewAdapterWithLoader<TrackViewHolder> {
|
||||
return InsertedViewAdapterWithLoader(context, arrayListOf(), arrayListOf(),
|
||||
childCountGetter = { dataset.size },
|
||||
childViewHolderBinder = { viewHolder, position -> viewHolder.bind(dataset[position]); },
|
||||
childViewHolderFactory = { viewGroup, _ ->
|
||||
val holder = TrackViewHolder(viewGroup);
|
||||
holder.onClick.subscribe { c ->
|
||||
|
||||
val playlist = _album?.toPlaylist(_tracks);
|
||||
if (playlist != null) {
|
||||
val index = playlist.videos.indexOf(c);
|
||||
if (index == -1)
|
||||
return@subscribe;
|
||||
|
||||
StatePlayer.instance.setPlaylist(playlist, index, true);
|
||||
}
|
||||
};
|
||||
holder.onOptions.subscribe {
|
||||
if(it is IPlatformVideo)
|
||||
UISlideOverlays.showVideoOptionsOverlay(it, _overlayContainer);
|
||||
}
|
||||
return@InsertedViewAdapterWithLoader holder;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
override fun updateSpanCount(){ }
|
||||
|
||||
override fun createLayoutManager(recyclerResults: RecyclerView, context: Context): GridLayoutManager {
|
||||
val glmResults = GridLayoutManager(context, 1)
|
||||
|
||||
_swipeRefresh.layoutParams = (_swipeRefresh.layoutParams as MarginLayoutParams?)?.apply {
|
||||
rightMargin = TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
8.0f,
|
||||
context.resources.displayMetrics
|
||||
).toInt()
|
||||
}
|
||||
return glmResults
|
||||
}
|
||||
|
||||
override fun onShuffleClick() {
|
||||
val playlist = _album?.toPlaylist(_tracks);
|
||||
if (playlist != null) {
|
||||
StatePlayer.instance.setPlaylist(playlist, focus = true, shuffle = true);
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVideoOptions(video: IPlatformVideo) {
|
||||
UISlideOverlays.showVideoOptionsOverlay(video, overlayContainer);
|
||||
}
|
||||
override fun onVideoClicked(video: IPlatformVideo) {
|
||||
val playlist = _album?.toPlaylist(_tracks);
|
||||
if (playlist != null) {
|
||||
val index = playlist.videos.indexOf(video);
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
StatePlayer.instance.setPlaylist(playlist, index, true);
|
||||
}
|
||||
companion object {
|
||||
private const val TAG = "LibraryArtistsFragmentsView";
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
-7
@@ -36,9 +36,11 @@ import com.futo.platformplayer.states.StateLibrary
|
||||
import com.futo.platformplayer.stores.FragmentedStorage
|
||||
import com.futo.platformplayer.stores.StringStorage
|
||||
import com.futo.platformplayer.views.FeedStyle
|
||||
import com.futo.platformplayer.views.LibraryTypeHeaderView
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
|
||||
import com.futo.platformplayer.views.adapters.SubscriptionAdapter
|
||||
import com.futo.platformplayer.views.adapters.viewholders.AlbumTileViewHolder
|
||||
import com.futo.platformplayer.views.adapters.viewholders.SelectablePlaylist
|
||||
import com.futo.platformplayer.views.others.CreatorThumbnail
|
||||
import com.futo.platformplayer.views.platform.PlatformIndicator
|
||||
@@ -75,24 +77,41 @@ class LibraryAlbumsFragment : MainFragment() {
|
||||
fun newInstance() = LibraryAlbumsFragment().apply {}
|
||||
}
|
||||
|
||||
class FragView : FeedView<LibraryAlbumsFragment, Album, Album, IPager<Album>, AlbumViewHolder> {
|
||||
class FragView : FeedView<LibraryAlbumsFragment, Album, Album, IPager<Album>, AlbumTileViewHolder> {
|
||||
override val feedStyle: FeedStyle = FeedStyle.THUMBNAIL; //R.layout.list_creator;
|
||||
|
||||
constructor(fragment: LibraryAlbumsFragment, inflater: LayoutInflater) : super(fragment, inflater)
|
||||
val libraryTypeHeader: LibraryTypeHeaderView;
|
||||
|
||||
constructor(fragment: LibraryAlbumsFragment, inflater: LayoutInflater) : super(fragment, inflater) {
|
||||
libraryTypeHeader = LibraryTypeHeaderView(context);
|
||||
libraryTypeHeader.setSelectedType(LibraryTypeHeaderView.SelectedType.Albums);
|
||||
libraryTypeHeader.setMetadata("");
|
||||
|
||||
libraryTypeHeader.onSelectedChanged.subscribe {
|
||||
when(it) {
|
||||
LibraryTypeHeaderView.SelectedType.Artists -> fragment.navigate<LibraryArtistsFragment>();
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
_toolbarContentView.addView(libraryTypeHeader);
|
||||
}
|
||||
|
||||
fun onShown() {
|
||||
val initialAlbums = StateLibrary.instance.getAlbums();
|
||||
Logger.i(TAG, "Initial album count: " + initialAlbums.size);
|
||||
|
||||
libraryTypeHeader.setMetadata("${initialAlbums.size} albums");
|
||||
setPager(AdhocPager<Album>({ listOf(); }, initialAlbums));
|
||||
}
|
||||
|
||||
override fun createAdapter(recyclerResults: RecyclerView, context: Context, dataset: ArrayList<Album>): InsertedViewAdapterWithLoader<AlbumViewHolder> {
|
||||
override fun createAdapter(recyclerResults: RecyclerView, context: Context, dataset: ArrayList<Album>): InsertedViewAdapterWithLoader<AlbumTileViewHolder> {
|
||||
return InsertedViewAdapterWithLoader(context, arrayListOf(), arrayListOf(),
|
||||
childCountGetter = { dataset.size },
|
||||
childViewHolderBinder = { viewHolder, position -> viewHolder.bind(dataset[position]); },
|
||||
childViewHolderFactory = { viewGroup, _ ->
|
||||
val holder = AlbumViewHolder(viewGroup);
|
||||
val holder = AlbumTileViewHolder(viewGroup);
|
||||
holder.setAutoSize(resources.displayMetrics.widthPixels / resources.displayMetrics.density)
|
||||
holder.onClick.subscribe { c -> fragment.navigate<LibraryAlbumFragment>(c) };
|
||||
return@InsertedViewAdapterWithLoader holder;
|
||||
}
|
||||
@@ -102,12 +121,12 @@ class LibraryAlbumsFragment : MainFragment() {
|
||||
override fun updateSpanCount(){ }
|
||||
|
||||
override fun createLayoutManager(recyclerResults: RecyclerView, context: Context): GridLayoutManager {
|
||||
val glmResults = GridLayoutManager(context, 1)
|
||||
val glmResults = GridLayoutManager(context, AlbumTileViewHolder.getAutoSizeColumns(resources.displayMetrics.widthPixels / resources.displayMetrics.density))
|
||||
|
||||
_swipeRefresh.layoutParams = (_swipeRefresh.layoutParams as MarginLayoutParams?)?.apply {
|
||||
rightMargin = TypedValue.applyDimension(
|
||||
leftMargin = TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
8.0f,
|
||||
3f,
|
||||
context.resources.displayMetrics
|
||||
).toInt()
|
||||
}
|
||||
|
||||
+6
-4
@@ -51,6 +51,7 @@ import com.futo.platformplayer.states.StatePlaylists
|
||||
import com.futo.platformplayer.states.StateSubscriptions
|
||||
import com.futo.platformplayer.views.FeedStyle
|
||||
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
|
||||
import com.futo.platformplayer.views.adapters.viewholders.AlbumTileViewHolder
|
||||
import com.futo.platformplayer.views.others.CreatorThumbnail
|
||||
import com.futo.platformplayer.views.overlays.slideup.SlideUpMenuOverlay
|
||||
import com.futo.platformplayer.views.subscriptions.SubscribeButton
|
||||
@@ -518,7 +519,7 @@ class LibraryArtistFragment : MainFragment() {
|
||||
_lastArtist = artist;
|
||||
}
|
||||
}
|
||||
class ArtistAlbumsView : FeedView<LibraryArtistFragment, Album, Album, IPager<Album>, AlbumViewHolder> {
|
||||
class ArtistAlbumsView : FeedView<LibraryArtistFragment, Album, Album, IPager<Album>, AlbumTileViewHolder> {
|
||||
override val feedStyle: FeedStyle = FeedStyle.THUMBNAIL; //R.layout.list_creator;
|
||||
|
||||
constructor(fragment: LibraryArtistFragment, inflater: LayoutInflater) : super(fragment, inflater)
|
||||
@@ -533,12 +534,13 @@ class LibraryArtistFragment : MainFragment() {
|
||||
setPager(AdhocPager({ listOf() }, initialAlbums));
|
||||
}
|
||||
|
||||
override fun createAdapter(recyclerResults: RecyclerView, context: Context, dataset: ArrayList<Album>): InsertedViewAdapterWithLoader<AlbumViewHolder> {
|
||||
override fun createAdapter(recyclerResults: RecyclerView, context: Context, dataset: ArrayList<Album>): InsertedViewAdapterWithLoader<AlbumTileViewHolder> {
|
||||
return InsertedViewAdapterWithLoader(context, arrayListOf(), arrayListOf(),
|
||||
childCountGetter = { dataset.size },
|
||||
childViewHolderBinder = { viewHolder, position -> viewHolder.bind(dataset[position]); },
|
||||
childViewHolderFactory = { viewGroup, _ ->
|
||||
val holder = AlbumViewHolder(viewGroup);
|
||||
val holder = AlbumTileViewHolder(viewGroup);
|
||||
holder.setAutoSize(resources.displayMetrics.widthPixels / resources.displayMetrics.density)
|
||||
holder.onClick.subscribe { c -> fragment.navigate<LibraryAlbumFragment>(c) };
|
||||
return@InsertedViewAdapterWithLoader holder;
|
||||
}
|
||||
@@ -548,7 +550,7 @@ class LibraryArtistFragment : MainFragment() {
|
||||
override fun updateSpanCount(){ }
|
||||
|
||||
override fun createLayoutManager(recyclerResults: RecyclerView, context: Context): GridLayoutManager {
|
||||
val glmResults = GridLayoutManager(context, 1)
|
||||
val glmResults = GridLayoutManager(context, AlbumTileViewHolder.getAutoSizeColumns(resources.displayMetrics.widthPixels / resources.displayMetrics.density))
|
||||
|
||||
_swipeRefresh.layoutParams = (_swipeRefresh.layoutParams as MarginLayoutParams?)?.apply {
|
||||
rightMargin = TypedValue.applyDimension(
|
||||
|
||||
+28
-6
@@ -12,6 +12,7 @@ import android.widget.EditText
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.LinearLayout.GONE
|
||||
import android.widget.LinearLayout.VISIBLE
|
||||
import android.widget.Spinner
|
||||
@@ -37,6 +38,7 @@ import com.futo.platformplayer.states.StateLibrary
|
||||
import com.futo.platformplayer.stores.FragmentedStorage
|
||||
import com.futo.platformplayer.stores.StringStorage
|
||||
import com.futo.platformplayer.views.FeedStyle
|
||||
import com.futo.platformplayer.views.LibraryTypeHeaderView
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
|
||||
import com.futo.platformplayer.views.adapters.SubscriptionAdapter
|
||||
@@ -80,21 +82,35 @@ class LibraryArtistsFragment : MainFragment() {
|
||||
class FragView : FeedView<LibraryArtistsFragment, Artist, Artist, IPager<Artist>, ArtistViewHolder> {
|
||||
override val feedStyle: FeedStyle = FeedStyle.THUMBNAIL; //R.layout.list_creator;
|
||||
|
||||
constructor(fragment: LibraryArtistsFragment, inflater: LayoutInflater) : super(fragment, inflater)
|
||||
val libraryTypeHeader: LibraryTypeHeaderView;
|
||||
|
||||
constructor(fragment: LibraryArtistsFragment, inflater: LayoutInflater) : super(fragment, inflater) {
|
||||
libraryTypeHeader = LibraryTypeHeaderView(context);
|
||||
libraryTypeHeader.setSelectedType(LibraryTypeHeaderView.SelectedType.Artists);
|
||||
libraryTypeHeader.setMetadata("");
|
||||
|
||||
libraryTypeHeader.onSelectedChanged.subscribe {
|
||||
when(it) {
|
||||
LibraryTypeHeaderView.SelectedType.Albums -> fragment.navigate<LibraryAlbumsFragment>();
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
_toolbarContentView.addView(libraryTypeHeader);
|
||||
}
|
||||
|
||||
fun onShown() {
|
||||
val intialArtists = StateLibrary.instance.getArtists(ArtistOrdering.Alphabethic);
|
||||
Logger.i(TAG, "Initial album count: " + intialArtists.size);
|
||||
|
||||
setPager(AdhocPager<Artist>({ listOf(); }, intialArtists));
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
override fun reload() {
|
||||
try {
|
||||
setLoading(true);
|
||||
val intialArtists = StateLibrary.instance.getArtists(ArtistOrdering.Alphabethic);
|
||||
Logger.i(TAG, "Initial album count: " + intialArtists.size);
|
||||
|
||||
libraryTypeHeader.setMetadata("${intialArtists.size} artists");
|
||||
setPager(AdhocPager<Artist>({ listOf(); }, intialArtists));
|
||||
}
|
||||
finally {
|
||||
@@ -170,7 +186,13 @@ class LibraryArtistsFragment : MainFragment() {
|
||||
*/
|
||||
|
||||
_textName.text = artist.name;
|
||||
_textMetadata.text = artist.countTracks?.let { "${it} tracks" } ?: "";
|
||||
|
||||
val metaComps = listOf(
|
||||
artist.countTracks?.let { "${it} tracks" },
|
||||
artist.countAlbums?.let { "${it} albums" }
|
||||
).filterNotNull();
|
||||
|
||||
_textMetadata.text = metaComps.joinToString(", ");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.futo.platformplayer.views
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.bumptech.glide.Glide
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.constructs.Event0
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
|
||||
class AlbumHeaderView: ConstraintLayout {
|
||||
|
||||
|
||||
val textName: TextView;
|
||||
val textMetadata: TextView;
|
||||
|
||||
val imageThumbnail: ImageView;
|
||||
val imageThumbnailBackground: ImageView;
|
||||
|
||||
val buttonPlayAll: LinearLayout;
|
||||
val buttonShuffle: LinearLayout;
|
||||
|
||||
val onPlayAll = Event0();
|
||||
val onShuffle = Event0();
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
inflate(context, R.layout.view_album_header, this)
|
||||
|
||||
textName = findViewById(R.id.text_name);
|
||||
textMetadata = findViewById(R.id.text_metadata);
|
||||
imageThumbnail = findViewById(R.id.image_thumbnail);
|
||||
imageThumbnailBackground = findViewById(R.id.image_thumbnail_background);
|
||||
buttonPlayAll = findViewById(R.id.button_play_all);
|
||||
buttonShuffle = findViewById(R.id.button_shuffle);
|
||||
|
||||
buttonPlayAll.setOnClickListener { onPlayAll.emit() };
|
||||
buttonShuffle.setOnClickListener { onShuffle.emit() };
|
||||
}
|
||||
|
||||
fun setThumbnail(thumbnail: String?) {
|
||||
if (thumbnail != null)
|
||||
Glide.with(imageThumbnail)
|
||||
.load(thumbnail)
|
||||
.placeholder(R.drawable.placeholder_channel_thumbnail)
|
||||
.into(imageThumbnail)
|
||||
else
|
||||
Glide.with(imageThumbnail)
|
||||
.load(R.drawable.placeholder_channel_thumbnail)
|
||||
.into(imageThumbnail);
|
||||
if (thumbnail != null)
|
||||
Glide.with(imageThumbnailBackground)
|
||||
.load(thumbnail)
|
||||
.placeholder(R.drawable.placeholder_channel_thumbnail)
|
||||
.into(imageThumbnailBackground)
|
||||
else
|
||||
Glide.with(imageThumbnailBackground)
|
||||
.load(R.drawable.placeholder_channel_thumbnail)
|
||||
.into(imageThumbnailBackground);
|
||||
|
||||
}
|
||||
|
||||
fun setName(str: String){
|
||||
textName.text = str;
|
||||
}
|
||||
fun setMetadata(str: String) {
|
||||
textMetadata.text = str;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.futo.platformplayer.views
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
|
||||
class LibraryTypeHeaderView: ConstraintLayout {
|
||||
|
||||
var selected: SelectedType = SelectedType.Artists;
|
||||
|
||||
val pillArtist: PillV2;
|
||||
val pillAlbums: PillV2;
|
||||
val textMetadata: TextView;
|
||||
val pills: List<PillV2>
|
||||
|
||||
val onSelectedChanged = Event1<SelectedType>();
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
inflate(context, R.layout.view_library_type_header, this)
|
||||
|
||||
textMetadata = findViewById(R.id.text_metadata);
|
||||
pillArtist = findViewById(R.id.pill_artist);
|
||||
pillAlbums = findViewById(R.id.pill_albums);
|
||||
|
||||
pillArtist.onClick.subscribe {
|
||||
setSelectedType(SelectedType.Artists, true);
|
||||
}
|
||||
pillAlbums.onClick.subscribe {
|
||||
setSelectedType(SelectedType.Albums, true);
|
||||
}
|
||||
|
||||
pills = listOf(pillArtist, pillAlbums);
|
||||
|
||||
setSelectedType(SelectedType.Artists, false);
|
||||
}
|
||||
|
||||
fun setMetadata(str: String) {
|
||||
textMetadata.text = str;
|
||||
}
|
||||
|
||||
fun setSelectedType(selected: SelectedType, notify: Boolean = false){
|
||||
this.selected = selected;
|
||||
|
||||
pills.forEach { it.setIsEnabled(false) };
|
||||
|
||||
when(selected) {
|
||||
SelectedType.Artists -> {
|
||||
pillArtist.setIsEnabled(true);
|
||||
}
|
||||
SelectedType.Albums -> {
|
||||
pillAlbums.setIsEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
if(notify)
|
||||
onSelectedChanged.emit(selected);
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum class SelectedType {
|
||||
Artists,
|
||||
Albums
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.futo.platformplayer.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
|
||||
class PillV2: FrameLayout {
|
||||
|
||||
val root: FrameLayout;
|
||||
val text: TextView;
|
||||
|
||||
var isToggled: Boolean = false;
|
||||
|
||||
val onClick = Event1<Boolean>();
|
||||
|
||||
constructor(context: Context, attr: AttributeSet? = null) : super(context, attr) {
|
||||
inflate(context, R.layout.view_tag_v2, this);
|
||||
root = findViewById(R.id.root);
|
||||
text = findViewById(R.id.text_tag);
|
||||
|
||||
val attrArr = context.obtainStyledAttributes(attr, R.styleable.PillV2, 0, 0);
|
||||
val attrEnabled = attrArr.getBoolean(R.styleable.PillV2_pillV2Enabled, false);
|
||||
val attrText = attrArr.getText(R.styleable.PillV2_pillV2Text) ?: "";
|
||||
text.text = attrText;
|
||||
setIsEnabled(attrEnabled);
|
||||
|
||||
setOnClickListener {
|
||||
setIsEnabled(!isToggled);
|
||||
onClick.emit(isToggled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun setText(text: String) {
|
||||
this.text.text = text;
|
||||
}
|
||||
|
||||
fun setIsEnabled(enabled: Boolean = true) {
|
||||
if(enabled)
|
||||
root.setBackgroundResource(R.drawable.background_2e_round_4dp)
|
||||
else
|
||||
root.setBackgroundResource(R.drawable.background_black_2e_round_4dp);
|
||||
this.isToggled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -5,9 +5,12 @@ import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import com.bumptech.glide.Glide
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
import com.futo.platformplayer.dp
|
||||
import com.futo.platformplayer.states.Album
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
|
||||
@@ -19,12 +22,14 @@ class AlbumTileViewHolder(val _viewGroup: ViewGroup) : AnyAdapter.AnyViewHolder<
|
||||
|
||||
val onClick = Event1<Album?>();
|
||||
|
||||
protected var _root: ConstraintLayout;
|
||||
protected var _album: Album? = null;
|
||||
protected val _imageThumbnail: ImageView
|
||||
protected val _textName: TextView
|
||||
protected val _textMetadata: TextView
|
||||
|
||||
init {
|
||||
_root = _view.findViewById(R.id.root);
|
||||
_imageThumbnail = _view.findViewById(R.id.image_thumbnail);
|
||||
_textName = _view.findViewById(R.id.text_name);
|
||||
_textMetadata = _view.findViewById(R.id.text_metadata);
|
||||
@@ -32,6 +37,25 @@ class AlbumTileViewHolder(val _viewGroup: ViewGroup) : AnyAdapter.AnyViewHolder<
|
||||
_view.setOnClickListener { onClick.emit(_album) };
|
||||
}
|
||||
|
||||
fun setWidth(dp: Int) {
|
||||
_root.updateLayoutParams {
|
||||
this.width = (dp - 12).dp(_viewGroup.context.resources);
|
||||
this.height = (dp + 48).dp(_viewGroup.context.resources);
|
||||
}
|
||||
_imageThumbnail.updateLayoutParams {
|
||||
this.width = (dp - 12).dp(_viewGroup.context.resources);
|
||||
this.height = (dp - 12).dp(_viewGroup.context.resources);
|
||||
}
|
||||
}
|
||||
|
||||
fun setAutoSize(totalWidth: Float) {
|
||||
val viewWidth = 98;
|
||||
val dpWidth = totalWidth;
|
||||
val columns = Math.max(((dpWidth) / viewWidth).toInt(), 1);
|
||||
val remainder = dpWidth - columns * viewWidth;
|
||||
val targetSize = viewWidth + (remainder / columns).toInt();
|
||||
setWidth(targetSize);
|
||||
}
|
||||
|
||||
override fun bind(album: Album) {
|
||||
_album = album;
|
||||
@@ -49,4 +73,12 @@ class AlbumTileViewHolder(val _viewGroup: ViewGroup) : AnyAdapter.AnyViewHolder<
|
||||
_textMetadata.text = album.artist ?: "";
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getAutoSizeColumns(totalWidth: Float): Int {
|
||||
val viewWidth = 98;
|
||||
val dpWidth = totalWidth;
|
||||
val columns = Math.max(((dpWidth) / viewWidth).toInt(), 1);
|
||||
return columns;
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.futo.platformplayer.views.adapters.viewholders
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
|
||||
import com.futo.platformplayer.api.media.models.video.IPlatformVideo
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
import com.futo.platformplayer.toHumanDuration
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
|
||||
|
||||
class TrackViewHolder(private val _viewGroup: ViewGroup) : AnyAdapter.AnyViewHolder<IPlatformContent>(
|
||||
LayoutInflater.from(_viewGroup.context).inflate(
|
||||
R.layout.list_track,
|
||||
_viewGroup, false)) {
|
||||
|
||||
val onClick = Event1<IPlatformContent>();
|
||||
val onOptions = Event1<IPlatformContent>();
|
||||
|
||||
protected var _content: IPlatformContent? = null;
|
||||
//protected val _imageThumbnail: ImageView
|
||||
protected val _textName: TextView
|
||||
protected val _textMetadata: TextView
|
||||
|
||||
protected val _imageSettings: ImageView;
|
||||
|
||||
init {
|
||||
//_imageThumbnail = _view.findViewById(R.id.image_thumbnail);
|
||||
_textName = _view.findViewById(R.id.text_name);
|
||||
_textMetadata = _view.findViewById(R.id.text_metadata);
|
||||
_imageSettings = _view.findViewById(R.id.button_options);
|
||||
|
||||
_view.setOnClickListener { _content?.let { onClick.emit(it) } };
|
||||
_imageSettings.setOnClickListener { _content?.let { onOptions.emit(it) } };
|
||||
}
|
||||
|
||||
override fun bind(content: IPlatformContent) {
|
||||
_content = content;
|
||||
/*
|
||||
_imageThumbnail?.let {
|
||||
if (artist.thumbnail != null)
|
||||
Glide.with(it)
|
||||
.load(artist.thumbnail)
|
||||
.placeholder(R.drawable.placeholder_channel_thumbnail)
|
||||
.into(it)
|
||||
else
|
||||
Glide.with(it).load(R.drawable.placeholder_channel_thumbnail).into(it);
|
||||
};
|
||||
*/
|
||||
|
||||
_textName.text = content.name;
|
||||
|
||||
val metaComps = listOf(
|
||||
if(content is IPlatformVideo) "${content.duration.toHumanDuration(false)}" else null
|
||||
).filterNotNull();
|
||||
|
||||
_textMetadata.text = metaComps.joinToString(", ");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#2e2e2e" />
|
||||
<corners android:radius="4dp" />
|
||||
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
|
||||
<stroke android:width="1dp" android:color="#2e2e2e" />
|
||||
</shape>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#000000" />
|
||||
<corners android:radius="4dp" />
|
||||
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
|
||||
<stroke android:width="1dp" android:color="#2e2e2e" />
|
||||
</shape>
|
||||
@@ -0,0 +1,21 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="428dp"
|
||||
android:height="230dp"
|
||||
android:viewportWidth="428"
|
||||
android:viewportHeight="201">
|
||||
<path
|
||||
android:pathData="M0,0h428v201h-428z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="214"
|
||||
android:startY="0"
|
||||
android:endX="214"
|
||||
android:endY="201"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#AA0A0A0A"/>
|
||||
<item android:offset="1" android:color="#FF000000"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
</vector>
|
||||
@@ -6,8 +6,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:id="@+id/root"
|
||||
android:clickable="true">
|
||||
|
||||
@@ -33,6 +31,7 @@
|
||||
android:fontFamily="@font/inter_light"
|
||||
tools:text="Legendary grant recipient: Marvin Wißfeld Very Long Title That is Long"
|
||||
android:maxLines="2"
|
||||
android:layout_marginTop="5dp"
|
||||
app:layout_constraintLeft_toRightOf="@id/image_thumbnail"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/button_trash"
|
||||
@@ -47,6 +46,7 @@
|
||||
android:textSize="10dp"
|
||||
android:textColor="@color/gray_e0"
|
||||
android:fontFamily="@font/inter_extra_light"
|
||||
android:layout_marginBottom="5dp"
|
||||
tools:text="3 videos"
|
||||
android:maxLines="1"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_name"
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_width="86dp"
|
||||
android:layout_height="146dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginRight="6dp"
|
||||
@@ -15,13 +15,15 @@
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/image_thumbnail"
|
||||
android:layout_height="86dp"
|
||||
android:layout_width="86dp"
|
||||
android:layout_width="0dp"
|
||||
android:scaleType="centerCrop"
|
||||
app:layout_constraintDimensionRatio="H,1,1"
|
||||
app:shapeAppearanceOverlay="@style/roundedCorners_4dp"
|
||||
app:srcCompat="@drawable/unknown_music"
|
||||
android:background="@drawable/video_thumbnail_outline"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent" />
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_name"
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
android:id="@+id/root"
|
||||
android:clickable="true"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingTop="10dp">
|
||||
android:paddingRight="10dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_name"
|
||||
@@ -21,8 +19,9 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="13dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
tools:text="Example Artist"
|
||||
android:maxLines="1"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
@@ -37,6 +36,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="10dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:textColor="@color/gray_e0"
|
||||
android:fontFamily="@font/inter_extra_light"
|
||||
tools:text="3 videos"
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:id="@+id/root"
|
||||
android:clickable="true"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="13dp"
|
||||
android:layout_marginTop="15dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
tools:text="Example Artist"
|
||||
android:maxLines="1"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/button_options"
|
||||
android:layout_marginRight="20dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/text_metadata"
|
||||
android:layout_marginStart="10dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_metadata"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="10dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:textColor="#595959"
|
||||
android:fontFamily="@font/inter_regular"
|
||||
tools:text="3 videos"
|
||||
android:maxLines="1"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_name"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/button_options"
|
||||
android:layout_marginRight="20dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginStart="10dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/button_options"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:src="@drawable/ic_settings"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<!--
|
||||
<ImageButton
|
||||
android:id="@+id/button_play"
|
||||
android:layout_width="34dp"
|
||||
android:layout_height="34dp"
|
||||
app:srcCompat="@drawable/ic_play_white_nopad"
|
||||
android:scaleType="fitCenter"
|
||||
android:padding="8dp"
|
||||
app:layout_constraintRight_toLeftOf="@id/button_trash"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginEnd="10dp"/> -->
|
||||
|
||||
<View
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1px"
|
||||
android:background="#181818" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,179 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/root">
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/transparent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:elevation="0dp">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="0dp"
|
||||
app:layout_scrollFlags="scroll"
|
||||
app:contentInsetStart="0dp"
|
||||
app:contentInsetEnd="0dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="230dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_thumbnail_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:srcCompat="@drawable/background_thumbnail_live"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:srcCompat="@drawable/bottom_gradient_dark"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-220dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent">
|
||||
<ImageView
|
||||
android:id="@+id/image_thumbnail"
|
||||
android:layout_width="108dp"
|
||||
android:layout_height="108dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="30dp"
|
||||
app:srcCompat="@drawable/background_thumbnail_live"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter_medium"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18dp"
|
||||
tools:text="Playlist name"
|
||||
android:layout_marginTop="10dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/image_thumbnail"
|
||||
app:layout_constraintLeft_toLeftOf="@id/container_buttons"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/text_metadata"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_metadata"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter_extra_light"
|
||||
android:textColor="#595959"
|
||||
android:textSize="14dp"
|
||||
tools:text="15 tracks - 1h 15 minutes"
|
||||
android:layout_marginBottom="15dp"
|
||||
app:layout_constraintLeft_toLeftOf="@id/container_buttons"
|
||||
app:layout_constraintBottom_toTopOf="@id/container_buttons"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="horizontal">
|
||||
<LinearLayout
|
||||
android:id="@+id/button_play_all"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/background_button_primary_round"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:scaleType="fitCenter"
|
||||
app:srcCompat="@drawable/ic_play_white_nopad"
|
||||
android:layout_marginEnd="10dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16dp"
|
||||
android:text="@string/play_all" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/button_shuffle"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/background_button_round"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="5dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:scaleType="fitCenter"
|
||||
app:srcCompat="@drawable/ic_shuffle"
|
||||
android:layout_marginEnd="5dp"
|
||||
app:tint="@color/white" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/inter_light"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16dp"
|
||||
android:text="@string/shuffle" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<com.futo.platformplayer.views.SearchView
|
||||
android:id="@+id/search_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-10dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@+id/container_buttons"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/root">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container_tags"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_margin="7dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.futo.platformplayer.views.PillV2
|
||||
android:id="@+id/pill_artist"
|
||||
app:pillV2Text="Artist"
|
||||
android:layout_margin="3dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<com.futo.platformplayer.views.PillV2
|
||||
android:id="@+id/pill_albums"
|
||||
app:pillV2Text="Albums"
|
||||
android:layout_margin="3dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_metadata"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:layout_margin="3dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="13sp"
|
||||
android:textColor="#D0D0D0"
|
||||
android:text="0 artists"
|
||||
app:layout_constraintLeft_toLeftOf="@id/container_tags"
|
||||
app:layout_constraintTop_toBottomOf="@id/container_tags"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingBottom="6dp"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:background="@drawable/background_black_2e_round_4dp"
|
||||
android:id="@+id/root">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_tag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/white"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:textSize="11dp"
|
||||
android:fontFamily="@font/inter_light"
|
||||
tools:text="Artist" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="PillV2">
|
||||
<attr name="pillV2Enabled" format="boolean" />
|
||||
<attr name="pillV2Text" format="string" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user