diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryAlbumFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryAlbumFragment.kt index 815d1653..18eea07e 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryAlbumFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryAlbumFragment.kt @@ -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, TrackViewHolder> { + override val feedStyle: FeedStyle = FeedStyle.THUMBNAIL; //R.layout.list_creator; + + private val _header: AlbumHeaderView; private var _album: Album? = null; private var _tracks: List? = 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): InsertedViewAdapterWithLoader { + 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"; } } } \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryAlbumsFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryAlbumsFragment.kt index 89eb63c1..68ab873c 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryAlbumsFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryAlbumsFragment.kt @@ -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, AlbumViewHolder> { + class FragView : FeedView, 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(); + 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({ listOf(); }, initialAlbums)); } - override fun createAdapter(recyclerResults: RecyclerView, context: Context, dataset: ArrayList): InsertedViewAdapterWithLoader { + override fun createAdapter(recyclerResults: RecyclerView, context: Context, dataset: ArrayList): InsertedViewAdapterWithLoader { 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(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() } diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryArtistFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryArtistFragment.kt index 4c904eb7..4bce7eea 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryArtistFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryArtistFragment.kt @@ -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, AlbumViewHolder> { + class ArtistAlbumsView : FeedView, 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): InsertedViewAdapterWithLoader { + override fun createAdapter(recyclerResults: RecyclerView, context: Context, dataset: ArrayList): InsertedViewAdapterWithLoader { 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(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( diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryArtistsFragment.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryArtistsFragment.kt index 335aa7f7..8b465176 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryArtistsFragment.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/LibraryArtistsFragment.kt @@ -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, 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(); + else -> {} + } + } + + _toolbarContentView.addView(libraryTypeHeader); + } fun onShown() { - val intialArtists = StateLibrary.instance.getArtists(ArtistOrdering.Alphabethic); - Logger.i(TAG, "Initial album count: " + intialArtists.size); - - setPager(AdhocPager({ 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({ 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(", "); } } diff --git a/app/src/main/java/com/futo/platformplayer/views/AlbumHeaderView.kt b/app/src/main/java/com/futo/platformplayer/views/AlbumHeaderView.kt new file mode 100644 index 00000000..b2eadfef --- /dev/null +++ b/app/src/main/java/com/futo/platformplayer/views/AlbumHeaderView.kt @@ -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; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/views/LibraryTypeHeaderView.kt b/app/src/main/java/com/futo/platformplayer/views/LibraryTypeHeaderView.kt new file mode 100644 index 00000000..cd11f447 --- /dev/null +++ b/app/src/main/java/com/futo/platformplayer/views/LibraryTypeHeaderView.kt @@ -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 + + val onSelectedChanged = Event1(); + + 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 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/views/PillV2.kt b/app/src/main/java/com/futo/platformplayer/views/PillV2.kt new file mode 100644 index 00000000..abea7817 --- /dev/null +++ b/app/src/main/java/com/futo/platformplayer/views/PillV2.kt @@ -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(); + + 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; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/AlbumTileViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/AlbumTileViewHolder.kt index 66d75a95..ad812307 100644 --- a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/AlbumTileViewHolder.kt +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/AlbumTileViewHolder.kt @@ -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(); + 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; + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/TrackViewHolder.kt b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/TrackViewHolder.kt new file mode 100644 index 00000000..6b2e39c5 --- /dev/null +++ b/app/src/main/java/com/futo/platformplayer/views/adapters/viewholders/TrackViewHolder.kt @@ -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( + LayoutInflater.from(_viewGroup.context).inflate( + R.layout.list_track, + _viewGroup, false)) { + + val onClick = Event1(); + val onOptions = Event1(); + + 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(", "); + } + +} \ No newline at end of file diff --git a/app/src/main/res/drawable/background_2e_round_4dp.xml b/app/src/main/res/drawable/background_2e_round_4dp.xml new file mode 100644 index 00000000..d43dbcc9 --- /dev/null +++ b/app/src/main/res/drawable/background_2e_round_4dp.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/background_black_2e_round_4dp.xml b/app/src/main/res/drawable/background_black_2e_round_4dp.xml new file mode 100644 index 00000000..57dd83db --- /dev/null +++ b/app/src/main/res/drawable/background_black_2e_round_4dp.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bottom_gradient_dark.xml b/app/src/main/res/drawable/bottom_gradient_dark.xml new file mode 100644 index 00000000..8bbcdbdc --- /dev/null +++ b/app/src/main/res/drawable/bottom_gradient_dark.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/list_album.xml b/app/src/main/res/layout/list_album.xml index ce5901b1..cf45be48 100644 --- a/app/src/main/res/layout/list_album.xml +++ b/app/src/main/res/layout/list_album.xml @@ -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" diff --git a/app/src/main/res/layout/list_album_tile.xml b/app/src/main/res/layout/list_album_tile.xml index 01f63a0e..9f25a20c 100644 --- a/app/src/main/res/layout/list_album_tile.xml +++ b/app/src/main/res/layout/list_album_tile.xml @@ -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 @@ + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" /> + android:paddingRight="10dp"> + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_album_header.xml b/app/src/main/res/layout/view_album_header.xml new file mode 100644 index 00000000..da94d3fb --- /dev/null +++ b/app/src/main/res/layout/view_album_header.xml @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_library_type_header.xml b/app/src/main/res/layout/view_library_type_header.xml new file mode 100644 index 00000000..58d1c69a --- /dev/null +++ b/app/src/main/res/layout/view_library_type_header.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_tag_v2.xml b/app/src/main/res/layout/view_tag_v2.xml new file mode 100644 index 00000000..7a5928de --- /dev/null +++ b/app/src/main/res/layout/view_tag_v2.xml @@ -0,0 +1,28 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/pill_v2_attrs.xml b/app/src/main/res/values/pill_v2_attrs.xml new file mode 100644 index 00000000..ecf860a7 --- /dev/null +++ b/app/src/main/res/values/pill_v2_attrs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file