mirror of
https://github.com/clangen/musikcube.git
synced 2025-01-05 21:55:24 +00:00
Moved to dependency injection for WebSocketService. Also downgraded
support libraries from 26.0.0-beta2 to beta1. There seem to be issues drawing toolbar icons in beta2.
This commit is contained in:
parent
2a2688f1bf
commit
fdb1d10235
@ -11,6 +11,7 @@ buildscript {
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'io.fabric'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
android {
|
||||
compileSdkVersion 26
|
||||
@ -59,7 +60,7 @@ kapt {
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
})
|
||||
|
||||
@ -68,11 +69,11 @@ dependencies {
|
||||
implementation(name:'videocache-2.8.0-pre', ext:'aar')
|
||||
implementation 'org.slf4j:slf4j-android:1.7.21'
|
||||
|
||||
implementation "android.arch.persistence.room:runtime:1.0.0-alpha3"
|
||||
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha3"
|
||||
kapt "android.arch.persistence.room:compiler:1.0.0-alpha3"
|
||||
implementation "android.arch.persistence.room:runtime:1.0.0-alpha4"
|
||||
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha4"
|
||||
kapt "android.arch.persistence.room:compiler:1.0.0-alpha4"
|
||||
|
||||
provided 'org.glassfish:javax.annotation:10.0-b28'
|
||||
compileOnly 'org.glassfish:javax.annotation:10.0-b28'
|
||||
implementation 'com.google.dagger:dagger:2.11'
|
||||
implementation 'com.google.dagger:dagger-android:2.11'
|
||||
annotationProcessor 'com.google.dagger:dagger-android-processor:2.11'
|
||||
@ -90,14 +91,14 @@ dependencies {
|
||||
implementation 'com.github.pluscubed:recycler-fast-scroll:0.3.2@aar'
|
||||
implementation 'com.facebook.stetho:stetho:1.5.0'
|
||||
|
||||
implementation 'com.android.support:appcompat-v7:26.0.0-beta2'
|
||||
implementation 'com.android.support:recyclerview-v7:26.0.0-beta2'
|
||||
implementation 'com.android.support:design:26.0.0-beta2'
|
||||
implementation 'com.android.support:appcompat-v7:26.0.0-beta1'
|
||||
implementation 'com.android.support:recyclerview-v7:26.0.0-beta1'
|
||||
implementation 'com.android.support:design:26.0.0-beta1'
|
||||
|
||||
implementation('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
|
||||
transitive = true
|
||||
}
|
||||
|
||||
testCompile 'junit:junit:4.12'
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
|
||||
testImplementation 'junit:junit:4.12'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
|
||||
}
|
||||
|
@ -2,13 +2,13 @@ package io.casey.musikcube.remote
|
||||
|
||||
import android.app.Activity
|
||||
import android.arch.persistence.room.Room
|
||||
import android.content.Context
|
||||
import com.crashlytics.android.Crashlytics
|
||||
import com.facebook.stetho.Stetho
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.DispatchingAndroidInjector
|
||||
import dagger.android.HasActivityInjector
|
||||
import io.casey.musikcube.remote.injection.DaggerMainComponent
|
||||
import io.casey.musikcube.remote.injection.MainComponent
|
||||
import io.casey.musikcube.remote.injection.MainModule
|
||||
import io.casey.musikcube.remote.offline.OfflineDb
|
||||
import io.casey.musikcube.remote.playback.StreamProxy
|
||||
@ -24,7 +24,8 @@ class Application : android.app.Application(), HasActivityInjector {
|
||||
|
||||
super.onCreate()
|
||||
|
||||
DaggerMainComponent.builder().mainModule(MainModule()).build().inject(this)
|
||||
mainComponent = DaggerMainComponent.builder().mainModule(MainModule()).build()
|
||||
mainComponent.inject(this)
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
Stetho.initializeWithDefaults(this)
|
||||
@ -47,7 +48,9 @@ class Application : android.app.Application(), HasActivityInjector {
|
||||
}
|
||||
|
||||
companion object {
|
||||
var instance: Context? = null
|
||||
lateinit var mainComponent: MainComponent
|
||||
|
||||
var instance: Application? = null
|
||||
private set
|
||||
|
||||
var offlineDb: OfflineDb? = null
|
||||
|
@ -4,6 +4,7 @@ import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
@ -110,7 +111,7 @@ class MainActivity : WebSocketActivityBase() {
|
||||
menu.findItem(R.id.action_genres).isEnabled = connected
|
||||
|
||||
menu.findItem(R.id.action_remote_toggle).setIcon(
|
||||
if (streaming) R.mipmap.ic_toolbar_streaming else R.mipmap.ic_toolbar_remote)
|
||||
if (streaming) R.drawable.ic_toolbar_streaming else R.drawable.ic_toolbar_remote)
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
@ -3,9 +3,28 @@ package io.casey.musikcube.remote.injection
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import io.casey.musikcube.remote.MainActivity
|
||||
import io.casey.musikcube.remote.ui.activity.*
|
||||
|
||||
@Module
|
||||
abstract class ActivityModule {
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributeMainActivityInjector(): MainActivity
|
||||
abstract fun mainActivityInjector(): MainActivity
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun baseActivityInject(): WebSocketActivityBase
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun settingsInjector(): SettingsActivity
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun albumBrowseInject(): AlbumBrowseActivity
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun categoryBrowseInject(): CategoryBrowseActivity
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun playQueueInject(): PlayQueueActivity
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun trackListInject(): TrackListActivity
|
||||
}
|
||||
|
@ -4,8 +4,24 @@ import dagger.Component
|
||||
import dagger.android.AndroidInjectionModule
|
||||
import dagger.android.AndroidInjector
|
||||
import io.casey.musikcube.remote.Application
|
||||
import io.casey.musikcube.remote.offline.OfflineDb
|
||||
import io.casey.musikcube.remote.playback.RemotePlaybackService
|
||||
import io.casey.musikcube.remote.playback.StreamingPlaybackService
|
||||
import io.casey.musikcube.remote.ui.view.EmptyListView
|
||||
import io.casey.musikcube.remote.ui.view.MainMetadataView
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@Component(modules = arrayOf(AndroidInjectionModule::class, MainModule::class, ActivityModule::class))
|
||||
interface MainComponent : AndroidInjector<Application> {
|
||||
/* views */
|
||||
fun inject(view: EmptyListView)
|
||||
fun inject(view: MainMetadataView)
|
||||
|
||||
/* services */
|
||||
fun inject(service: StreamingPlaybackService)
|
||||
fun inject(service: RemotePlaybackService)
|
||||
|
||||
/* data */
|
||||
fun inject(db: OfflineDb)
|
||||
}
|
||||
|
@ -1,8 +1,22 @@
|
||||
package io.casey.musikcube.remote.injection
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import io.casey.musikcube.remote.Application
|
||||
import io.casey.musikcube.remote.websocket.WebSocketService
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
class MainModule {
|
||||
@Provides
|
||||
fun providesContext(): Context {
|
||||
return Application.instance!!
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesWebSocketService(context: Context): WebSocketService {
|
||||
return WebSocketService(context)
|
||||
}
|
||||
}
|
||||
|
@ -14,22 +14,26 @@ import io.reactivex.schedulers.Schedulers
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@Database(entities = arrayOf(OfflineTrack::class), version = 1)
|
||||
abstract class OfflineDb : RoomDatabase() {
|
||||
@Inject lateinit var wss: WebSocketService
|
||||
|
||||
init {
|
||||
WebSocketService.getInstance(Application.instance!!)
|
||||
.addInterceptor({ message, responder ->
|
||||
var result = false
|
||||
if (Messages.Request.QueryTracksByCategory.matches(message.name)) {
|
||||
val category = message.getStringOption(Messages.Key.CATEGORY)
|
||||
if (Messages.Category.OFFLINE == category) {
|
||||
queryTracks(message, responder)
|
||||
result = true
|
||||
}
|
||||
Application.mainComponent.inject(this)
|
||||
|
||||
wss.addInterceptor({ message, responder ->
|
||||
var result = false
|
||||
if (Messages.Request.QueryTracksByCategory.matches(message.name)) {
|
||||
val category = message.getStringOption(Messages.Key.CATEGORY)
|
||||
if (Messages.Category.OFFLINE == category) {
|
||||
queryTracks(message, responder)
|
||||
result = true
|
||||
}
|
||||
result
|
||||
})
|
||||
}
|
||||
result
|
||||
})
|
||||
|
||||
prune()
|
||||
}
|
||||
|
@ -2,12 +2,14 @@ package io.casey.musikcube.remote.playback
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import io.casey.musikcube.remote.Application
|
||||
import io.casey.musikcube.remote.ui.model.TrackListSlidingWindow
|
||||
import io.casey.musikcube.remote.websocket.Messages
|
||||
import io.casey.musikcube.remote.websocket.SocketMessage
|
||||
import io.casey.musikcube.remote.websocket.WebSocketService
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class RemotePlaybackService(context: Context) : PlaybackService {
|
||||
private interface Key {
|
||||
@ -89,8 +91,8 @@ class RemotePlaybackService(context: Context) : PlaybackService {
|
||||
}
|
||||
}
|
||||
|
||||
@Inject lateinit var wss: WebSocketService
|
||||
private val handler = Handler()
|
||||
private val wss: WebSocketService = WebSocketService.getInstance(context.applicationContext)
|
||||
private val listeners = HashSet<() -> Unit>()
|
||||
private val estimatedTime = EstimatedPosition()
|
||||
|
||||
@ -142,6 +144,7 @@ class RemotePlaybackService(context: Context) : PlaybackService {
|
||||
private var track: JSONObject = JSONObject()
|
||||
|
||||
init {
|
||||
Application.mainComponent.inject(this)
|
||||
reset()
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,10 @@ import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.net.URLEncoder
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class StreamingPlaybackService(context: Context) : PlaybackService {
|
||||
private val wss: WebSocketService = WebSocketService.getInstance(context.applicationContext)
|
||||
@Inject lateinit var wss: WebSocketService
|
||||
private val prefs: SharedPreferences = context.getSharedPreferences(Prefs.NAME, Context.MODE_PRIVATE)
|
||||
private val listeners = HashSet<() -> Unit>()
|
||||
private var params: QueueParams? = null
|
||||
@ -136,6 +137,10 @@ class StreamingPlaybackService(context: Context) : PlaybackService {
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
Application.mainComponent.inject(this)
|
||||
}
|
||||
|
||||
@Synchronized override fun connect(listener: () -> Unit) {
|
||||
listeners.add(listener)
|
||||
if (listeners.size == 1) {
|
||||
|
@ -255,7 +255,7 @@ class SystemService : Service() {
|
||||
applicationContext, 1, MainActivity.getStartIntent(this), 0)
|
||||
|
||||
val notification = NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.mipmap.ic_notification)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setContentTitle(title)
|
||||
.setContentText(artist + " - " + album)
|
||||
.setContentIntent(contentIntent)
|
||||
|
@ -12,6 +12,7 @@ import android.support.v7.app.AppCompatActivity
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.widget.*
|
||||
import dagger.android.AndroidInjection
|
||||
import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.playback.PlayerWrapper
|
||||
import io.casey.musikcube.remote.playback.StreamProxy
|
||||
@ -21,6 +22,7 @@ import io.casey.musikcube.remote.ui.extension.setTextAndMoveCursorToEnd
|
||||
import io.casey.musikcube.remote.websocket.Prefs
|
||||
import io.casey.musikcube.remote.websocket.WebSocketService
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import io.casey.musikcube.remote.websocket.Prefs.Default as Defaults
|
||||
import io.casey.musikcube.remote.websocket.Prefs.Key as Keys
|
||||
|
||||
@ -38,7 +40,10 @@ class SettingsActivity : AppCompatActivity() {
|
||||
private lateinit var cacheSpinner: Spinner
|
||||
private lateinit var prefs: SharedPreferences
|
||||
|
||||
@Inject lateinit var wss: WebSocketService
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
AndroidInjection.inject(this)
|
||||
super.onCreate(savedInstanceState)
|
||||
prefs = this.getSharedPreferences(Prefs.NAME, Context.MODE_PRIVATE)
|
||||
setContentView(R.layout.activity_settings)
|
||||
@ -178,7 +183,7 @@ class SettingsActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
StreamProxy.reload()
|
||||
WebSocketService.getInstance(this).disconnect()
|
||||
wss.disconnect()
|
||||
|
||||
finish()
|
||||
}
|
||||
|
@ -11,23 +11,25 @@ import android.view.MenuItem
|
||||
import com.uacf.taskrunner.LifecycleDelegate
|
||||
import com.uacf.taskrunner.Runner
|
||||
import com.uacf.taskrunner.Task
|
||||
import dagger.android.AndroidInjection
|
||||
|
||||
import io.casey.musikcube.remote.playback.PlaybackService
|
||||
import io.casey.musikcube.remote.playback.PlaybackServiceFactory
|
||||
import io.casey.musikcube.remote.websocket.Prefs
|
||||
import io.casey.musikcube.remote.websocket.WebSocketService
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class WebSocketActivityBase : AppCompatActivity(), Runner.TaskCallbacks {
|
||||
private lateinit var runnerDelegate: LifecycleDelegate
|
||||
private lateinit var prefs: SharedPreferences
|
||||
private lateinit var wss: WebSocketService
|
||||
@Inject lateinit var wss: WebSocketService
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
AndroidInjection.inject(this)
|
||||
super.onCreate(savedInstanceState)
|
||||
volumeControlStream = AudioManager.STREAM_MUSIC
|
||||
runnerDelegate = LifecycleDelegate(this, this, javaClass, null)
|
||||
runnerDelegate.onCreate(savedInstanceState)
|
||||
wss = WebSocketService.getInstance(this)
|
||||
playbackService = PlaybackServiceFactory.instance(this)
|
||||
prefs = getSharedPreferences(Prefs.NAME, Context.MODE_PRIVATE)
|
||||
}
|
||||
|
@ -7,17 +7,21 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import io.casey.musikcube.remote.Application
|
||||
import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.playback.PlaybackServiceFactory
|
||||
import io.casey.musikcube.remote.playback.StreamingPlaybackService
|
||||
import io.casey.musikcube.remote.ui.activity.TrackListActivity
|
||||
import io.casey.musikcube.remote.ui.extension.setVisible
|
||||
import io.casey.musikcube.remote.websocket.WebSocketService
|
||||
import javax.inject.Inject
|
||||
import io.casey.musikcube.remote.websocket.WebSocketService.State as WebSocketState
|
||||
|
||||
class EmptyListView : FrameLayout {
|
||||
enum class Capability { OnlineOnly, OfflineOk }
|
||||
|
||||
@Inject lateinit var wss: WebSocketService
|
||||
|
||||
private var mainView: View? = null
|
||||
private var emptyTextView: TextView? = null
|
||||
private var emptyContainer: View? = null
|
||||
@ -81,6 +85,8 @@ class EmptyListView : FrameLayout {
|
||||
}
|
||||
|
||||
private fun initialize() {
|
||||
Application.mainComponent.inject(this)
|
||||
|
||||
val inflater = LayoutInflater.from(context)
|
||||
|
||||
mainView = inflater.inflate(R.layout.empty_list_view, this, false)
|
||||
@ -93,7 +99,7 @@ class EmptyListView : FrameLayout {
|
||||
addView(mainView)
|
||||
|
||||
reconnectButton?.setOnClickListener { _ ->
|
||||
WebSocketService.getInstance(context).reconnect()
|
||||
wss.reconnect()
|
||||
}
|
||||
|
||||
viewOfflineButton?.setOnClickListener { _ ->
|
||||
|
@ -21,6 +21,8 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.load.resource.drawable.GlideDrawable
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import dagger.android.AndroidInjection
|
||||
import io.casey.musikcube.remote.Application
|
||||
import io.casey.musikcube.remote.R
|
||||
import io.casey.musikcube.remote.playback.*
|
||||
import io.casey.musikcube.remote.ui.activity.AlbumBrowseActivity
|
||||
@ -33,9 +35,10 @@ import io.casey.musikcube.remote.websocket.Prefs
|
||||
import io.casey.musikcube.remote.websocket.SocketMessage
|
||||
import io.casey.musikcube.remote.websocket.WebSocketService
|
||||
import org.json.JSONArray
|
||||
import javax.inject.Inject
|
||||
|
||||
class MainMetadataView : FrameLayout {
|
||||
private var wss: WebSocketService? = null
|
||||
@Inject lateinit var wss: WebSocketService
|
||||
private var prefs: SharedPreferences? = null
|
||||
|
||||
private var isPaused = true
|
||||
@ -300,8 +303,9 @@ class MainMetadataView : FrameLayout {
|
||||
}
|
||||
|
||||
private fun init() {
|
||||
Application.mainComponent.inject(this)
|
||||
|
||||
this.prefs = context.getSharedPreferences(Prefs.NAME, Context.MODE_PRIVATE)
|
||||
this.wss = WebSocketService.getInstance(context)
|
||||
|
||||
val child = LayoutInflater.from(context).inflate(R.layout.main_metadata, this, false)
|
||||
|
||||
|
@ -14,7 +14,7 @@ import io.reactivex.Observable
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
class WebSocketService private constructor(val context: Context) {
|
||||
class WebSocketService constructor(val context: Context) {
|
||||
interface Client {
|
||||
fun onStateChanged(newState: State, oldState: State)
|
||||
fun onMessageReceived(message: SocketMessage)
|
||||
@ -581,17 +581,8 @@ class WebSocketService private constructor(val context: Context) {
|
||||
private val MESSAGE_SCHEDULE_PING = MESSAGE_BASE + 4
|
||||
private val MESSAGE_PING_EXPIRED = MESSAGE_BASE + 5
|
||||
|
||||
private var INSTANCE: WebSocketService? = null
|
||||
private val NEXT_ID = AtomicLong(0)
|
||||
|
||||
@Synchronized fun getInstance(context: Context): WebSocketService {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = WebSocketService(context)
|
||||
}
|
||||
|
||||
return INSTANCE!!
|
||||
}
|
||||
|
||||
private val INTERNAL_CLIENT = object : Client {
|
||||
override fun onStateChanged(newState: State, oldState: State) {}
|
||||
override fun onMessageReceived(message: SocketMessage) {}
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
@ -7,7 +7,7 @@
|
||||
android:id="@+id/action_remote_toggle"
|
||||
app:showAsAction="always"
|
||||
android:title="@string/menu_remote_toggle"
|
||||
android:icon="@mipmap/ic_toolbar_remote" />
|
||||
android:icon="@drawable/ic_toolbar_remote" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_playlists"
|
||||
@ -18,6 +18,7 @@
|
||||
android:id="@+id/action_genres"
|
||||
app:showAsAction="never"
|
||||
android:title="@string/menu_genres"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_offline_tracks"
|
||||
app:showAsAction="never"
|
||||
|
Loading…
Reference in New Issue
Block a user