mirror of
https://github.com/clangen/musikcube.git
synced 2024-10-02 13:02:35 +00:00
Added context menu to PlayQueueActivity and PlayQueueAdapter.
This commit is contained in:
parent
a573265092
commit
93f1980b77
@ -3,13 +3,13 @@ package io.casey.musikcube.remote
|
|||||||
import android.arch.persistence.room.Room
|
import android.arch.persistence.room.Room
|
||||||
import com.crashlytics.android.Crashlytics
|
import com.crashlytics.android.Crashlytics
|
||||||
import com.facebook.stetho.Stetho
|
import com.facebook.stetho.Stetho
|
||||||
import io.casey.musikcube.remote.ui.settings.model.ConnectionsDb
|
|
||||||
import io.casey.musikcube.remote.service.playback.impl.streaming.offline.OfflineDb
|
|
||||||
import io.casey.musikcube.remote.injection.DaggerAppComponent
|
|
||||||
import io.casey.musikcube.remote.injection.AppComponent
|
import io.casey.musikcube.remote.injection.AppComponent
|
||||||
import io.casey.musikcube.remote.injection.AppModule
|
import io.casey.musikcube.remote.injection.AppModule
|
||||||
|
import io.casey.musikcube.remote.injection.DaggerAppComponent
|
||||||
import io.casey.musikcube.remote.injection.ServiceModule
|
import io.casey.musikcube.remote.injection.ServiceModule
|
||||||
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamProxy
|
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamProxy
|
||||||
|
import io.casey.musikcube.remote.service.playback.impl.streaming.offline.OfflineDb
|
||||||
|
import io.casey.musikcube.remote.ui.settings.model.ConnectionsDb
|
||||||
import io.casey.musikcube.remote.ui.shared.util.NetworkUtil
|
import io.casey.musikcube.remote.ui.shared.util.NetworkUtil
|
||||||
import io.fabric.sdk.android.Fabric
|
import io.fabric.sdk.android.Fabric
|
||||||
|
|
||||||
|
@ -2,14 +2,12 @@ package io.casey.musikcube.remote.injection
|
|||||||
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
|
||||||
import io.casey.musikcube.remote.model.impl.remote.RemoteDataProvider
|
|
||||||
import io.casey.musikcube.remote.service.websocket.WebSocketService
|
import io.casey.musikcube.remote.service.websocket.WebSocketService
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.impl.remote.RemoteDataProvider
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
class DataModule {
|
class DataModule {
|
||||||
@Provides
|
@Provides
|
||||||
fun providesDataProvider(wss: WebSocketService): IDataProvider {
|
fun providesDataProvider(wss: WebSocketService): IDataProvider = RemoteDataProvider(wss)
|
||||||
return RemoteDataProvider(wss)
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -11,9 +11,9 @@ import com.bumptech.glide.load.model.GlideUrl
|
|||||||
import com.bumptech.glide.module.AppGlideModule
|
import com.bumptech.glide.module.AppGlideModule
|
||||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
|
import java.io.InputStream
|
||||||
import io.casey.musikcube.remote.ui.shared.model.albumart.canIntercept as canInterceptArtwork
|
import io.casey.musikcube.remote.ui.shared.model.albumart.canIntercept as canInterceptArtwork
|
||||||
import io.casey.musikcube.remote.ui.shared.model.albumart.intercept as interceptArtwork
|
import io.casey.musikcube.remote.ui.shared.model.albumart.intercept as interceptArtwork
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
@GlideModule
|
@GlideModule
|
||||||
class GlideModule : AppGlideModule() {
|
class GlideModule : AppGlideModule() {
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
package io.casey.musikcube.remote.injection
|
package io.casey.musikcube.remote.injection
|
||||||
|
|
||||||
import dagger.Component
|
import dagger.Component
|
||||||
import io.casey.musikcube.remote.ui.home.activity.MainActivity
|
|
||||||
import io.casey.musikcube.remote.ui.category.activity.*
|
|
||||||
import io.casey.musikcube.remote.ui.albums.activity.AlbumBrowseActivity
|
import io.casey.musikcube.remote.ui.albums.activity.AlbumBrowseActivity
|
||||||
import io.casey.musikcube.remote.ui.playqueue.activity.PlayQueueActivity
|
import io.casey.musikcube.remote.ui.category.activity.CategoryBrowseActivity
|
||||||
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
import io.casey.musikcube.remote.ui.home.activity.MainActivity
|
||||||
import io.casey.musikcube.remote.ui.shared.view.EmptyListView
|
|
||||||
import io.casey.musikcube.remote.ui.home.view.MainMetadataView
|
import io.casey.musikcube.remote.ui.home.view.MainMetadataView
|
||||||
|
import io.casey.musikcube.remote.ui.playqueue.activity.PlayQueueActivity
|
||||||
import io.casey.musikcube.remote.ui.settings.activity.ConnectionsActivity
|
import io.casey.musikcube.remote.ui.settings.activity.ConnectionsActivity
|
||||||
import io.casey.musikcube.remote.ui.settings.activity.SettingsActivity
|
import io.casey.musikcube.remote.ui.settings.activity.SettingsActivity
|
||||||
|
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
||||||
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
|
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.ItemContextMenuMixin
|
||||||
|
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.activity.TrackListActivity
|
||||||
|
|
||||||
@ViewScope
|
@ViewScope
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package io.casey.musikcube.remote.service.playback
|
package io.casey.musikcube.remote.service.playback
|
||||||
|
|
||||||
import io.casey.musikcube.remote.Application
|
import io.casey.musikcube.remote.Application
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
|
||||||
import io.casey.musikcube.remote.service.playback.impl.streaming.offline.OfflineTrack
|
|
||||||
import io.casey.musikcube.remote.service.playback.impl.player.ExoPlayerWrapper
|
import io.casey.musikcube.remote.service.playback.impl.player.ExoPlayerWrapper
|
||||||
import io.casey.musikcube.remote.service.playback.impl.player.MediaPlayerWrapper
|
import io.casey.musikcube.remote.service.playback.impl.player.MediaPlayerWrapper
|
||||||
|
import io.casey.musikcube.remote.service.playback.impl.streaming.offline.OfflineTrack
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
import io.casey.musikcube.remote.util.Preconditions
|
import io.casey.musikcube.remote.util.Preconditions
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
|
@ -21,12 +21,12 @@ import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter
|
|||||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
|
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
|
||||||
import com.google.android.exoplayer2.util.Util
|
import com.google.android.exoplayer2.util.Util
|
||||||
import io.casey.musikcube.remote.Application
|
import io.casey.musikcube.remote.Application
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
|
||||||
import io.casey.musikcube.remote.service.playback.PlayerWrapper
|
import io.casey.musikcube.remote.service.playback.PlayerWrapper
|
||||||
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamProxy
|
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamProxy
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
|
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||||
import io.casey.musikcube.remote.ui.shared.util.NetworkUtil
|
import io.casey.musikcube.remote.ui.shared.util.NetworkUtil
|
||||||
import io.casey.musikcube.remote.util.Preconditions
|
import io.casey.musikcube.remote.util.Preconditions
|
||||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
|
||||||
import okhttp3.Cache
|
import okhttp3.Cache
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -9,11 +9,11 @@ import android.os.PowerManager
|
|||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import io.casey.musikcube.remote.Application
|
import io.casey.musikcube.remote.Application
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
|
||||||
import io.casey.musikcube.remote.service.playback.PlayerWrapper
|
import io.casey.musikcube.remote.service.playback.PlayerWrapper
|
||||||
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamProxy
|
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamProxy
|
||||||
import io.casey.musikcube.remote.util.Preconditions
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||||
|
import io.casey.musikcube.remote.util.Preconditions
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import android.os.Handler
|
|||||||
import io.casey.musikcube.remote.Application
|
import io.casey.musikcube.remote.Application
|
||||||
import io.casey.musikcube.remote.injection.DaggerServiceComponent
|
import io.casey.musikcube.remote.injection.DaggerServiceComponent
|
||||||
import io.casey.musikcube.remote.injection.DataModule
|
import io.casey.musikcube.remote.injection.DataModule
|
||||||
import io.casey.musikcube.remote.model.impl.remote.RemoteTrack
|
|
||||||
import io.casey.musikcube.remote.service.playback.IPlaybackService
|
import io.casey.musikcube.remote.service.playback.IPlaybackService
|
||||||
import io.casey.musikcube.remote.service.playback.PlaybackState
|
import io.casey.musikcube.remote.service.playback.PlaybackState
|
||||||
import io.casey.musikcube.remote.service.playback.RepeatMode
|
import io.casey.musikcube.remote.service.playback.RepeatMode
|
||||||
@ -13,6 +12,7 @@ import io.casey.musikcube.remote.service.websocket.SocketMessage
|
|||||||
import io.casey.musikcube.remote.service.websocket.WebSocketService
|
import io.casey.musikcube.remote.service.websocket.WebSocketService
|
||||||
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.impl.remote.RemoteTrack
|
||||||
import io.casey.musikcube.remote.ui.shared.model.TrackListSlidingWindow
|
import io.casey.musikcube.remote.ui.shared.model.TrackListSlidingWindow
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
@ -8,9 +8,9 @@ import com.danikula.videocache.CacheListener
|
|||||||
import com.danikula.videocache.HttpProxyCacheServer
|
import com.danikula.videocache.HttpProxyCacheServer
|
||||||
import com.danikula.videocache.file.Md5FileNameGenerator
|
import com.danikula.videocache.file.Md5FileNameGenerator
|
||||||
import io.casey.musikcube.remote.Application
|
import io.casey.musikcube.remote.Application
|
||||||
|
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||||
import io.casey.musikcube.remote.ui.shared.util.NetworkUtil
|
import io.casey.musikcube.remote.ui.shared.util.NetworkUtil
|
||||||
import io.casey.musikcube.remote.util.Strings
|
import io.casey.musikcube.remote.util.Strings
|
||||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ import io.casey.musikcube.remote.Application
|
|||||||
import io.casey.musikcube.remote.R
|
import io.casey.musikcube.remote.R
|
||||||
import io.casey.musikcube.remote.injection.DaggerServiceComponent
|
import io.casey.musikcube.remote.injection.DaggerServiceComponent
|
||||||
import io.casey.musikcube.remote.injection.DataModule
|
import io.casey.musikcube.remote.injection.DataModule
|
||||||
import io.casey.musikcube.remote.model.impl.remote.RemoteTrack
|
|
||||||
import io.casey.musikcube.remote.service.playback.IPlaybackService
|
import io.casey.musikcube.remote.service.playback.IPlaybackService
|
||||||
import io.casey.musikcube.remote.service.playback.PlaybackState
|
import io.casey.musikcube.remote.service.playback.PlaybackState
|
||||||
import io.casey.musikcube.remote.service.playback.PlayerWrapper
|
import io.casey.musikcube.remote.service.playback.PlayerWrapper
|
||||||
@ -21,6 +20,7 @@ import io.casey.musikcube.remote.service.system.SystemService
|
|||||||
import io.casey.musikcube.remote.service.websocket.Messages
|
import io.casey.musikcube.remote.service.websocket.Messages
|
||||||
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.impl.remote.RemoteTrack
|
||||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||||
import io.casey.musikcube.remote.ui.shared.model.TrackListSlidingWindow
|
import io.casey.musikcube.remote.ui.shared.model.TrackListSlidingWindow
|
||||||
import io.casey.musikcube.remote.util.Strings
|
import io.casey.musikcube.remote.util.Strings
|
||||||
|
@ -5,10 +5,10 @@ import android.arch.persistence.room.RoomDatabase
|
|||||||
import io.casey.musikcube.remote.Application
|
import io.casey.musikcube.remote.Application
|
||||||
import io.casey.musikcube.remote.injection.DaggerDataComponent
|
import io.casey.musikcube.remote.injection.DaggerDataComponent
|
||||||
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamProxy
|
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamProxy
|
||||||
import io.casey.musikcube.remote.util.Strings
|
|
||||||
import io.casey.musikcube.remote.service.websocket.Messages
|
import io.casey.musikcube.remote.service.websocket.Messages
|
||||||
import io.casey.musikcube.remote.service.websocket.SocketMessage
|
import io.casey.musikcube.remote.service.websocket.SocketMessage
|
||||||
import io.casey.musikcube.remote.service.websocket.WebSocketService
|
import io.casey.musikcube.remote.service.websocket.WebSocketService
|
||||||
|
import io.casey.musikcube.remote.util.Strings
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
@ -22,6 +22,7 @@ abstract class OfflineDb : RoomDatabase() {
|
|||||||
@Inject lateinit var wss: WebSocketService
|
@Inject lateinit var wss: WebSocketService
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
DaggerDataComponent.builder()
|
DaggerDataComponent.builder()
|
||||||
.appComponent(Application.appComponent)
|
.appComponent(Application.appComponent)
|
||||||
.build().inject(this)
|
.build().inject(this)
|
||||||
|
@ -21,19 +21,19 @@ import com.bumptech.glide.request.target.SimpleTarget
|
|||||||
import com.bumptech.glide.request.target.Target
|
import com.bumptech.glide.request.target.Target
|
||||||
import com.bumptech.glide.request.transition.Transition
|
import com.bumptech.glide.request.transition.Transition
|
||||||
import io.casey.musikcube.remote.Application
|
import io.casey.musikcube.remote.Application
|
||||||
import io.casey.musikcube.remote.ui.home.activity.MainActivity
|
|
||||||
import io.casey.musikcube.remote.R
|
import io.casey.musikcube.remote.R
|
||||||
import io.casey.musikcube.remote.injection.GlideApp
|
import io.casey.musikcube.remote.injection.GlideApp
|
||||||
import io.casey.musikcube.remote.injection.GlideRequest
|
import io.casey.musikcube.remote.injection.GlideRequest
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
|
||||||
import io.casey.musikcube.remote.service.playback.PlaybackServiceFactory
|
import io.casey.musikcube.remote.service.playback.PlaybackServiceFactory
|
||||||
import io.casey.musikcube.remote.service.playback.PlaybackState
|
import io.casey.musikcube.remote.service.playback.PlaybackState
|
||||||
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamingPlaybackService
|
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamingPlaybackService
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
|
import io.casey.musikcube.remote.ui.home.activity.MainActivity
|
||||||
|
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||||
import io.casey.musikcube.remote.ui.shared.extension.fallback
|
import io.casey.musikcube.remote.ui.shared.extension.fallback
|
||||||
import io.casey.musikcube.remote.ui.shared.model.albumart.Size
|
import io.casey.musikcube.remote.ui.shared.model.albumart.Size
|
||||||
import io.casey.musikcube.remote.util.Debouncer
|
import io.casey.musikcube.remote.util.Debouncer
|
||||||
import io.casey.musikcube.remote.util.Strings
|
import io.casey.musikcube.remote.util.Strings
|
||||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
|
||||||
import android.support.v4.app.NotificationCompat.Action as NotifAction
|
import android.support.v4.app.NotificationCompat.Action as NotifAction
|
||||||
import io.casey.musikcube.remote.ui.shared.model.albumart.getUrl as getAlbumArtUrl
|
import io.casey.musikcube.remote.ui.shared.model.albumart.getUrl as getAlbumArtUrl
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package io.casey.musikcube.remote.model.impl.remote
|
package io.casey.musikcube.remote.service.websocket.model.impl.remote
|
||||||
|
|
||||||
import io.casey.musikcube.remote.service.websocket.model.IAlbum
|
|
||||||
import io.casey.musikcube.remote.service.playback.impl.remote.Metadata
|
import io.casey.musikcube.remote.service.playback.impl.remote.Metadata
|
||||||
import io.casey.musikcube.remote.service.websocket.Messages
|
import io.casey.musikcube.remote.service.websocket.Messages
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.IAlbum
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
class RemoteAlbum(val json: JSONObject) : IAlbum {
|
class RemoteAlbum(val json: JSONObject) : IAlbum {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.casey.musikcube.remote.model.impl.remote
|
package io.casey.musikcube.remote.service.websocket.model.impl.remote
|
||||||
|
|
||||||
import io.casey.musikcube.remote.service.websocket.model.IAlbumArtist
|
|
||||||
import io.casey.musikcube.remote.service.websocket.Messages
|
import io.casey.musikcube.remote.service.websocket.Messages
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.IAlbumArtist
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
class RemoteAlbumArtist(private val json: JSONObject) : IAlbumArtist {
|
class RemoteAlbumArtist(private val json: JSONObject) : IAlbumArtist {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.casey.musikcube.remote.model.impl.remote
|
package io.casey.musikcube.remote.service.websocket.model.impl.remote
|
||||||
|
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ICategoryValue
|
|
||||||
import io.casey.musikcube.remote.service.websocket.Messages
|
import io.casey.musikcube.remote.service.websocket.Messages
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.ICategoryValue
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
class RemoteCategoryValue(private val categoryType: String,
|
class RemoteCategoryValue(private val categoryType: String,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package io.casey.musikcube.remote.model.impl.remote
|
package io.casey.musikcube.remote.service.websocket.model.impl.remote
|
||||||
|
|
||||||
import io.casey.musikcube.remote.service.websocket.Messages
|
import io.casey.musikcube.remote.service.websocket.Messages
|
||||||
import io.casey.musikcube.remote.service.websocket.SocketMessage
|
import io.casey.musikcube.remote.service.websocket.SocketMessage
|
||||||
@ -33,9 +33,8 @@ class RemoteDataProvider(private val service: WebSocketService) : IDataProvider
|
|||||||
override val state: IDataProvider.State
|
override val state: IDataProvider.State
|
||||||
get() = currentState
|
get() = currentState
|
||||||
|
|
||||||
override fun getAlbums(filter: String): Observable<List<IAlbum>> {
|
override fun getAlbums(filter: String): Observable<List<IAlbum>> =
|
||||||
return getAlbumsForCategory("", 0, filter)
|
getAlbumsForCategory("", 0, filter)
|
||||||
}
|
|
||||||
|
|
||||||
override fun getAlbumsForCategory(categoryType: String, categoryId: Long, filter: String): Observable<List<IAlbum>> {
|
override fun getAlbumsForCategory(categoryType: String, categoryId: Long, filter: String): Observable<List<IAlbum>> {
|
||||||
val message = SocketMessage.Builder
|
val message = SocketMessage.Builder
|
||||||
@ -100,9 +99,8 @@ class RemoteDataProvider(private val service: WebSocketService) : IDataProvider
|
|||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTracks(filter: String): Observable<List<ITrack>> {
|
override fun getTracks(filter: String): Observable<List<ITrack>> =
|
||||||
return getTracks(-1, -1, filter)
|
getTracks(-1, -1, filter)
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTrackCountByCategory(category: String, id: Long, filter: String): Observable<Int> {
|
override fun getTrackCountByCategory(category: String, id: Long, filter: String): Observable<Int> {
|
||||||
val message = SocketMessage.Builder
|
val message = SocketMessage.Builder
|
||||||
@ -118,9 +116,8 @@ class RemoteDataProvider(private val service: WebSocketService) : IDataProvider
|
|||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTracksByCategory(category: String, id: Long, filter: String): Observable<List<ITrack>> {
|
override fun getTracksByCategory(category: String, id: Long, filter: String): Observable<List<ITrack>> =
|
||||||
return getTracksByCategory(category, id, -1, -1, filter)
|
getTracksByCategory(category, id, -1, -1, filter)
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTracksByCategory(category: String, id: Long, limit: Int, offset: Int, filter: String): Observable<List<ITrack>> {
|
override fun getTracksByCategory(category: String, id: Long, limit: Int, offset: Int, filter: String): Observable<List<ITrack>> {
|
||||||
val builder = SocketMessage.Builder
|
val builder = SocketMessage.Builder
|
||||||
@ -152,9 +149,8 @@ class RemoteDataProvider(private val service: WebSocketService) : IDataProvider
|
|||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPlayQueueTracks(filter: String): Observable<List<ITrack>> {
|
override fun getPlayQueueTracks(filter: String): Observable<List<ITrack>> =
|
||||||
return getPlayQueueTracks(-1, -1, filter)
|
getPlayQueueTracks(-1, -1, filter)
|
||||||
}
|
|
||||||
|
|
||||||
override fun getPlayQueueTracks(limit: Int, offset: Int, filter: String): Observable<List<ITrack>> {
|
override fun getPlayQueueTracks(limit: Int, offset: Int, filter: String): Observable<List<ITrack>> {
|
||||||
val builder = SocketMessage.Builder
|
val builder = SocketMessage.Builder
|
||||||
@ -360,17 +356,14 @@ class RemoteDataProvider(private val service: WebSocketService) : IDataProvider
|
|||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun observeState(): Observable<Pair<IDataProvider.State, IDataProvider.State>> {
|
override fun observeState(): Observable<Pair<IDataProvider.State, IDataProvider.State>> =
|
||||||
return connectionStatePublisher.observeOn(AndroidSchedulers.mainThread())
|
connectionStatePublisher.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
|
||||||
|
|
||||||
override fun observePlayQueue(): Observable<Unit> {
|
override fun observePlayQueue(): Observable<Unit> =
|
||||||
return playQueueStatePublisher.observeOn(AndroidSchedulers.mainThread())
|
playQueueStatePublisher.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
|
||||||
|
|
||||||
override fun observeAuthFailure(): Observable<Unit> {
|
override fun observeAuthFailure(): Observable<Unit> =
|
||||||
return authFailurePublisher.observeOn(AndroidSchedulers.mainThread())
|
authFailurePublisher.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
|
||||||
|
|
||||||
override fun attach() {
|
override fun attach() {
|
||||||
service.addClient(client)
|
service.addClient(client)
|
||||||
@ -404,13 +397,12 @@ class RemoteDataProvider(private val service: WebSocketService) : IDataProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mapState(state: WebSocketService.State): IDataProvider.State {
|
private fun mapState(state: WebSocketService.State): IDataProvider.State =
|
||||||
return when (state) {
|
when (state) {
|
||||||
WebSocketService.State.Disconnected -> IDataProvider.State.Disconnected
|
WebSocketService.State.Disconnected -> IDataProvider.State.Disconnected
|
||||||
WebSocketService.State.Connecting -> IDataProvider.State.Connecting
|
WebSocketService.State.Connecting -> IDataProvider.State.Connecting
|
||||||
WebSocketService.State.Connected -> IDataProvider.State.Connected
|
WebSocketService.State.Connected -> IDataProvider.State.Connected
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun createTrackListSubquery(categoryType: String, categoryId: Long, filter: String): JSONObject {
|
private fun createTrackListSubquery(categoryType: String, categoryId: Long, filter: String): JSONObject {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.casey.musikcube.remote.model.impl.remote
|
package io.casey.musikcube.remote.service.websocket.model.impl.remote
|
||||||
|
|
||||||
import io.casey.musikcube.remote.service.websocket.model.IPlaylist
|
|
||||||
import io.casey.musikcube.remote.service.websocket.Messages
|
import io.casey.musikcube.remote.service.websocket.Messages
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.IPlaylist
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
class RemotePlaylist(private val json: JSONObject) : IPlaylist {
|
class RemotePlaylist(private val json: JSONObject) : IPlaylist {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package io.casey.musikcube.remote.model.impl.remote
|
package io.casey.musikcube.remote.service.websocket.model.impl.remote
|
||||||
|
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
|
||||||
import io.casey.musikcube.remote.service.playback.impl.remote.Metadata
|
import io.casey.musikcube.remote.service.playback.impl.remote.Metadata
|
||||||
import io.casey.musikcube.remote.service.websocket.Messages
|
import io.casey.musikcube.remote.service.websocket.Messages
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
class RemoteTrack(val json: JSONObject) : ITrack {
|
class RemoteTrack(val json: JSONObject) : ITrack {
|
||||||
|
@ -32,11 +32,11 @@ import io.casey.musikcube.remote.ui.playqueue.activity.PlayQueueActivity
|
|||||||
import io.casey.musikcube.remote.ui.settings.activity.SettingsActivity
|
import io.casey.musikcube.remote.ui.settings.activity.SettingsActivity
|
||||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||||
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
||||||
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
|
|
||||||
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
|
|
||||||
import io.casey.musikcube.remote.ui.shared.extension.getColorCompat
|
import io.casey.musikcube.remote.ui.shared.extension.getColorCompat
|
||||||
import io.casey.musikcube.remote.ui.shared.extension.setCheckWithoutEvent
|
import io.casey.musikcube.remote.ui.shared.extension.setCheckWithoutEvent
|
||||||
import io.casey.musikcube.remote.ui.shared.extension.showSnackbar
|
import io.casey.musikcube.remote.ui.shared.extension.showSnackbar
|
||||||
|
import io.casey.musikcube.remote.ui.shared.mixin.DataProviderMixin
|
||||||
|
import io.casey.musikcube.remote.ui.shared.mixin.PlaybackMixin
|
||||||
import io.casey.musikcube.remote.ui.shared.util.Duration
|
import io.casey.musikcube.remote.ui.shared.util.Duration
|
||||||
import io.casey.musikcube.remote.ui.shared.util.UpdateCheck
|
import io.casey.musikcube.remote.ui.shared.util.UpdateCheck
|
||||||
import io.casey.musikcube.remote.ui.tracks.activity.TrackListActivity
|
import io.casey.musikcube.remote.ui.tracks.activity.TrackListActivity
|
||||||
|
@ -3,41 +3,52 @@ package io.casey.musikcube.remote.ui.playqueue.activity
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.TextView
|
|
||||||
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||||
import io.casey.musikcube.remote.R
|
import io.casey.musikcube.remote.R
|
||||||
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
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.activity.BaseActivity
|
||||||
import io.casey.musikcube.remote.ui.shared.extension.*
|
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.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.mixin.PlaybackMixin
|
||||||
import io.casey.musikcube.remote.ui.shared.model.TrackListSlidingWindow
|
import io.casey.musikcube.remote.ui.shared.model.TrackListSlidingWindow
|
||||||
import io.casey.musikcube.remote.ui.shared.view.EmptyListView
|
import io.casey.musikcube.remote.ui.shared.view.EmptyListView
|
||||||
import io.reactivex.rxkotlin.subscribeBy
|
import io.reactivex.rxkotlin.subscribeBy
|
||||||
|
|
||||||
class PlayQueueActivity : BaseActivity() {
|
class PlayQueueActivity : BaseActivity() {
|
||||||
private var adapter: Adapter = Adapter()
|
|
||||||
private var offlineQueue: Boolean = false
|
private var offlineQueue: Boolean = false
|
||||||
private lateinit var data: DataProviderMixin
|
private lateinit var data: DataProviderMixin
|
||||||
private lateinit var playback: PlaybackMixin
|
private lateinit var playback: PlaybackMixin
|
||||||
private lateinit var tracks: TrackListSlidingWindow
|
private lateinit var tracks: TrackListSlidingWindow
|
||||||
|
private lateinit var adapter: PlayQueueAdapter
|
||||||
private lateinit var emptyView: EmptyListView
|
private lateinit var emptyView: EmptyListView
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
component.inject(this)
|
component.inject(this)
|
||||||
|
|
||||||
data = mixin(DataProviderMixin())
|
data = mixin(DataProviderMixin())
|
||||||
playback = mixin(PlaybackMixin(playbackEvents))
|
playback = mixin(PlaybackMixin(playbackEvents))
|
||||||
|
mixin(ItemContextMenuMixin(this))
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
setContentView(R.layout.recycler_view_activity)
|
setContentView(R.layout.recycler_view_activity)
|
||||||
|
|
||||||
|
val queryFactory = playback.service.playlistQueryFactory
|
||||||
|
offlineQueue = playback.service.playlistQueryFactory.offline()
|
||||||
|
|
||||||
val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view)
|
val recyclerView = findViewById<FastScrollRecyclerView>(R.id.recycler_view)
|
||||||
|
tracks = TrackListSlidingWindow(recyclerView, data.provider, queryFactory)
|
||||||
|
tracks.setInitialPosition(intent.getIntExtra(EXTRA_PLAYING_INDEX, -1))
|
||||||
|
tracks.setOnMetadataLoadedListener(slidingWindowListener)
|
||||||
|
adapter = PlayQueueAdapter(tracks, playback, adapterListener)
|
||||||
|
|
||||||
setupDefaultRecyclerView(recyclerView, adapter)
|
setupDefaultRecyclerView(recyclerView, adapter)
|
||||||
|
|
||||||
emptyView = findViewById(R.id.empty_list_view)
|
emptyView = findViewById(R.id.empty_list_view)
|
||||||
@ -45,13 +56,6 @@ class PlayQueueActivity : BaseActivity() {
|
|||||||
emptyView.emptyMessage = getString(R.string.play_queue_empty)
|
emptyView.emptyMessage = getString(R.string.play_queue_empty)
|
||||||
emptyView.alternateView = recyclerView
|
emptyView.alternateView = recyclerView
|
||||||
|
|
||||||
val queryFactory = playback.service.playlistQueryFactory
|
|
||||||
offlineQueue = playback.service.playlistQueryFactory.offline()
|
|
||||||
|
|
||||||
tracks = TrackListSlidingWindow(recyclerView, data.provider, queryFactory)
|
|
||||||
tracks.setInitialPosition(intent.getIntExtra(EXTRA_PLAYING_INDEX, -1))
|
|
||||||
tracks.setOnMetadataLoadedListener(slidingWindowListener)
|
|
||||||
|
|
||||||
data.provider.observeState().subscribeBy(
|
data.provider.observeState().subscribeBy(
|
||||||
onNext = { states ->
|
onNext = { states ->
|
||||||
if (states.first == IDataProvider.State.Connected) {
|
if (states.first == IDataProvider.State.Connected) {
|
||||||
@ -84,9 +88,12 @@ class PlayQueueActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val onItemClickListener = View.OnClickListener { v ->
|
private val adapterListener = object: PlayQueueAdapter.EventListener {
|
||||||
if (v.tag is Int) {
|
override fun onItemClicked(position: Int) =
|
||||||
playback.service.playAt(v.tag as Int)
|
playback.service.playAt(position)
|
||||||
|
|
||||||
|
override fun onActionClicked(view: View, value: ITrack) {
|
||||||
|
mixin(ItemContextMenuMixin::class.java)?.showForTrack(value, view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,61 +104,11 @@ class PlayQueueActivity : BaseActivity() {
|
|||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class ViewHolder internal constructor(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
|
||||||
private val title: TextView = itemView.findViewById(R.id.title)
|
|
||||||
private val subtitle: TextView = itemView.findViewById(R.id.subtitle)
|
|
||||||
private val trackNum: TextView = itemView.findViewById(R.id.track_num)
|
|
||||||
|
|
||||||
internal fun bind(track: ITrack?, position: Int) {
|
|
||||||
trackNum.text = (position + 1).toString()
|
|
||||||
itemView.tag = position
|
|
||||||
var titleColor = R.color.theme_foreground
|
|
||||||
var subtitleColor = R.color.theme_disabled_foreground
|
|
||||||
|
|
||||||
if (track == null) {
|
|
||||||
title.text = "-"
|
|
||||||
subtitle.text = "-"
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val playing = playback.service.playingTrack
|
|
||||||
val entryExternalId = track.externalId
|
|
||||||
val playingExternalId = playing.externalId
|
|
||||||
|
|
||||||
if (entryExternalId == playingExternalId) {
|
|
||||||
titleColor = R.color.theme_green
|
|
||||||
subtitleColor = R.color.theme_yellow
|
|
||||||
}
|
|
||||||
|
|
||||||
title.text = fallback(track.title, "-")
|
|
||||||
subtitle.text = fallback(track.albumArtist, "-")
|
|
||||||
}
|
|
||||||
|
|
||||||
title.setTextColor(getColorCompat(titleColor))
|
|
||||||
subtitle.setTextColor(getColorCompat(subtitleColor))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class Adapter : RecyclerView.Adapter<ViewHolder>() {
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
|
||||||
val inflater = LayoutInflater.from(parent.context)
|
|
||||||
val view = inflater.inflate(R.layout.play_queue_row, parent, false)
|
|
||||||
view.setOnClickListener(onItemClickListener)
|
|
||||||
return ViewHolder(view)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
||||||
holder.bind(tracks.getTrack(position), position)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount(): Int = tracks.count
|
|
||||||
}
|
|
||||||
|
|
||||||
private val slidingWindowListener = object : TrackListSlidingWindow.OnMetadataLoadedListener {
|
private val slidingWindowListener = object : TrackListSlidingWindow.OnMetadataLoadedListener {
|
||||||
override fun onReloaded(count: Int) {
|
override fun onReloaded(count: Int) =
|
||||||
emptyView.update(data.provider.state, count)
|
emptyView.update(data.provider.state, count)
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMetadataLoaded(offset: Int, count: Int) {}
|
override fun onMetadataLoaded(offset: Int, count: Int) = Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
package io.casey.musikcube.remote.ui.playqueue.adapter
|
||||||
|
|
||||||
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
|
import io.casey.musikcube.remote.R
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
|
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.mixin.PlaybackMixin
|
||||||
|
import io.casey.musikcube.remote.ui.shared.model.TrackListSlidingWindow
|
||||||
|
|
||||||
|
class PlayQueueAdapter(val tracks: TrackListSlidingWindow,
|
||||||
|
val playback: PlaybackMixin,
|
||||||
|
val listener: EventListener): RecyclerView.Adapter<PlayQueueAdapter.ViewHolder>()
|
||||||
|
{
|
||||||
|
interface EventListener {
|
||||||
|
fun onItemClicked(position: Int)
|
||||||
|
fun onActionClicked(view: View, value: ITrack)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
|
val view = inflater.inflate(R.layout.play_queue_row, parent, false)
|
||||||
|
val action = view.findViewById<View>(R.id.action)
|
||||||
|
view.setOnClickListener{ v -> listener.onItemClicked(v.tag as Int) }
|
||||||
|
action.setOnClickListener{ v -> listener.onActionClicked(v, v.tag as ITrack) }
|
||||||
|
return ViewHolder(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
|
holder.bind(tracks.getTrack(position), position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = tracks.count
|
||||||
|
|
||||||
|
inner class ViewHolder internal constructor(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
private val title = itemView.findViewById<TextView>(R.id.title)
|
||||||
|
private val subtitle = itemView.findViewById<TextView>(R.id.subtitle)
|
||||||
|
private val trackNum = itemView.findViewById<TextView>(R.id.track_num)
|
||||||
|
private val action = itemView.findViewById<View>(R.id.action)
|
||||||
|
|
||||||
|
internal fun bind(track: ITrack?, position: Int) {
|
||||||
|
trackNum.text = (position + 1).toString()
|
||||||
|
itemView.tag = position
|
||||||
|
action.tag = track
|
||||||
|
|
||||||
|
var titleColor = R.color.theme_foreground
|
||||||
|
var subtitleColor = R.color.theme_disabled_foreground
|
||||||
|
|
||||||
|
if (track == null) {
|
||||||
|
title.text = "-"
|
||||||
|
subtitle.text = "-"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val playing = playback.service.playingTrack
|
||||||
|
val entryExternalId = track.externalId
|
||||||
|
val playingExternalId = playing.externalId
|
||||||
|
|
||||||
|
if (entryExternalId == playingExternalId) {
|
||||||
|
titleColor = R.color.theme_green
|
||||||
|
subtitleColor = R.color.theme_yellow
|
||||||
|
}
|
||||||
|
|
||||||
|
title.text = fallback(track.title, "-")
|
||||||
|
subtitle.text = fallback(track.albumArtist, "-")
|
||||||
|
}
|
||||||
|
|
||||||
|
title.setTextColor(getColorCompat(titleColor))
|
||||||
|
subtitle.setTextColor(getColorCompat(subtitleColor))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,8 +20,8 @@ import com.uacf.taskrunner.Tasks
|
|||||||
import io.casey.musikcube.remote.Application
|
import io.casey.musikcube.remote.Application
|
||||||
import io.casey.musikcube.remote.R
|
import io.casey.musikcube.remote.R
|
||||||
import io.casey.musikcube.remote.ui.settings.model.Connection
|
import io.casey.musikcube.remote.ui.settings.model.Connection
|
||||||
import io.casey.musikcube.remote.ui.shared.extension.*
|
|
||||||
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
import io.casey.musikcube.remote.ui.shared.activity.BaseActivity
|
||||||
|
import io.casey.musikcube.remote.ui.shared.extension.*
|
||||||
|
|
||||||
private val EXTRA_CONNECTION = "extra_connection"
|
private val EXTRA_CONNECTION = "extra_connection"
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ import android.support.v7.widget.RecyclerView
|
|||||||
import android.support.v7.widget.SearchView
|
import android.support.v7.widget.SearchView
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.widget.CheckBox
|
import android.widget.CheckBox
|
||||||
import android.widget.CompoundButton
|
import android.widget.CompoundButton
|
||||||
|
@ -7,7 +7,6 @@ import android.support.v7.app.AppCompatActivity
|
|||||||
import io.casey.musikcube.remote.framework.IMixin
|
import io.casey.musikcube.remote.framework.IMixin
|
||||||
import io.casey.musikcube.remote.framework.MixinSet
|
import io.casey.musikcube.remote.framework.MixinSet
|
||||||
import io.casey.musikcube.remote.framework.ViewModel
|
import io.casey.musikcube.remote.framework.ViewModel
|
||||||
import io.casey.musikcube.remote.ui.shared.mixin.ItemContextMenuMixin
|
|
||||||
import io.casey.musikcube.remote.ui.shared.mixin.ViewModelMixin
|
import io.casey.musikcube.remote.ui.shared.mixin.ViewModelMixin
|
||||||
|
|
||||||
open class BaseDialogFragment: DialogFragment(), ViewModel.Provider {
|
open class BaseDialogFragment: DialogFragment(), ViewModel.Provider {
|
||||||
|
@ -8,9 +8,10 @@ import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
|||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.subscribeBy
|
||||||
|
|
||||||
class TrackListSlidingWindow(private val recyclerView: FastScrollRecyclerView,
|
class TrackListSlidingWindow(private val recyclerView: FastScrollRecyclerView,
|
||||||
val dataProvider: IDataProvider,
|
private val dataProvider: IDataProvider,
|
||||||
private val queryFactory: TrackListSlidingWindow.QueryFactory)
|
private val queryFactory: TrackListSlidingWindow.QueryFactory)
|
||||||
{
|
{
|
||||||
private var scrollState = RecyclerView.SCROLL_STATE_IDLE
|
private var scrollState = RecyclerView.SCROLL_STATE_IDLE
|
||||||
@ -29,9 +30,7 @@ class TrackListSlidingWindow(private val recyclerView: FastScrollRecyclerView,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val cache = object : LinkedHashMap<Int, CacheEntry>() {
|
private val cache = object : LinkedHashMap<Int, CacheEntry>() {
|
||||||
override fun removeEldestEntry(eldest: MutableMap.MutableEntry<Int, CacheEntry>): Boolean {
|
override fun removeEldestEntry(eldest: MutableMap.MutableEntry<Int, CacheEntry>): Boolean = size >= MAX_SIZE
|
||||||
return size >= MAX_SIZE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnMetadataLoadedListener {
|
interface OnMetadataLoadedListener {
|
||||||
@ -74,20 +73,20 @@ class TrackListSlidingWindow(private val recyclerView: FastScrollRecyclerView,
|
|||||||
val countObservable = queryFactory.count()
|
val countObservable = queryFactory.count()
|
||||||
|
|
||||||
if (countObservable != null) {
|
if (countObservable != null) {
|
||||||
countObservable.subscribe(
|
countObservable.subscribeBy(
|
||||||
{ newCount ->
|
onNext = { newCount ->
|
||||||
count = newCount
|
count = newCount
|
||||||
|
|
||||||
if (initialPosition != -1) {
|
if (initialPosition != -1) {
|
||||||
recyclerView.scrollToPosition(initialPosition)
|
recyclerView.scrollToPosition(initialPosition)
|
||||||
initialPosition = -1
|
initialPosition = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
loadedListener?.onReloaded(count)
|
loadedListener?.onReloaded(count)
|
||||||
},
|
},
|
||||||
{ _ ->
|
onError = { _ ->
|
||||||
Log.d("TrackListSlidingWindow", "message send failed, likely canceled")
|
Log.d("TrackListSlidingWindow", "message send failed, likely canceled")
|
||||||
})
|
})
|
||||||
|
|
||||||
queried = true
|
queried = true
|
||||||
}
|
}
|
||||||
@ -127,7 +126,7 @@ class TrackListSlidingWindow(private val recyclerView: FastScrollRecyclerView,
|
|||||||
fun getTrack(index: Int): ITrack? {
|
fun getTrack(index: Int): ITrack? {
|
||||||
val track = cache[index]
|
val track = cache[index]
|
||||||
|
|
||||||
if (track?.dirty ?: true) {
|
if (track == null || track.dirty) {
|
||||||
if (scrollState == RecyclerView.SCROLL_STATE_IDLE) {
|
if (scrollState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||||
getPageAround(index)
|
getPageAround(index)
|
||||||
}
|
}
|
||||||
@ -167,8 +166,8 @@ class TrackListSlidingWindow(private val recyclerView: FastScrollRecyclerView,
|
|||||||
queryOffset = offset
|
queryOffset = offset
|
||||||
queryLimit = limit
|
queryLimit = limit
|
||||||
|
|
||||||
pageRequest.subscribe(
|
pageRequest.subscribeBy(
|
||||||
{ response ->
|
onNext = { response ->
|
||||||
queryLimit = -1
|
queryLimit = -1
|
||||||
queryOffset = queryLimit
|
queryOffset = queryLimit
|
||||||
|
|
||||||
@ -183,23 +182,20 @@ class TrackListSlidingWindow(private val recyclerView: FastScrollRecyclerView,
|
|||||||
notifyAdapterChanged()
|
notifyAdapterChanged()
|
||||||
notifyMetadataLoaded(offset, i)
|
notifyMetadataLoaded(offset, i)
|
||||||
},
|
},
|
||||||
{ _ ->
|
onError = { _ ->
|
||||||
Log.d("TrackListSlidingWindow", "message send failed, likely canceled")
|
Log.d("TrackListSlidingWindow", "message send failed, likely canceled")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun notifyAdapterChanged() {
|
private fun notifyAdapterChanged() =
|
||||||
recyclerView.adapter.notifyDataSetChanged()
|
recyclerView.adapter.notifyDataSetChanged()
|
||||||
}
|
|
||||||
|
|
||||||
private fun notifyMetadataLoaded(offset: Int, count: Int) {
|
private fun notifyMetadataLoaded(offset: Int, count: Int) =
|
||||||
loadedListener?.onMetadataLoaded(offset, count)
|
loadedListener?.onMetadataLoaded(offset, count)
|
||||||
}
|
|
||||||
|
|
||||||
private fun scrolling(): Boolean {
|
private fun scrolling(): Boolean =
|
||||||
return scrollState != RecyclerView.SCROLL_STATE_IDLE || fastScrollerActive
|
scrollState != RecyclerView.SCROLL_STATE_IDLE || fastScrollerActive
|
||||||
}
|
|
||||||
|
|
||||||
private val recyclerViewScrollListener = object : RecyclerView.OnScrollListener() {
|
private val recyclerViewScrollListener = object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
|
override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
|
||||||
|
@ -5,9 +5,11 @@ import android.util.LruCache
|
|||||||
import io.casey.musikcube.remote.Application
|
import io.casey.musikcube.remote.Application
|
||||||
import io.casey.musikcube.remote.service.websocket.model.IAlbum
|
import io.casey.musikcube.remote.service.websocket.model.IAlbum
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
import io.casey.musikcube.remote.util.Strings
|
|
||||||
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
import io.casey.musikcube.remote.ui.settings.constants.Prefs
|
||||||
import okhttp3.*
|
import io.casey.musikcube.remote.util.Strings
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
@ -9,14 +9,14 @@ import android.widget.FrameLayout
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import io.casey.musikcube.remote.Application
|
import io.casey.musikcube.remote.Application
|
||||||
import io.casey.musikcube.remote.R
|
import io.casey.musikcube.remote.R
|
||||||
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
|
||||||
import io.casey.musikcube.remote.injection.DaggerViewComponent
|
import io.casey.musikcube.remote.injection.DaggerViewComponent
|
||||||
import io.casey.musikcube.remote.injection.DataModule
|
import io.casey.musikcube.remote.injection.DataModule
|
||||||
import io.casey.musikcube.remote.service.playback.PlaybackServiceFactory
|
import io.casey.musikcube.remote.service.playback.PlaybackServiceFactory
|
||||||
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamingPlaybackService
|
import io.casey.musikcube.remote.service.playback.impl.streaming.StreamingPlaybackService
|
||||||
import io.casey.musikcube.remote.ui.tracks.activity.TrackListActivity
|
|
||||||
import io.casey.musikcube.remote.ui.shared.extension.setVisible
|
|
||||||
import io.casey.musikcube.remote.service.websocket.WebSocketService
|
import io.casey.musikcube.remote.service.websocket.WebSocketService
|
||||||
|
import io.casey.musikcube.remote.service.websocket.model.IDataProvider
|
||||||
|
import io.casey.musikcube.remote.ui.shared.extension.setVisible
|
||||||
|
import io.casey.musikcube.remote.ui.tracks.activity.TrackListActivity
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import io.casey.musikcube.remote.service.websocket.WebSocketService.State as WebSocketState
|
import io.casey.musikcube.remote.service.websocket.WebSocketService.State as WebSocketState
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import io.casey.musikcube.remote.R
|
import io.casey.musikcube.remote.R
|
||||||
import io.casey.musikcube.remote.service.playback.IPlaybackService
|
|
||||||
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
import io.casey.musikcube.remote.service.websocket.model.ITrack
|
||||||
import io.casey.musikcube.remote.ui.shared.extension.fallback
|
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.getColorCompat
|
||||||
|
@ -1,28 +1,30 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?android:selectableItemBackground"
|
android:background="?android:selectableItemBackground"
|
||||||
android:minHeight="52dp"
|
android:minHeight="52dp"
|
||||||
android:padding="8dp" >
|
android:padding="8dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/track_num"
|
android:id="@+id/track_num"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginRight="12dp"
|
android:layout_marginEnd="12dp"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentStart="true"
|
||||||
android:textColor="@color/theme_disabled_foreground"
|
android:textColor="@color/theme_disabled_foreground"
|
||||||
android:text="1" />
|
tools:text="1" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_toRightOf="@id/track_num"
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toEndOf="@id/track_num"
|
||||||
|
android:layout_toStartOf="@+id/action"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -34,7 +36,7 @@
|
|||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:textColor="@color/theme_foreground"
|
android:textColor="@color/theme_foreground"
|
||||||
android:text="title"/>
|
tools:text="title"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:textSize="12dp"
|
android:textSize="12dp"
|
||||||
@ -46,9 +48,20 @@
|
|||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:textColor="@color/theme_disabled_foreground"
|
android:textColor="@color/theme_disabled_foreground"
|
||||||
android:text="subtitle"/>
|
tools:text="subtitle"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/action"
|
||||||
|
android:background="?android:selectableItemBackground"
|
||||||
|
android:src="@drawable/ic_overflow"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:gravity="center"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
Loading…
Reference in New Issue
Block a user