mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2026-05-16 04:52:39 +02:00
Library work
This commit is contained in:
+81
-89
@@ -8,94 +8,52 @@ import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
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
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.core.view.allViews
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.bumptech.glide.Glide
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.UIDialogs
|
||||
import com.futo.platformplayer.UISlideOverlays
|
||||
import com.futo.platformplayer.api.media.PlatformID
|
||||
import com.futo.platformplayer.api.media.exceptions.NoPlatformClientException
|
||||
import com.futo.platformplayer.api.media.models.PlatformAuthorLink
|
||||
import com.futo.platformplayer.api.media.models.ResultCapabilities
|
||||
import com.futo.platformplayer.api.media.models.channels.IPlatformChannel
|
||||
import com.futo.platformplayer.api.media.models.channels.SerializedChannel
|
||||
import com.futo.platformplayer.api.media.models.contents.ContentType
|
||||
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
|
||||
import com.futo.platformplayer.api.media.models.playlists.IPlatformPlaylist
|
||||
import com.futo.platformplayer.api.media.models.post.IPlatformPost
|
||||
import com.futo.platformplayer.api.media.models.video.IPlatformVideo
|
||||
import com.futo.platformplayer.api.media.models.video.SerializedPlatformVideo
|
||||
import com.futo.platformplayer.api.media.platforms.local.LocalClient
|
||||
import com.futo.platformplayer.api.media.structures.AdhocPager
|
||||
import com.futo.platformplayer.api.media.structures.IPager
|
||||
import com.futo.platformplayer.assume
|
||||
import com.futo.platformplayer.constructs.Event1
|
||||
import com.futo.platformplayer.constructs.Event2
|
||||
import com.futo.platformplayer.constructs.Event3
|
||||
import com.futo.platformplayer.constructs.TaskHandler
|
||||
import com.futo.platformplayer.dp
|
||||
import com.futo.platformplayer.fragment.channel.tab.ChannelAboutFragment
|
||||
import com.futo.platformplayer.fragment.channel.tab.ChannelContentsFragment
|
||||
import com.futo.platformplayer.fragment.channel.tab.ChannelListFragment
|
||||
import com.futo.platformplayer.fragment.channel.tab.ChannelMonetizationFragment
|
||||
import com.futo.platformplayer.fragment.channel.tab.ChannelPlaylistsFragment
|
||||
import com.futo.platformplayer.fragment.channel.tab.IChannelTabFragment
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.ChannelFragment.Companion
|
||||
import com.futo.platformplayer.fragment.mainactivity.main.LibraryAlbumsFragment.AlbumViewHolder
|
||||
import com.futo.platformplayer.fragment.mainactivity.topbar.NavigationTopBarFragment
|
||||
import com.futo.platformplayer.images.GlideHelper.Companion.crossfade
|
||||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.models.SearchType
|
||||
import com.futo.platformplayer.models.Subscription
|
||||
import com.futo.platformplayer.selectBestImage
|
||||
import com.futo.platformplayer.selectHighestResolutionImage
|
||||
import com.futo.platformplayer.states.Album
|
||||
import com.futo.platformplayer.states.Artist
|
||||
import com.futo.platformplayer.states.StateLibrary
|
||||
import com.futo.platformplayer.states.StatePlatform
|
||||
import com.futo.platformplayer.states.StatePlayer
|
||||
import com.futo.platformplayer.states.StatePlaylists
|
||||
import com.futo.platformplayer.states.StatePolycentric
|
||||
import com.futo.platformplayer.states.StateSubscriptions
|
||||
import com.futo.platformplayer.stores.FragmentedStorage
|
||||
import com.futo.platformplayer.stores.StringStorage
|
||||
import com.futo.platformplayer.toHumanNumber
|
||||
import com.futo.platformplayer.views.FeedStyle
|
||||
import com.futo.platformplayer.views.ToggleBar
|
||||
import com.futo.platformplayer.views.adapters.AnyAdapter
|
||||
import com.futo.platformplayer.views.adapters.ChannelTab
|
||||
import com.futo.platformplayer.views.adapters.ChannelViewPagerAdapter
|
||||
import com.futo.platformplayer.views.adapters.InsertedViewAdapterWithLoader
|
||||
import com.futo.platformplayer.views.adapters.SubscriptionAdapter
|
||||
import com.futo.platformplayer.views.adapters.viewholders.SelectablePlaylist
|
||||
import com.futo.platformplayer.views.others.CreatorThumbnail
|
||||
import com.futo.platformplayer.views.overlays.slideup.SlideUpMenuOverlay
|
||||
import com.futo.platformplayer.views.platform.PlatformIndicator
|
||||
import com.futo.platformplayer.views.subscriptions.SubscribeButton
|
||||
import com.futo.polycentric.core.ApiMethods
|
||||
import com.futo.polycentric.core.PolycentricProfile
|
||||
import com.futo.polycentric.core.toURLInfoSystemLinkUrl
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -384,31 +342,14 @@ class LibraryArtistFragment : MainFragment() {
|
||||
|
||||
var supportsPlaylists = false;
|
||||
val playlistPosition = 1
|
||||
if (supportsPlaylists && !(_viewPager.adapter as ArtistViewPagerAdapter).containsItem(
|
||||
ArtistTab.PLAYLISTS.ordinal.toLong()
|
||||
)
|
||||
) {
|
||||
// keep the current tab selected
|
||||
if (_viewPager.currentItem >= playlistPosition) {
|
||||
_viewPager.setCurrentItem(_viewPager.currentItem + 1, false)
|
||||
}
|
||||
|
||||
(_viewPager.adapter as ArtistViewPagerAdapter).insert(
|
||||
playlistPosition,
|
||||
ArtistTab.PLAYLISTS
|
||||
ArtistTab.ALBUMS
|
||||
)
|
||||
}
|
||||
if (!supportsPlaylists && (_viewPager.adapter as ArtistViewPagerAdapter).containsItem(
|
||||
ArtistTab.PLAYLISTS.ordinal.toLong()
|
||||
)
|
||||
) {
|
||||
// keep the current tab selected
|
||||
if (_viewPager.currentItem >= playlistPosition) {
|
||||
_viewPager.setCurrentItem(_viewPager.currentItem - 1, false)
|
||||
}
|
||||
|
||||
(_viewPager.adapter as ArtistViewPagerAdapter).remove(playlistPosition)
|
||||
}
|
||||
|
||||
// sets the channel for each tab
|
||||
for (fragment in _fragment.childFragmentManager.fragments) {
|
||||
@@ -429,15 +370,15 @@ class LibraryArtistFragment : MainFragment() {
|
||||
}
|
||||
}
|
||||
enum class ArtistTab {
|
||||
VIDEOS, PLAYLISTS
|
||||
SONGS, ALBUMS
|
||||
}
|
||||
|
||||
class ArtistViewPagerAdapter(private val fragment: LibraryArtistFragment, fragmentManager: FragmentManager, lifecycle: Lifecycle) :
|
||||
FragmentStateAdapter(fragmentManager, lifecycle) {
|
||||
private val _supportedFragments = mutableMapOf(
|
||||
ArtistTab.VIDEOS.ordinal to ArtistTab.VIDEOS
|
||||
ArtistTab.SONGS.ordinal to ArtistTab.SONGS
|
||||
)
|
||||
private val _tabs = arrayListOf(ArtistTab.VIDEOS)
|
||||
private val _tabs = arrayListOf(ArtistTab.SONGS, ArtistTab.ALBUMS)
|
||||
|
||||
var artist: Artist? = null
|
||||
|
||||
@@ -486,35 +427,15 @@ class LibraryArtistFragment : MainFragment() {
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
val fragment: Fragment
|
||||
when (_tabs[position]) {
|
||||
ArtistTab.VIDEOS -> {
|
||||
ArtistTab.SONGS -> {
|
||||
fragment = ChannelContentsFragment(this.fragment).apply {
|
||||
/*
|
||||
onContentClicked.subscribe { video, num, _ ->
|
||||
this@ArtistViewPagerAdapter.onContentClicked.emit(video, num)
|
||||
}
|
||||
onContentUrlClicked.subscribe(this@ArtistViewPagerAdapter.onContentUrlClicked::emit)
|
||||
onUrlClicked.subscribe(this@ArtistViewPagerAdapter.onUrlClicked::emit)
|
||||
onChannelClicked.subscribe(this@ArtistViewPagerAdapter.onChannelClicked::emit)
|
||||
onAddToClicked.subscribe(this@ArtistViewPagerAdapter.onAddToClicked::emit)
|
||||
onAddToQueueClicked.subscribe(this@ArtistViewPagerAdapter.onAddToQueueClicked::emit)
|
||||
onAddToWatchLaterClicked.subscribe(this@ArtistViewPagerAdapter.onAddToWatchLaterClicked::emit)
|
||||
onLongPress.subscribe(this@ArtistViewPagerAdapter.onLongPress::emit)
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ArtistTab.PLAYLISTS -> {
|
||||
fragment = ChannelPlaylistsFragment.newInstance().apply {
|
||||
/*
|
||||
onContentClicked.subscribe(this@ArtistViewPagerAdapter.onContentClicked::emit)
|
||||
onContentUrlClicked.subscribe(this@ArtistViewPagerAdapter.onContentUrlClicked::emit)
|
||||
onUrlClicked.subscribe(this@ArtistViewPagerAdapter.onUrlClicked::emit)
|
||||
onChannelClicked.subscribe(this@ArtistViewPagerAdapter.onChannelClicked::emit)
|
||||
onAddToClicked.subscribe(this@ArtistViewPagerAdapter.onAddToClicked::emit)
|
||||
onAddToQueueClicked.subscribe(this@ArtistViewPagerAdapter.onAddToQueueClicked::emit)
|
||||
onAddToWatchLaterClicked.subscribe(this@ArtistViewPagerAdapter.onAddToWatchLaterClicked::emit)
|
||||
onLongPress.subscribe(this@ArtistViewPagerAdapter.onLongPress::emit)
|
||||
*/
|
||||
ArtistTab.ALBUMS -> {
|
||||
fragment = ArtistAlbumsFragment(this.fragment).apply {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -569,6 +490,77 @@ class LibraryArtistFragment : MainFragment() {
|
||||
override fun updateSpanCount(){ }
|
||||
|
||||
|
||||
companion object {
|
||||
private const val TAG = "LibraryAlbumsFragmentsView";
|
||||
}
|
||||
}
|
||||
class ArtistAlbumsFragment(private val frag: LibraryArtistFragment) : Fragment(), IArtistTabFragment {
|
||||
|
||||
var view: ArtistAlbumsView? = null;
|
||||
|
||||
private var _lastArtist: Artist? = null;
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
view = ArtistAlbumsView(frag, inflater);
|
||||
_lastArtist?.let {
|
||||
view?.setArtist(it);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
view = null;
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun setArtist(artist: Artist) {
|
||||
view?.setArtist(artist);
|
||||
_lastArtist = artist;
|
||||
}
|
||||
}
|
||||
class ArtistAlbumsView : FeedView<LibraryArtistFragment, Album, Album, IPager<Album>, AlbumViewHolder> {
|
||||
override val feedStyle: FeedStyle = FeedStyle.THUMBNAIL; //R.layout.list_creator;
|
||||
|
||||
constructor(fragment: LibraryArtistFragment, inflater: LayoutInflater) : super(fragment, inflater)
|
||||
|
||||
fun onShown() {
|
||||
}
|
||||
|
||||
fun setArtist(artist: Artist) {
|
||||
val initialAlbums = artist.getAlbums();
|
||||
Logger.i(TAG, "Initial album count: " + initialAlbums.size);
|
||||
|
||||
setPager(AdhocPager({ listOf() }, initialAlbums));
|
||||
}
|
||||
|
||||
override fun createAdapter(recyclerResults: RecyclerView, context: Context, dataset: ArrayList<Album>): InsertedViewAdapterWithLoader<AlbumViewHolder> {
|
||||
return InsertedViewAdapterWithLoader(context, arrayListOf(), arrayListOf(),
|
||||
childCountGetter = { dataset.size },
|
||||
childViewHolderBinder = { viewHolder, position -> viewHolder.bind(dataset[position]); },
|
||||
childViewHolderFactory = { viewGroup, _ ->
|
||||
val holder = AlbumViewHolder(viewGroup);
|
||||
holder.onClick.subscribe { c -> fragment.navigate<LibraryAlbumFragment>(c) };
|
||||
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
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "LibraryAlbumsFragmentsView";
|
||||
}
|
||||
|
||||
+18
-3
@@ -88,6 +88,19 @@ class LibraryArtistsFragment : MainFragment() {
|
||||
setPager(AdhocPager<Artist>({ listOf(); }, intialArtists));
|
||||
}
|
||||
|
||||
override fun reload() {
|
||||
try {
|
||||
setLoading(true);
|
||||
val intialArtists = StateLibrary.instance.getArtists();
|
||||
Logger.i(TAG, "Initial album count: " + intialArtists.size);
|
||||
|
||||
setPager(AdhocPager<Artist>({ listOf(); }, intialArtists));
|
||||
}
|
||||
finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
override fun createAdapter(recyclerResults: RecyclerView, context: Context, dataset: ArrayList<Artist>): InsertedViewAdapterWithLoader<ArtistViewHolder> {
|
||||
return InsertedViewAdapterWithLoader(context, arrayListOf(), arrayListOf(),
|
||||
childCountGetter = { dataset.size },
|
||||
@@ -123,18 +136,18 @@ class LibraryArtistsFragment : MainFragment() {
|
||||
}
|
||||
|
||||
class ArtistViewHolder(private val _viewGroup: ViewGroup) : AnyAdapter.AnyViewHolder<Artist>(
|
||||
LayoutInflater.from(_viewGroup.context).inflate(R.layout.list_album,
|
||||
LayoutInflater.from(_viewGroup.context).inflate(R.layout.list_artist,
|
||||
_viewGroup, false)) {
|
||||
|
||||
val onClick = Event1<Artist>();
|
||||
|
||||
protected var _artist: Artist? = null;
|
||||
protected val _imageThumbnail: ImageView
|
||||
//protected val _imageThumbnail: ImageView
|
||||
protected val _textName: TextView
|
||||
protected val _textMetadata: TextView
|
||||
|
||||
init {
|
||||
_imageThumbnail = _view.findViewById(R.id.image_thumbnail);
|
||||
//_imageThumbnail = _view.findViewById(R.id.image_thumbnail);
|
||||
_textName = _view.findViewById(R.id.text_name);
|
||||
_textMetadata = _view.findViewById(R.id.text_metadata);
|
||||
|
||||
@@ -143,6 +156,7 @@ class LibraryArtistsFragment : MainFragment() {
|
||||
|
||||
override fun bind(artist: Artist) {
|
||||
_artist = artist;
|
||||
/*
|
||||
_imageThumbnail?.let {
|
||||
if (artist.thumbnail != null)
|
||||
Glide.with(it)
|
||||
@@ -152,6 +166,7 @@ class LibraryArtistsFragment : MainFragment() {
|
||||
else
|
||||
Glide.with(it).load(R.drawable.placeholder_channel_thumbnail).into(it);
|
||||
};
|
||||
*/
|
||||
|
||||
_textName.text = artist.name;
|
||||
_textMetadata.text = artist.countTracks?.let { "${it} tracks" } ?: "";
|
||||
|
||||
+121
-8
@@ -7,10 +7,14 @@ import android.provider.MediaStore
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import com.futo.platformplayer.R
|
||||
import com.futo.platformplayer.UIDialogs
|
||||
import com.futo.platformplayer.activities.MainActivity
|
||||
import com.futo.platformplayer.states.StateApp
|
||||
import com.futo.platformplayer.views.buttons.BigButton
|
||||
@@ -23,9 +27,12 @@ class LibraryFragment : MainFragment() {
|
||||
|
||||
private var view: FragView? = null;
|
||||
|
||||
private var allowedMusic = false;
|
||||
private var allowedVideo = false;
|
||||
|
||||
|
||||
override fun onCreateMainView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): android.view.View {
|
||||
val newView = FragView(this);
|
||||
val newView = FragView(this, allowedMusic, allowedVideo);
|
||||
view = newView;
|
||||
return newView;
|
||||
}
|
||||
@@ -33,6 +40,9 @@ class LibraryFragment : MainFragment() {
|
||||
override fun onShownWithView(parameter: Any?, isBack: Boolean) {
|
||||
super.onShownWithView(parameter, isBack);
|
||||
view?.onShown();
|
||||
|
||||
requestPermissionMusic();
|
||||
requestPermissionVideo();
|
||||
}
|
||||
|
||||
override fun onDestroyMainView() {
|
||||
@@ -40,6 +50,63 @@ class LibraryFragment : MainFragment() {
|
||||
super.onDestroyMainView();
|
||||
}
|
||||
|
||||
fun setPermissionResultAudio(access: Boolean) {
|
||||
allowedMusic = access;
|
||||
view?.setMusicPermissions(access);
|
||||
}
|
||||
fun setPermissionResultVideo(access: Boolean) {
|
||||
allowedVideo = access;
|
||||
view?.setVideoPermissions(access);
|
||||
}
|
||||
|
||||
fun requestPermissionMusic() {
|
||||
when {
|
||||
ContextCompat.checkSelfPermission(requireContext(), android.Manifest.permission.READ_MEDIA_AUDIO) == PackageManager.PERMISSION_GRANTED -> {
|
||||
setPermissionResultAudio(true);
|
||||
}
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(), android.Manifest.permission.READ_MEDIA_AUDIO) -> {
|
||||
UIDialogs.showDialog(requireContext(), R.drawable.ic_library,
|
||||
"Music permissions", "We require permissions to see your on-device music, denying this will hide the option to see local music.", null, 1,
|
||||
UIDialogs.Action("Ok", {
|
||||
permissionReqAudio.launch(android.Manifest.permission.READ_MEDIA_AUDIO);
|
||||
}, UIDialogs.ActionStyle.PRIMARY),
|
||||
UIDialogs.Action("Cancel", {
|
||||
|
||||
}, UIDialogs.ActionStyle.NONE));
|
||||
}
|
||||
else -> {
|
||||
permissionReqAudio.launch(android.Manifest.permission.READ_MEDIA_AUDIO);
|
||||
}
|
||||
}
|
||||
}
|
||||
fun requestPermissionVideo() {
|
||||
when {
|
||||
ContextCompat.checkSelfPermission(requireContext(), android.Manifest.permission.READ_MEDIA_VIDEO) == PackageManager.PERMISSION_GRANTED -> {
|
||||
setPermissionResultVideo(true);
|
||||
}
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(), android.Manifest.permission.READ_MEDIA_VIDEO) -> {
|
||||
UIDialogs.showDialog(requireContext(), R.drawable.ic_library, false,
|
||||
"Videos permissions", "We require permissions to see your on-device videos, denying this will hide the option to see local videos.", null, 1,
|
||||
UIDialogs.Action("Ok", {
|
||||
permissionReqVideo.launch(android.Manifest.permission.READ_MEDIA_VIDEO);
|
||||
}, UIDialogs.ActionStyle.PRIMARY),
|
||||
UIDialogs.Action("Cancel", {
|
||||
|
||||
}, UIDialogs.ActionStyle.NONE));
|
||||
}
|
||||
else -> {
|
||||
permissionReqVideo.launch(android.Manifest.permission.READ_MEDIA_VIDEO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val permissionReqAudio = registerForActivityResult(ActivityResultContracts.RequestPermission(), { isGranted ->
|
||||
setPermissionResultAudio(isGranted);
|
||||
});
|
||||
val permissionReqVideo = registerForActivityResult(ActivityResultContracts.RequestPermission(), { isGranted ->
|
||||
setPermissionResultVideo(isGranted);
|
||||
});
|
||||
|
||||
companion object {
|
||||
fun newInstance() = LibraryFragment().apply {}
|
||||
}
|
||||
@@ -47,30 +114,76 @@ class LibraryFragment : MainFragment() {
|
||||
|
||||
class FragView: ConstraintLayout {
|
||||
val fragment: LibraryFragment;
|
||||
constructor(fragment: LibraryFragment, attrs : AttributeSet? = null) : super(fragment.requireContext(), attrs) {
|
||||
|
||||
var buttonArtists: BigButton;
|
||||
var buttonAlbums: BigButton;
|
||||
var buttonVideos: BigButton;
|
||||
var buttonPlaylists: BigButton;
|
||||
var buttonFiles: BigButton;
|
||||
|
||||
var metaInfo: TextView;
|
||||
|
||||
var allowMusic: Boolean = false;
|
||||
var allowVideo: Boolean = false;
|
||||
|
||||
constructor(fragment: LibraryFragment, allowMusic: Boolean?, allowVideo: Boolean?) : super(fragment.requireContext()) {
|
||||
inflate(context, R.layout.fragview_library, this);
|
||||
this.fragment = fragment;
|
||||
val buttonArtists = findViewById<BigButton>(R.id.button_artists);
|
||||
val buttonAlbums = findViewById<BigButton>(R.id.button_albums);
|
||||
val buttonVideos = findViewById<BigButton>(R.id.button_videos);
|
||||
val buttonPlaylists = findViewById<BigButton>(R.id.button_playlists);
|
||||
val buttonFiles = findViewById<BigButton>(R.id.button_files);
|
||||
buttonArtists = findViewById<BigButton>(R.id.button_artists);
|
||||
buttonAlbums = findViewById<BigButton>(R.id.button_albums);
|
||||
buttonVideos = findViewById<BigButton>(R.id.button_videos);
|
||||
buttonPlaylists = findViewById<BigButton>(R.id.button_playlists);
|
||||
buttonFiles = findViewById<BigButton>(R.id.button_files);
|
||||
metaInfo = findViewById(R.id.meta_info);
|
||||
|
||||
this.allowMusic = allowMusic ?: false;
|
||||
this.allowVideo = allowVideo ?: false;
|
||||
|
||||
buttonArtists.onClick.subscribe {
|
||||
if(this.allowMusic)
|
||||
fragment.navigate<LibraryArtistsFragment>();
|
||||
else
|
||||
fragment.requestPermissionMusic();
|
||||
}
|
||||
buttonAlbums.onClick.subscribe {
|
||||
if(this.allowMusic)
|
||||
fragment.navigate<LibraryAlbumsFragment>();
|
||||
else
|
||||
fragment.requestPermissionMusic();
|
||||
}
|
||||
buttonVideos.onClick.subscribe {
|
||||
if(this.allowVideo)
|
||||
fragment.navigate<LibraryVideosFragment>();
|
||||
else
|
||||
fragment.requestPermissionVideo();
|
||||
}
|
||||
buttonPlaylists.onClick.subscribe {
|
||||
fragment.navigate<PlaylistsFragment>();
|
||||
}
|
||||
buttonFiles.onClick.subscribe {
|
||||
|
||||
UIDialogs.appToast("This is gonna require a bit more work..");
|
||||
}
|
||||
buttonFiles.setButtonEnabled(false);
|
||||
setMusicPermissions(allowMusic ?: false);
|
||||
setVideoPermissions(allowVideo ?: false);
|
||||
}
|
||||
|
||||
fun setMusicPermissions(access: Boolean) {
|
||||
allowMusic = access;
|
||||
buttonAlbums.setButtonEnabled(access);
|
||||
buttonArtists.setButtonEnabled(access);
|
||||
metaInfo.text = listOf(
|
||||
if(!allowMusic) "You did not give access to local music, so these options are disabled" else null,
|
||||
if(!allowVideo) "You did not give access to local videos, so these options are disabled" else null
|
||||
).filterNotNull().joinToString("\n");
|
||||
}
|
||||
fun setVideoPermissions(access: Boolean) {
|
||||
allowVideo = access;
|
||||
buttonVideos.setButtonEnabled(access);
|
||||
metaInfo.text = listOf(
|
||||
if(!allowMusic) "You did not give access to local music, so these options are disabled" else null,
|
||||
if(!allowVideo) "You did not give access to local videos, so these options are disabled" else null
|
||||
).filterNotNull().joinToString("\n");
|
||||
}
|
||||
|
||||
fun onShown() {
|
||||
|
||||
@@ -271,7 +271,7 @@ class Artist {
|
||||
}
|
||||
|
||||
fun getAlbums(): List<Album> {
|
||||
return listOf();
|
||||
return Album.getArtistAlbums(id.toLongOrNull() ?: return listOf());
|
||||
}
|
||||
|
||||
fun getAudioTracks(): IPager<IPlatformContent> {
|
||||
@@ -438,5 +438,22 @@ class Album {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
fun getArtistAlbums(artistId: Long): List<Album> {
|
||||
val resolver = StateApp.instance.contextOrNull?.contentResolver;
|
||||
if(resolver == null) {
|
||||
Logger.w(TAG, "Album contentResolver not found");
|
||||
return listOf();
|
||||
}
|
||||
val cursor = resolver?.query(
|
||||
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, PROJECTION, "${MediaStore.Audio.Media.ARTIST_ID} = ?", arrayOf(artistId.toString()),
|
||||
MediaStore.Audio.Albums.ALBUM + " ASC") ?: return listOf();
|
||||
cursor.moveToFirst();
|
||||
val list = mutableListOf<Album>()
|
||||
while(!cursor.isAfterLast) {
|
||||
list.add(fromCursor(cursor));
|
||||
cursor.moveToNext();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,22 @@
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="Library UI is temporary, and will be replaced"
|
||||
android:textColor="#FFAA00" />
|
||||
<TextView
|
||||
android:id="@+id/meta_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="center"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="Library UI is temporary, and will be replaced"
|
||||
android:textColor="#AAAAAA" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?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="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:id="@+id/root"
|
||||
android:clickable="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="13dp"
|
||||
android:textColor="@color/white"
|
||||
android:fontFamily="@font/inter_light"
|
||||
tools:text="Legendary grant recipient: Marvin Wißfeld Very Long Title That is Long"
|
||||
android:maxLines="2"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
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:textColor="@color/gray_e0"
|
||||
android:fontFamily="@font/inter_extra_light"
|
||||
tools:text="3 videos"
|
||||
android:maxLines="1"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_name"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginStart="10dp" />
|
||||
|
||||
<!--
|
||||
<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"/> -->
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
Reference in New Issue
Block a user