mirror of
https://github.com/clangen/musikcube.git
synced 2024-10-02 04:52:32 +00:00
Deeper down the rabbit hole...
This commit is contained in:
parent
3ac54e633d
commit
fb5f0b5663
@ -10,6 +10,7 @@ import io.casey.musikcube.remote.ui.category.fragment.CategoryBrowseFragment
|
||||
import io.casey.musikcube.remote.ui.home.activity.MainActivity
|
||||
import io.casey.musikcube.remote.ui.home.view.MainMetadataView
|
||||
import io.casey.musikcube.remote.ui.playqueue.activity.PlayQueueActivity
|
||||
import io.casey.musikcube.remote.ui.playqueue.fragment.PlayQueueFragment
|
||||
import io.casey.musikcube.remote.ui.settings.activity.ConnectionsActivity
|
||||
import io.casey.musikcube.remote.ui.settings.activity.RemoteEqActivity
|
||||
import io.casey.musikcube.remote.ui.settings.activity.RemoteSettingsActivity
|
||||
@ -38,9 +39,10 @@ interface ViewComponent {
|
||||
fun inject(activity: SettingsActivity)
|
||||
fun inject(activity: TrackListActivity)
|
||||
|
||||
fun inject(fragment: BaseFragment)
|
||||
fun inject(fragment: AlbumBrowseFragment)
|
||||
fun inject(fragment: BaseFragment)
|
||||
fun inject(fragment: CategoryBrowseFragment)
|
||||
fun inject(fragment: PlayQueueFragment)
|
||||
fun inject(fragment: TrackListFragment)
|
||||
|
||||
fun inject(view: EmptyListView)
|
||||
|
@ -9,11 +9,11 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||
import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.service.playback.impl.remote.Metadata
|
||||
import io.casey.musikcube.remote.service.websocket.model.IAlbum
|
||||
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
||||
import io.casey.musikcube.remote.ui.albums.adapter.AlbumBrowseAdapter
|
||||
import io.casey.musikcube.remote.ui.albums.constant.Album
|
||||
import io.casey.musikcube.remote.ui.navigation.Navigate
|
||||
import io.casey.musikcube.remote.ui.shared.activity.IFilterable
|
||||
import io.casey.musikcube.remote.ui.shared.activity.ITitleProvider
|
||||
import io.casey.musikcube.remote.ui.shared.activity.ITransportObserver
|
||||
@ -24,8 +24,6 @@ import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.ItemContextMenuMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
|
||||
import io.casey.musikcube.remote.ui.shared.view.EmptyListView
|
||||
import io.casey.musikcube.remote.ui.tracks.activity.TrackListActivity
|
||||
import io.casey.musikcube.remote.ui.tracks.fragment.TrackListFragment
|
||||
import io.casey.musikcube.remote.util.Debouncer
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
|
||||
@ -119,26 +117,7 @@ class AlbumBrowseFragment: BaseFragment(), IFilterable, ITitleProvider, ITranspo
|
||||
|
||||
private val eventListener = object: AlbumBrowseAdapter.EventListener {
|
||||
override fun onItemClicked(album: IAlbum) {
|
||||
when (pushContainerId > 0) {
|
||||
true ->
|
||||
pushWithToolbar(
|
||||
pushContainerId,
|
||||
"TracksForAlbum($album.id)",
|
||||
TrackListFragment.create(
|
||||
TrackListFragment.arguments(
|
||||
appCompatActivity,
|
||||
Metadata.Category.ALBUM,
|
||||
album.id,
|
||||
album.value))
|
||||
.pushTo(pushContainerId))
|
||||
false ->
|
||||
startActivity(
|
||||
TrackListActivity.getStartIntent(
|
||||
appCompatActivity,
|
||||
Metadata.Category.ALBUM,
|
||||
album.id,
|
||||
album.value))
|
||||
}
|
||||
Navigate.toAlbum(album, appCompatActivity, this@AlbumBrowseFragment)
|
||||
}
|
||||
|
||||
override fun onActionClicked(view: View, album: IAlbum) {
|
||||
|
@ -14,6 +14,7 @@ import io.casey.musikcube.remote.ui.shared.activity.ITransportObserver
|
||||
import io.casey.musikcube.remote.ui.shared.extension.enableUpNavigation
|
||||
import io.casey.musikcube.remote.ui.shared.extension.find
|
||||
import io.casey.musikcube.remote.ui.shared.extension.findFragment
|
||||
import io.casey.musikcube.remote.ui.shared.extension.pushTo
|
||||
import io.casey.musikcube.remote.ui.shared.fragment.TransportFragment
|
||||
|
||||
class BrowseActivity: BaseActivity() {
|
||||
@ -59,7 +60,9 @@ class BrowseActivity: BaseActivity() {
|
||||
BrowseFragment.TAG)
|
||||
.add(
|
||||
R.id.transport_container,
|
||||
TransportFragment.create(),
|
||||
TransportFragment
|
||||
.create()
|
||||
.pushTo(R.id.content_container),
|
||||
TransportFragment.TAG)
|
||||
.commit()
|
||||
|
||||
|
@ -15,8 +15,7 @@ import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.service.playback.impl.remote.Metadata
|
||||
import io.casey.musikcube.remote.service.websocket.model.ICategoryValue
|
||||
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
||||
import io.casey.musikcube.remote.ui.albums.activity.AlbumBrowseActivity
|
||||
import io.casey.musikcube.remote.ui.albums.fragment.AlbumBrowseFragment
|
||||
import io.casey.musikcube.remote.ui.navigation.Navigate
|
||||
import io.casey.musikcube.remote.ui.category.adapter.CategoryBrowseAdapter
|
||||
import io.casey.musikcube.remote.ui.category.constant.Category
|
||||
import io.casey.musikcube.remote.ui.category.constant.NavigationType
|
||||
@ -31,8 +30,6 @@ import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.ItemContextMenuMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
|
||||
import io.casey.musikcube.remote.ui.shared.view.EmptyListView
|
||||
import io.casey.musikcube.remote.ui.tracks.activity.TrackListActivity
|
||||
import io.casey.musikcube.remote.ui.tracks.fragment.TrackListFragment
|
||||
import io.casey.musikcube.remote.util.Debouncer
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
|
||||
@ -192,33 +189,10 @@ class CategoryBrowseFragment: BaseFragment(), IFilterable, ITitleProvider, ITran
|
||||
}
|
||||
|
||||
private fun navigateToAlbums(entry: ICategoryValue) =
|
||||
when (pushContainerId > 0) {
|
||||
true ->
|
||||
this.pushWithToolbar(
|
||||
pushContainerId,
|
||||
"AlbumsBy($entry.value)",
|
||||
AlbumBrowseFragment
|
||||
.create(app, entry.type, entry.id, entry.value)
|
||||
.pushTo(pushContainerId))
|
||||
false ->
|
||||
startActivity(AlbumBrowseActivity
|
||||
.getStartIntent(appCompatActivity, category, entry))
|
||||
|
||||
}
|
||||
Navigate.toAlbums(category, entry, appCompatActivity, this)
|
||||
|
||||
private fun navigateToTracks(entry: ICategoryValue) =
|
||||
when (this.pushContainerId > 0) {
|
||||
true ->
|
||||
this.pushWithToolbar(
|
||||
this.pushContainerId,
|
||||
"TracksBy($entry.value)",
|
||||
TrackListFragment.create(TrackListFragment
|
||||
.arguments(appCompatActivity, entry.type, entry.id))
|
||||
.pushTo(pushContainerId))
|
||||
false ->
|
||||
startActivity(TrackListActivity.getStartIntent(
|
||||
appCompatActivity, category, entry.id, entry.value))
|
||||
}
|
||||
Navigate.toTracks(category, entry, appCompatActivity, this)
|
||||
|
||||
private fun navigateToSelect(id: Long, name: String) =
|
||||
appCompatActivity.run {
|
||||
|
@ -0,0 +1,96 @@
|
||||
package io.casey.musikcube.remote.ui.navigation
|
||||
|
||||
import android.content.Intent
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import io.casey.musikcube.remote.service.playback.impl.remote.Metadata
|
||||
import io.casey.musikcube.remote.service.websocket.model.IAlbum
|
||||
import io.casey.musikcube.remote.service.websocket.model.ICategoryValue
|
||||
import io.casey.musikcube.remote.ui.albums.activity.AlbumBrowseActivity
|
||||
import io.casey.musikcube.remote.ui.albums.fragment.AlbumBrowseFragment
|
||||
import io.casey.musikcube.remote.ui.playqueue.activity.PlayQueueActivity
|
||||
import io.casey.musikcube.remote.ui.playqueue.fragment.PlayQueueFragment
|
||||
import io.casey.musikcube.remote.ui.shared.extension.pushContainerId
|
||||
import io.casey.musikcube.remote.ui.shared.extension.pushWithToolbar
|
||||
import io.casey.musikcube.remote.ui.shared.fragment.BaseFragment
|
||||
import io.casey.musikcube.remote.ui.tracks.activity.TrackListActivity
|
||||
import io.casey.musikcube.remote.ui.tracks.fragment.TrackListFragment
|
||||
|
||||
object Navigate {
|
||||
fun toAlbums(category: String,
|
||||
entry: ICategoryValue,
|
||||
activity: AppCompatActivity,
|
||||
fragment: BaseFragment? = null) =
|
||||
when (fragment != null && fragment.pushContainerId > 0) {
|
||||
true ->
|
||||
fragment.pushWithToolbar(
|
||||
fragment.pushContainerId,
|
||||
"AlbumsBy($entry.value)",
|
||||
AlbumBrowseFragment.create(activity, category, entry.id, entry.value))
|
||||
false ->
|
||||
activity.startActivity(AlbumBrowseActivity
|
||||
.getStartIntent(activity, category, entry))
|
||||
|
||||
}
|
||||
|
||||
fun toAlbums(activity: AppCompatActivity,
|
||||
fragment: BaseFragment? = null) =
|
||||
when (fragment != null && fragment.pushContainerId > 0) {
|
||||
true ->
|
||||
fragment.pushWithToolbar(
|
||||
fragment.pushContainerId,
|
||||
"AllAlbums",
|
||||
AlbumBrowseFragment.create(activity),
|
||||
Transition.Vertical)
|
||||
false ->
|
||||
activity.startActivity(AlbumBrowseActivity.getStartIntent(activity))
|
||||
}
|
||||
|
||||
fun toAlbum(album: IAlbum,
|
||||
activity: AppCompatActivity,
|
||||
fragment: BaseFragment? = null) =
|
||||
when (fragment != null && fragment.pushContainerId > 0) {
|
||||
true ->
|
||||
fragment.pushWithToolbar(
|
||||
fragment.pushContainerId,
|
||||
"TracksForAlbum($album.id)",
|
||||
TrackListFragment.create(
|
||||
TrackListFragment.arguments(
|
||||
activity, Metadata.Category.ALBUM, album.id, album.value)))
|
||||
false ->
|
||||
activity.startActivity(
|
||||
TrackListActivity.getStartIntent(
|
||||
activity, Metadata.Category.ALBUM, album.id, album.value))
|
||||
}
|
||||
|
||||
fun toTracks(category: String,
|
||||
entry: ICategoryValue,
|
||||
activity: AppCompatActivity,
|
||||
fragment: BaseFragment? = null) =
|
||||
when (fragment != null && fragment.pushContainerId > 0) {
|
||||
true ->
|
||||
fragment.pushWithToolbar(
|
||||
fragment.pushContainerId,
|
||||
"TracksBy($entry.value)",
|
||||
TrackListFragment.create(TrackListFragment.arguments(activity, entry.type, entry.id)))
|
||||
false ->
|
||||
activity.startActivity(TrackListActivity.getStartIntent(
|
||||
activity, category, entry.id, entry.value))
|
||||
}
|
||||
|
||||
fun toPlayQueue(playingIndex: Int,
|
||||
activity: AppCompatActivity,
|
||||
fragment: BaseFragment? = null) {
|
||||
when (fragment != null && fragment.pushContainerId > 0) {
|
||||
true ->
|
||||
fragment.pushWithToolbar(
|
||||
fragment.pushContainerId,
|
||||
PlayQueueFragment.TAG,
|
||||
PlayQueueFragment.create(playingIndex),
|
||||
Transition.Vertical)
|
||||
false ->
|
||||
activity.startActivity(PlayQueueActivity
|
||||
.getStartIntent(activity, playingIndex)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP))
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package io.casey.musikcube.remote.ui.navigation
|
||||
|
||||
enum class Transition {
|
||||
Horizontal, Vertical
|
||||
}
|
@ -2,142 +2,27 @@ package io.casey.musikcube.remote.ui.playqueue.activity
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||
import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||
import io.casey.musikcube.remote.ui.playqueue.adapter.PlayQueueAdapter
|
||||
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
||||
import io.casey.musikcube.remote.ui.shared.extension.addTransportFragment
|
||||
import io.casey.musikcube.remote.ui.shared.extension.enableUpNavigation
|
||||
import io.casey.musikcube.remote.ui.shared.extension.setTitleFromIntent
|
||||
import io.casey.musikcube.remote.ui.shared.extension.setupDefaultRecyclerView
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.ItemContextMenuMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
|
||||
import io.casey.musikcube.remote.ui.shared.model.DefaultSlidingWindow
|
||||
import io.casey.musikcube.remote.ui.shared.model.ITrackListSlidingWindow
|
||||
import io.casey.musikcube.remote.ui.shared.view.EmptyListView
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
import io.casey.musikcube.remote.ui.navigation.Transition
|
||||
import io.casey.musikcube.remote.ui.playqueue.constant.PlayQueue
|
||||
import io.casey.musikcube.remote.ui.playqueue.fragment.PlayQueueFragment
|
||||
import io.casey.musikcube.remote.ui.shared.activity.FragmentActivityWithTransport
|
||||
import io.casey.musikcube.remote.ui.shared.fragment.BaseFragment
|
||||
|
||||
class PlayQueueActivity : BaseActivity() {
|
||||
private var offlineQueue: Boolean = false
|
||||
private lateinit var data: DataProviderMixin
|
||||
private lateinit var playback: PlaybackMixin
|
||||
private lateinit var tracks: DefaultSlidingWindow
|
||||
private lateinit var adapter: PlayQueueAdapter
|
||||
private lateinit var emptyView: EmptyListView
|
||||
class PlayQueueActivity : FragmentActivityWithTransport() {
|
||||
override fun createContentFragment(): BaseFragment =
|
||||
PlayQueueFragment.create(extras.getInt(
|
||||
PlayQueue.Extra.PLAYING_INDEX, 0))
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
component.inject(this)
|
||||
|
||||
data = mixin(DataProviderMixin())
|
||||
playback = mixin(PlaybackMixin(playbackEvents))
|
||||
mixin(ItemContextMenuMixin(this))
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.recycler_view_activity)
|
||||
|
||||
val queryFactory = playback.service.playlistQueryFactory
|
||||
offlineQueue = playback.service.playlistQueryFactory.offline()
|
||||
|
||||
val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view)
|
||||
tracks = DefaultSlidingWindow(recyclerView, data.provider, queryFactory)
|
||||
tracks.setInitialPosition(intent.getIntExtra(EXTRA_PLAYING_INDEX, -1))
|
||||
tracks.setOnMetadataLoadedListener(slidingWindowListener)
|
||||
adapter = PlayQueueAdapter(tracks, playback, prefs, adapterListener)
|
||||
|
||||
setupDefaultRecyclerView(recyclerView, adapter)
|
||||
|
||||
emptyView = findViewById(R.id.empty_list_view)
|
||||
emptyView.capability = EmptyListView.Capability.OfflineOk
|
||||
emptyView.emptyMessage = getString(R.string.play_queue_empty)
|
||||
emptyView.alternateView = recyclerView
|
||||
|
||||
setTitleFromIntent(R.string.play_queue_title)
|
||||
addTransportFragment()
|
||||
enableUpNavigation()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
this.tracks.pause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
this.tracks.resume() /* needs to happen before */
|
||||
super.onResume()
|
||||
initObservers()
|
||||
if (offlineQueue) {
|
||||
tracks.requery()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
val result = super.onOptionsItemSelected(item)
|
||||
|
||||
if (item.itemId == android.R.id.home) {
|
||||
overridePendingTransition(R.anim.stay_put, R.anim.slide_down)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
super.onBackPressed()
|
||||
overridePendingTransition(R.anim.stay_put, R.anim.slide_down)
|
||||
}
|
||||
override val contentFragmentTag: String =
|
||||
PlayQueueFragment.TAG
|
||||
|
||||
override val transitionType: Transition
|
||||
get() = Transition.Vertical
|
||||
|
||||
private fun initObservers() {
|
||||
disposables.add(data.provider.observeState().subscribeBy(
|
||||
onNext = { states ->
|
||||
if (states.first == IDataProvider.State.Connected) {
|
||||
tracks.requery()
|
||||
}
|
||||
else {
|
||||
emptyView.update(states.first, adapter.itemCount)
|
||||
}
|
||||
},
|
||||
onError = {
|
||||
}))
|
||||
}
|
||||
|
||||
private val adapterListener = object: PlayQueueAdapter.EventListener {
|
||||
override fun onItemClicked(position: Int) =
|
||||
playback.service.playAt(position)
|
||||
|
||||
override fun onActionClicked(view: View, value: ITrack) {
|
||||
mixin(ItemContextMenuMixin::class.java)?.showForTrack(value, view)
|
||||
}
|
||||
}
|
||||
|
||||
private val playbackEvents = {
|
||||
if (adapter.itemCount == 0) {
|
||||
tracks.requery()
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private val slidingWindowListener = object : ITrackListSlidingWindow.OnMetadataLoadedListener {
|
||||
override fun onReloaded(count: Int) =
|
||||
emptyView.update(data.provider.state, count)
|
||||
|
||||
override fun onMetadataLoaded(offset: Int, count: Int) = Unit
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_PLAYING_INDEX = "extra_playing_index"
|
||||
|
||||
fun getStartIntent(context: Context, playingIndex: Int): Intent {
|
||||
return Intent(context, PlayQueueActivity::class.java)
|
||||
.putExtra(EXTRA_PLAYING_INDEX, playingIndex)
|
||||
.putExtra(PlayQueue.Extra.PLAYING_INDEX, playingIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package io.casey.musikcube.remote.ui.playqueue.constant
|
||||
|
||||
object PlayQueue {
|
||||
object Extra {
|
||||
const val PLAYING_INDEX = "extra_playing_index"
|
||||
}
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
package io.casey.musikcube.remote.ui.playqueue.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v4.view.ViewCompat
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||
import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||
import io.casey.musikcube.remote.ui.playqueue.adapter.PlayQueueAdapter
|
||||
import io.casey.musikcube.remote.ui.playqueue.constant.PlayQueue
|
||||
import io.casey.musikcube.remote.ui.shared.activity.ITitleProvider
|
||||
import io.casey.musikcube.remote.ui.shared.extension.*
|
||||
import io.casey.musikcube.remote.ui.shared.fragment.BaseFragment
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.ItemContextMenuMixin
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
|
||||
import io.casey.musikcube.remote.ui.shared.model.DefaultSlidingWindow
|
||||
import io.casey.musikcube.remote.ui.shared.model.ITrackListSlidingWindow
|
||||
import io.casey.musikcube.remote.ui.shared.view.EmptyListView
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
|
||||
class PlayQueueFragment: BaseFragment(), ITitleProvider {
|
||||
private var offlineQueue: Boolean = false
|
||||
private lateinit var data: DataProviderMixin
|
||||
private lateinit var playback: PlaybackMixin
|
||||
private lateinit var tracks: DefaultSlidingWindow
|
||||
private lateinit var adapter: PlayQueueAdapter
|
||||
private lateinit var emptyView: EmptyListView
|
||||
|
||||
override val title: String
|
||||
get() = getString(R.string.play_queue_title)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
component.inject(this)
|
||||
data = mixin(DataProviderMixin())
|
||||
playback = mixin(PlaybackMixin(playbackEvents))
|
||||
mixin(ItemContextMenuMixin(appCompatActivity, null, this))
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
inflater.inflate(this.getLayoutId(), container, false).apply {
|
||||
ViewCompat.setElevation(this, extras.elevation)
|
||||
|
||||
val queryFactory = playback.service.playlistQueryFactory
|
||||
offlineQueue = playback.service.playlistQueryFactory.offline()
|
||||
|
||||
val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view)
|
||||
tracks = DefaultSlidingWindow(recyclerView, data.provider, queryFactory)
|
||||
tracks.setInitialPosition(extras.getInt(PlayQueue.Extra.PLAYING_INDEX, -1))
|
||||
tracks.setOnMetadataLoadedListener(slidingWindowListener)
|
||||
adapter = PlayQueueAdapter(tracks, playback, prefs, adapterListener)
|
||||
|
||||
setupDefaultRecyclerView(recyclerView, adapter)
|
||||
initToolbarIfNecessary(appCompatActivity, this, searchMenu = false)
|
||||
|
||||
emptyView = findViewById(R.id.empty_list_view)
|
||||
emptyView.capability = EmptyListView.Capability.OfflineOk
|
||||
emptyView.emptyMessage = getString(R.string.play_queue_empty)
|
||||
emptyView.alternateView = recyclerView
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
this.tracks.pause()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
this.tracks.resume() /* needs to happen before */
|
||||
super.onResume()
|
||||
if (offlineQueue) {
|
||||
tracks.requery()
|
||||
}
|
||||
}
|
||||
|
||||
override fun initObservables() {
|
||||
disposables.add(data.provider.observeState().subscribeBy(
|
||||
onNext = { states ->
|
||||
if (states.first == IDataProvider.State.Connected) {
|
||||
tracks.requery()
|
||||
}
|
||||
else {
|
||||
emptyView.update(states.first, adapter.itemCount)
|
||||
}
|
||||
},
|
||||
onError = {
|
||||
}))
|
||||
}
|
||||
|
||||
private val adapterListener = object: PlayQueueAdapter.EventListener {
|
||||
override fun onItemClicked(position: Int) =
|
||||
playback.service.playAt(position)
|
||||
|
||||
override fun onActionClicked(view: View, value: ITrack) {
|
||||
mixin(ItemContextMenuMixin::class.java)?.showForTrack(value, view)
|
||||
}
|
||||
}
|
||||
|
||||
private val playbackEvents = {
|
||||
if (adapter.itemCount == 0) {
|
||||
tracks.requery()
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private val slidingWindowListener = object : ITrackListSlidingWindow.OnMetadataLoadedListener {
|
||||
override fun onReloaded(count: Int) =
|
||||
emptyView.update(data.provider.state, count)
|
||||
|
||||
override fun onMetadataLoaded(offset: Int, count: Int) = Unit
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "PlayQueueFragment"
|
||||
|
||||
fun create(playingIndex: Int): PlayQueueFragment =
|
||||
PlayQueueFragment().apply {
|
||||
arguments = Bundle().apply {
|
||||
putInt(PlayQueue.Extra.PLAYING_INDEX, playingIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import io.casey.musikcube.remote.service.websocket.model.IDevice
|
||||
import io.casey.musikcube.remote.service.websocket.model.IOutput
|
||||
import io.casey.musikcube.remote.service.websocket.model.ReplayGainMode
|
||||
import io.casey.musikcube.remote.service.websocket.model.TransportType
|
||||
import io.casey.musikcube.remote.ui.navigation.Transition
|
||||
import io.casey.musikcube.remote.ui.settings.viewmodel.RemoteSettingsViewModel
|
||||
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
|
||||
|
@ -17,6 +17,7 @@ import com.uacf.taskrunner.Tasks
|
||||
import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.service.playback.PlayerWrapper
|
||||
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamProxy
|
||||
import io.casey.musikcube.remote.ui.navigation.Transition
|
||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||
import io.casey.musikcube.remote.ui.settings.model.Connection
|
||||
import io.casey.musikcube.remote.ui.settings.model.ConnectionsDb
|
||||
|
@ -18,6 +18,7 @@ import io.casey.musikcube.remote.framework.MixinSet
|
||||
import io.casey.musikcube.remote.framework.ViewModel
|
||||
import io.casey.musikcube.remote.injection.DaggerViewComponent
|
||||
import io.casey.musikcube.remote.injection.ViewComponent
|
||||
import io.casey.musikcube.remote.ui.navigation.Transition
|
||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||
import io.casey.musikcube.remote.ui.shared.extension.*
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
|
||||
@ -26,10 +27,6 @@ import io.casey.musikcube.remote.ui.shared.mixin.ViewModelMixin
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
||||
abstract class BaseActivity : AppCompatActivity(), ViewModel.Provider, Runner.TaskCallbacks {
|
||||
protected enum class Transition {
|
||||
Horizontal, Vertical
|
||||
}
|
||||
|
||||
protected var disposables = CompositeDisposable()
|
||||
private set
|
||||
|
||||
|
@ -22,6 +22,7 @@ import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import io.casey.musikcube.remote.Application
|
||||
import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.ui.navigation.Transition
|
||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||
import io.casey.musikcube.remote.ui.shared.activity.IFilterable
|
||||
import io.casey.musikcube.remote.ui.shared.activity.IMenuProvider
|
||||
@ -57,6 +58,10 @@ fun Toolbar.setTitleFromIntent(defaultTitle: String) {
|
||||
this.title = if (Strings.notEmpty(title)) title else defaultTitle
|
||||
}
|
||||
|
||||
fun Toolbar.setTitleFromIntent(stringId: Int) {
|
||||
this.setTitleFromIntent(context.getString(stringId))
|
||||
}
|
||||
|
||||
fun Toolbar.collapseActionViewIfExpanded(): Boolean {
|
||||
(menu.findItem(R.id.action_search)?.actionView as? SearchView)?.let {
|
||||
if (!it.isIconified) {
|
||||
@ -167,9 +172,9 @@ fun AppCompatActivity.showDialog(dialog: DialogFragment, tag: String) {
|
||||
dialog.show(this.supportFragmentManager, tag)
|
||||
}
|
||||
|
||||
fun AppCompatActivity.slideNextUp() = overridePendingTransition(R.anim.slide_up, R.anim.stay_put)
|
||||
fun AppCompatActivity.slideNextUp() = overridePendingTransition(R.anim.slide_up, R.anim.stay_put_350)
|
||||
|
||||
fun AppCompatActivity.slideThisDown() = overridePendingTransition(R.anim.stay_put, R.anim.slide_down)
|
||||
fun AppCompatActivity.slideThisDown() = overridePendingTransition(R.anim.stay_put_350, R.anim.slide_down)
|
||||
|
||||
fun AppCompatActivity.slideNextLeft() = overridePendingTransition(R.anim.slide_left, R.anim.slide_left_bg)
|
||||
|
||||
@ -179,6 +184,19 @@ inline fun <reified T> AppCompatActivity.findFragment(tag: String): T {
|
||||
return this.supportFragmentManager.find(tag)
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* FragmentManager
|
||||
*
|
||||
*/
|
||||
val FragmentManager.topOfStack: String?
|
||||
get() {
|
||||
if (this.backStackEntryCount > 0) {
|
||||
return this.getBackStackEntryAt(this.backStackEntryCount - 1).name
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Bundle
|
||||
@ -214,20 +232,33 @@ inline fun <reified T: BaseFragment> T.pushTo(other: BaseFragment): T {
|
||||
return this
|
||||
}
|
||||
|
||||
fun BaseFragment.pushWithToolbar(containerId: Int, backstackId: String, fragment: BaseFragment) {
|
||||
fun BaseFragment.pushWithToolbar(
|
||||
containerId: Int,
|
||||
backstackId: String,
|
||||
fragment: BaseFragment,
|
||||
transition: Transition = Transition.Horizontal) {
|
||||
fragment.pushTo(containerId)
|
||||
appCompatActivity.supportFragmentManager
|
||||
.beginTransaction()
|
||||
.setCustomAnimations(
|
||||
R.anim.slide_left, R.anim.slide_left_bg,
|
||||
R.anim.slide_right_bg, R.anim.slide_right)
|
||||
.replace(
|
||||
containerId,
|
||||
fragment
|
||||
.withToolbar()
|
||||
.addElevation(appCompatActivity.supportFragmentManager),
|
||||
backstackId)
|
||||
.addToBackStack(backstackId)
|
||||
.commit()
|
||||
.beginTransaction().apply {
|
||||
if (transition == Transition.Horizontal) {
|
||||
setCustomAnimations(
|
||||
R.anim.slide_left, R.anim.slide_left_bg,
|
||||
R.anim.slide_right_bg, R.anim.slide_right)
|
||||
}
|
||||
else {
|
||||
setCustomAnimations(
|
||||
R.anim.slide_up, R.anim.stay_put_350,
|
||||
R.anim.stay_put_350, R.anim.slide_down)
|
||||
}
|
||||
replace(
|
||||
containerId,
|
||||
fragment
|
||||
.withToolbar()
|
||||
.addElevation(appCompatActivity.supportFragmentManager),
|
||||
backstackId)
|
||||
addToBackStack(backstackId)
|
||||
commit()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T: BaseFragment> T.withToolbar(): T {
|
||||
|
@ -9,9 +9,12 @@ import android.widget.TextView
|
||||
import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.service.playback.PlaybackState
|
||||
import io.casey.musikcube.remote.ui.home.activity.MainActivity
|
||||
import io.casey.musikcube.remote.ui.navigation.Navigate
|
||||
import io.casey.musikcube.remote.ui.playqueue.activity.PlayQueueActivity
|
||||
import io.casey.musikcube.remote.ui.playqueue.fragment.PlayQueueFragment
|
||||
import io.casey.musikcube.remote.ui.shared.extension.fallback
|
||||
import io.casey.musikcube.remote.ui.shared.extension.getColorCompat
|
||||
import io.casey.musikcube.remote.ui.shared.extension.topOfStack
|
||||
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
|
||||
|
||||
class TransportFragment: BaseFragment() {
|
||||
@ -55,12 +58,8 @@ class TransportFragment: BaseFragment() {
|
||||
|
||||
titleBar?.setOnClickListener {
|
||||
if (playback.service.state != PlaybackState.Stopped) {
|
||||
activity?.let { a ->
|
||||
startActivity(PlayQueueActivity
|
||||
.getStartIntent(a, playback.service.queuePosition)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP))
|
||||
|
||||
a.overridePendingTransition(R.anim.slide_up, R.anim.stay_put)
|
||||
if (appCompatActivity.supportFragmentManager.topOfStack != PlayQueueFragment.TAG) {
|
||||
Navigate.toPlayQueue(playback.service.queuePosition, appCompatActivity, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -291,15 +291,13 @@ class TrackListFragment: BaseFragment(), IFilterable, ITitleProvider, ITransport
|
||||
}
|
||||
}
|
||||
|
||||
fun create(intent: Intent?): TrackListFragment {
|
||||
return create(intent?.extras?.getBundle(Track.Extra.FRAGMENT_ARGUMENTS) ?: Bundle())
|
||||
}
|
||||
fun create(intent: Intent?): TrackListFragment =
|
||||
create(intent?.extras?.getBundle(Track.Extra.FRAGMENT_ARGUMENTS) ?: Bundle())
|
||||
|
||||
fun create(arguments: Bundle = Bundle()): TrackListFragment {
|
||||
return TrackListFragment().apply {
|
||||
fun create(arguments: Bundle = Bundle()): TrackListFragment =
|
||||
TrackListFragment().apply {
|
||||
this.arguments = arguments
|
||||
}
|
||||
}
|
||||
|
||||
private fun isValidCategory(categoryType: String?, categoryId: Long): Boolean =
|
||||
categoryType != null && categoryType.isNotEmpty() && categoryId != -1L
|
||||
|
@ -1,6 +1,6 @@
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<translate
|
||||
android:duration="250"
|
||||
android:duration="350"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:fromYDelta="100%"
|
||||
android:toYDelta="0" />
|
||||
|
7
src/musikdroid/app/src/main/res/anim/stay_put_350.xml
Normal file
7
src/musikdroid/app/src/main/res/anim/stay_put_350.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<translate
|
||||
android:duration="350"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:fromYDelta="100%"
|
||||
android:toYDelta="0" />
|
||||
</set>
|
Loading…
Reference in New Issue
Block a user