Fixed some more Kotlin compile issues -- not sure why they weren't

flagged before. Also getting Dagger 2 setup as a test. Will probably end
up removing it, but let's see if it can help with a few things.
This commit is contained in:
casey langen 2017-07-13 00:01:50 -07:00
parent 144eb64846
commit 20dfbb5462
13 changed files with 234 additions and 164 deletions

View File

@ -52,6 +52,10 @@ repositories {
maven { url 'https://maven.fabric.io/public' }
}
kapt {
generateStubs = true /* required for Dagger 2 code gen to work with Kotlin */
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
@ -68,6 +72,14 @@ dependencies {
annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha3"
kapt "android.arch.persistence.room:compiler:1.0.0-alpha3"
provided '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'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
kapt 'com.google.dagger:dagger-android-processor:2.11'
kapt 'com.google.dagger:dagger-compiler:2.11'
implementation 'com.neovisionaries:nv-websocket-client:1.31'
implementation 'com.squareup.okhttp3:okhttp:3.8.0'
implementation 'com.github.bumptech.glide:glide:3.8.0'
@ -78,9 +90,9 @@ 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:25.4.0'
implementation 'com.android.support:recyclerview-v7:25.4.0'
implementation 'com.android.support:design:25.4.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.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
transitive = true

View File

@ -1,20 +1,31 @@
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.MainModule
import io.casey.musikcube.remote.offline.OfflineDb
import io.casey.musikcube.remote.playback.StreamProxy
import io.casey.musikcube.remote.util.NetworkUtil
import io.fabric.sdk.android.Fabric
import javax.inject.Inject
class Application : android.app.Application(), HasActivityInjector {
@Inject lateinit var activityInjector: DispatchingAndroidInjector<Activity>
class Application : android.app.Application() {
override fun onCreate() {
instance = this
super.onCreate()
DaggerMainComponent.builder().mainModule(MainModule()).build().inject(this)
if (BuildConfig.DEBUG) {
Stetho.initializeWithDefaults(this)
}
@ -31,6 +42,10 @@ class Application : android.app.Application() {
"offline").build()
}
override fun activityInjector(): AndroidInjector<Activity> {
return activityInjector
}
companion object {
var instance: Context? = null
private set

View File

@ -18,6 +18,7 @@ import android.widget.CheckBox
import android.widget.CompoundButton
import android.widget.SeekBar
import android.widget.TextView
import dagger.android.AndroidInjection
import io.casey.musikcube.remote.playback.PlaybackService
import io.casey.musikcube.remote.playback.PlaybackState
import io.casey.musikcube.remote.playback.RepeatMode
@ -39,24 +40,29 @@ class MainActivity : WebSocketActivityBase() {
private var playback: PlaybackService? = null
private var updateCheck: UpdateCheck = UpdateCheck()
private var mainLayout: View? = null
private var metadataView: MainMetadataView? = null
private var playPause: TextView? = null
private var currentTime: TextView? = null
private var totalTime: TextView? = null
private var connectedNotPlayingContainer: View? = null
private var disconnectedButton: View? = null
private var showOfflineButton: View? = null
private var disconnectedContainer: View? = null
private var shuffleCb: CheckBox? = null
private var muteCb: CheckBox? = null
private var repeatCb: CheckBox? = null
private var disconnectedOverlay: View? = null
private var seekbar: SeekBar? = null
private var seekbarValue = -1
private var blink = 0
/* views */
private lateinit var mainLayout: View
private lateinit var metadataView: MainMetadataView
private lateinit var playPause: TextView
private lateinit var currentTime: TextView
private lateinit var totalTime: TextView
private lateinit var connectedNotPlayingContainer: View
private lateinit var disconnectedButton: View
private lateinit var showOfflineButton: View
private lateinit var disconnectedContainer: View
private lateinit var shuffleCb: CheckBox
private lateinit var muteCb: CheckBox
private lateinit var repeatCb: CheckBox
private lateinit var disconnectedOverlay: View
private lateinit var seekbar: SeekBar
/* end views */
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
prefs = this.getSharedPreferences(Prefs.NAME, Context.MODE_PRIVATE)
@ -72,15 +78,15 @@ class MainActivity : WebSocketActivityBase() {
override fun onPause() {
super.onPause()
metadataView?.onPause()
metadataView.onPause()
unbindCheckboxEventListeners()
handler.removeCallbacks(updateTimeRunnable)
}
override fun onResume() {
super.onResume()
this.playback = playbackService
metadataView?.onResume()
playback = playbackService
metadataView.onResume()
bindCheckBoxEventListeners()
rebindUi()
scheduleUpdateTime(true)
@ -193,7 +199,7 @@ class MainActivity : WebSocketActivityBase() {
}
private fun showSnackbar(stringId: Int) {
val sb = Snackbar.make(mainLayout!!, stringId, Snackbar.LENGTH_LONG)
val sb = Snackbar.make(mainLayout, stringId, Snackbar.LENGTH_LONG)
val sbView = sb.view
sbView.setBackgroundColor(getColorCompat(R.color.color_primary))
val tv = sbView.findViewById<TextView>(android.support.design.R.id.snackbar_text)
@ -202,38 +208,38 @@ class MainActivity : WebSocketActivityBase() {
}
private fun bindCheckBoxEventListeners() {
this.shuffleCb?.setOnCheckedChangeListener(shuffleListener)
this.muteCb?.setOnCheckedChangeListener(muteListener)
this.repeatCb?.setOnCheckedChangeListener(repeatListener)
shuffleCb.setOnCheckedChangeListener(shuffleListener)
muteCb.setOnCheckedChangeListener(muteListener)
repeatCb.setOnCheckedChangeListener(repeatListener)
}
/* onRestoreInstanceState() calls setChecked(), which has the side effect of
running these callbacks. this screws up state, especially for the repeat checkbox */
private fun unbindCheckboxEventListeners() {
this.shuffleCb?.setOnCheckedChangeListener(null)
this.muteCb?.setOnCheckedChangeListener(null)
this.repeatCb?.setOnCheckedChangeListener(null)
shuffleCb.setOnCheckedChangeListener(null)
muteCb.setOnCheckedChangeListener(null)
repeatCb.setOnCheckedChangeListener(null)
}
private fun bindEventListeners() {
this.mainLayout = findViewById(R.id.activity_main)
this.metadataView = findViewById(R.id.main_metadata_view) as MainMetadataView
this.shuffleCb = findViewById(R.id.check_shuffle) as CheckBox
this.muteCb = findViewById(R.id.check_mute) as CheckBox
this.repeatCb = findViewById(R.id.check_repeat) as CheckBox
this.connectedNotPlayingContainer = findViewById(R.id.connected_not_playing)
this.disconnectedButton = findViewById(R.id.disconnected_button)
this.disconnectedContainer = findViewById(R.id.disconnected_container)
this.disconnectedOverlay = findViewById(R.id.disconnected_overlay)
this.showOfflineButton = findViewById(R.id.offline_tracks_button)
this.playPause = findViewById(R.id.button_play_pause) as TextView
this.currentTime = findViewById(R.id.current_time) as TextView
this.totalTime = findViewById(R.id.total_time) as TextView
this.seekbar = findViewById(R.id.seekbar) as SeekBar
mainLayout = findViewById(R.id.activity_main)
metadataView = findViewById<MainMetadataView>(R.id.main_metadata_view)
shuffleCb = findViewById<CheckBox>(R.id.check_shuffle)
muteCb = findViewById<CheckBox>(R.id.check_mute)
repeatCb = findViewById<CheckBox>(R.id.check_repeat)
connectedNotPlayingContainer = findViewById(R.id.connected_not_playing)
disconnectedButton = findViewById(R.id.disconnected_button)
disconnectedContainer = findViewById(R.id.disconnected_container)
disconnectedOverlay = findViewById(R.id.disconnected_overlay)
showOfflineButton = findViewById(R.id.offline_tracks_button)
playPause = findViewById<TextView>(R.id.button_play_pause)
currentTime = findViewById<TextView>(R.id.current_time)
totalTime = findViewById<TextView>(R.id.total_time)
seekbar = findViewById<SeekBar>(R.id.seekbar)
findViewById(R.id.button_prev).setOnClickListener { _: View -> playback?.prev() }
findViewById<View>(R.id.button_prev).setOnClickListener { _: View -> playback?.prev() }
findViewById(R.id.button_play_pause).setOnClickListener { _: View ->
findViewById<View>(R.id.button_play_pause).setOnClickListener { _: View ->
if (playback?.playbackState === PlaybackState.Stopped) {
playback?.playAll()
}
@ -242,20 +248,19 @@ class MainActivity : WebSocketActivityBase() {
}
}
findViewById(R.id.button_next).setOnClickListener { _: View -> playback?.next() }
findViewById<View>(R.id.button_next).setOnClickListener { _: View -> playback?.next() }
disconnectedButton?.setOnClickListener { _ -> getWebSocketService().reconnect() }
disconnectedButton.setOnClickListener { _ -> getWebSocketService().reconnect() }
seekbar?.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
seekbarValue = progress
currentTime?.text = Duration.format(seekbarValue.toDouble())
currentTime.text = Duration.format(seekbarValue.toDouble())
}
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
@ -266,29 +271,36 @@ class MainActivity : WebSocketActivityBase() {
}
})
findViewById(R.id.button_artists).setOnClickListener { _: View -> startActivity(CategoryBrowseActivity.getStartIntent(this, Messages.Category.ALBUM_ARTIST)) }
findViewById<View>(R.id.button_artists).setOnClickListener { _: View ->
startActivity(CategoryBrowseActivity
.getStartIntent(this, Messages.Category.ALBUM_ARTIST))
}
findViewById(R.id.button_tracks).setOnClickListener { _: View -> startActivity(TrackListActivity.getStartIntent(this@MainActivity)) }
findViewById<View>(R.id.button_tracks).setOnClickListener { _: View ->
startActivity(TrackListActivity.getStartIntent(this@MainActivity))
}
findViewById(R.id.button_albums).setOnClickListener { _: View -> startActivity(AlbumBrowseActivity.getStartIntent(this@MainActivity)) }
findViewById<View>(R.id.button_albums).setOnClickListener { _: View ->
startActivity(AlbumBrowseActivity.getStartIntent(this@MainActivity))
}
findViewById(R.id.button_play_queue).setOnClickListener { _ -> navigateToPlayQueue() }
findViewById<View>(R.id.button_play_queue).setOnClickListener { _ -> navigateToPlayQueue() }
findViewById(R.id.metadata_container).setOnClickListener { _ ->
findViewById<View>(R.id.metadata_container).setOnClickListener { _ ->
if (playback?.queueCount ?: 0 > 0) {
navigateToPlayQueue()
}
}
disconnectedOverlay?.setOnClickListener { _ ->
disconnectedOverlay.setOnClickListener { _ ->
/* swallow input so user can't click on things while disconnected */
}
showOfflineButton?.setOnClickListener { _ -> onOfflineTracksSelected() }
showOfflineButton.setOnClickListener { _ -> onOfflineTracksSelected() }
}
private fun rebindUi() {
if (this.playback == null) {
if (playback == null) {
throw IllegalStateException()
}
@ -301,42 +313,41 @@ class MainActivity : WebSocketActivityBase() {
val showMetadataView = !stopped && (playback?.queueCount ?: 0) > 0
/* bottom section: transport controls */
this.playPause?.setText(if (playing || buffering) R.string.button_pause else R.string.button_play)
playPause.setText(if (playing || buffering) R.string.button_pause else R.string.button_play)
this.connectedNotPlayingContainer?.visibility = if (connected && stopped) View.VISIBLE else View.GONE
this.disconnectedOverlay?.visibility = if (connected || !stopped) View.GONE else View.VISIBLE
connectedNotPlayingContainer.visibility = if (connected && stopped) View.VISIBLE else View.GONE
disconnectedOverlay.visibility = if (connected || !stopped) View.GONE else View.VISIBLE
val repeatMode = playback?.repeatMode
val repeatChecked = repeatMode !== RepeatMode.None
repeatCb?.text = getString(REPEAT_TO_STRING_ID[repeatMode] ?: R.string.unknown_value)
repeatCb?.setCheckWithoutEvent(repeatChecked, this.repeatListener)
this.shuffleCb?.text = getString(if (streaming) R.string.button_random else R.string.button_shuffle)
shuffleCb?.setCheckWithoutEvent(playback?.isShuffled ?: false, shuffleListener)
muteCb?.setCheckWithoutEvent(playback?.isMuted ?: false, muteListener)
repeatCb.text = getString(REPEAT_TO_STRING_ID[repeatMode] ?: R.string.unknown_value)
repeatCb.setCheckWithoutEvent(repeatChecked, this.repeatListener)
shuffleCb.text = getString(if (streaming) R.string.button_random else R.string.button_shuffle)
shuffleCb.setCheckWithoutEvent(playback?.isShuffled ?: false, shuffleListener)
muteCb.setCheckWithoutEvent(playback?.isMuted ?: false, muteListener)
/* middle section: connected, disconnected, and metadata views */
connectedNotPlayingContainer?.visibility = View.GONE
disconnectedContainer?.visibility = View.GONE
connectedNotPlayingContainer.visibility = View.GONE
disconnectedContainer.visibility = View.GONE
if (!showMetadataView) {
metadataView?.hide()
metadataView.hide()
if (!connected) {
disconnectedContainer?.visibility = View.VISIBLE
disconnectedContainer.visibility = View.VISIBLE
}
else if (stopped) {
connectedNotPlayingContainer?.visibility = View.VISIBLE
connectedNotPlayingContainer.visibility = View.VISIBLE
}
}
else {
metadataView?.refresh()
metadataView.refresh()
}
}
private fun clearUi() {
metadataView?.clear()
metadataView.clear()
rebindUi()
}
@ -354,11 +365,11 @@ class MainActivity : WebSocketActivityBase() {
val duration = playback?.duration ?: 0.0
val current: Double = if (seekbarValue == -1) playback?.currentTime ?: 0.0 else seekbarValue.toDouble()
currentTime?.text = Duration.format(current)
totalTime?.text = Duration.format(duration)
seekbar?.max = duration.toInt()
seekbar?.progress = current.toInt()
seekbar?.secondaryProgress = playback?.bufferedTime?.toInt() ?: 0
currentTime.text = Duration.format(current)
totalTime.text = Duration.format(duration)
seekbar.max = duration.toInt()
seekbar.progress = current.toInt()
seekbar.secondaryProgress = playback?.bufferedTime?.toInt() ?: 0
var currentTimeColor = R.color.theme_foreground
if (playback?.playbackState === PlaybackState.Paused) {
@ -367,7 +378,7 @@ class MainActivity : WebSocketActivityBase() {
else R.color.theme_blink_foreground
}
currentTime?.setTextColor(getColorCompat(currentTimeColor))
currentTime.setTextColor(getColorCompat(currentTimeColor))
scheduleUpdateTime(false)
}
@ -398,8 +409,8 @@ class MainActivity : WebSocketActivityBase() {
}
val checked = newMode !== RepeatMode.None
repeatCb?.text = getString(REPEAT_TO_STRING_ID[newMode] ?: R.string.unknown_value)
repeatCb?.setCheckWithoutEvent(checked, repeatListener)
repeatCb.text = getString(REPEAT_TO_STRING_ID[newMode] ?: R.string.unknown_value)
repeatCb.setCheckWithoutEvent(checked, repeatListener)
playback?.toggleRepeatMode()
}

View File

@ -0,0 +1,11 @@
package io.casey.musikcube.remote.injection
import dagger.Module
import dagger.android.ContributesAndroidInjector
import io.casey.musikcube.remote.MainActivity
@Module
abstract class ActivityModule {
@ContributesAndroidInjector
abstract fun contributeMainActivityInjector(): MainActivity
}

View File

@ -0,0 +1,11 @@
package io.casey.musikcube.remote.injection
import dagger.Component
import dagger.android.AndroidInjectionModule
import dagger.android.AndroidInjector
import io.casey.musikcube.remote.Application
@Component(modules = arrayOf(AndroidInjectionModule::class, MainModule::class, ActivityModule::class))
interface MainComponent : AndroidInjector<Application> {
}

View File

@ -0,0 +1,8 @@
package io.casey.musikcube.remote.injection
import dagger.Module
@Module
class MainModule {
}

View File

@ -44,11 +44,11 @@ class AlbumBrowseActivity : WebSocketActivityBase(), Filterable {
setTitleFromIntent(R.string.albums_title)
enableUpNavigation()
val fastScroller = findViewById(R.id.fast_scroller) as RecyclerFastScroller
val recyclerView = findViewById(R.id.recycler_view) as RecyclerView
val fastScroller = findViewById<RecyclerFastScroller>(R.id.fast_scroller)
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
setupDefaultRecyclerView(recyclerView, fastScroller, adapter)
emptyView = findViewById(R.id.empty_list_view) as EmptyListView
emptyView = findViewById<EmptyListView>(R.id.empty_list_view)
emptyView?.capability = EmptyListView.Capability.OnlineOnly
emptyView?.emptyMessage = getString(R.string.empty_no_items_format, getString(R.string.browse_type_albums))
emptyView?.alternateView = recyclerView

View File

@ -50,11 +50,11 @@ class CategoryBrowseActivity : WebSocketActivityBase(), Filterable {
setContentView(R.layout.recycler_view_activity)
setTitle(categoryTitleStringId)
val fastScroller = findViewById(R.id.fast_scroller) as RecyclerFastScroller
val recyclerView = findViewById(R.id.recycler_view) as RecyclerView
val fastScroller = findViewById<RecyclerFastScroller>(R.id.fast_scroller)
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
setupDefaultRecyclerView(recyclerView, fastScroller, adapter)
emptyView = findViewById(R.id.empty_list_view) as EmptyListView
emptyView = findViewById<EmptyListView>(R.id.empty_list_view)
emptyView?.capability = EmptyListView.Capability.OnlineOnly
emptyView?.emptyMessage = getString(R.string.empty_no_items_format, getString(categoryTypeStringId))
emptyView?.alternateView = recyclerView

View File

@ -34,14 +34,14 @@ class PlayQueueActivity : WebSocketActivityBase() {
setContentView(R.layout.recycler_view_activity)
val fastScroller = findViewById(R.id.fast_scroller) as RecyclerFastScroller
val recyclerView = findViewById(R.id.recycler_view) as RecyclerView
val fastScroller = findViewById<RecyclerFastScroller>(R.id.fast_scroller)
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
setupDefaultRecyclerView(recyclerView, fastScroller, adapter)
val queryFactory = playback!!.playlistQueryFactory
val message: SocketMessage? = queryFactory.getRequeryMessage()
emptyView = findViewById(R.id.empty_list_view) as EmptyListView
emptyView = findViewById<EmptyListView>(R.id.empty_list_view)
emptyView?.capability = EmptyListView.Capability.OfflineOk
emptyView?.emptyMessage = getString(R.string.play_queue_empty)
emptyView?.alternateView = recyclerView

View File

@ -140,17 +140,17 @@ class SettingsActivity : AppCompatActivity() {
}
private fun bindEventListeners() {
this.addressText = this.findViewById(R.id.address) as EditText
this.portText = this.findViewById(R.id.port) as EditText
this.httpPortText = this.findViewById(R.id.http_port) as EditText
this.passwordText = this.findViewById(R.id.password) as EditText
this.albumArtCheckbox = findViewById(R.id.album_art_checkbox) as CheckBox
this.messageCompressionCheckbox = findViewById(R.id.message_compression) as CheckBox
this.softwareVolume = findViewById(R.id.software_volume) as CheckBox
this.bitrateSpinner = findViewById(R.id.transcoder_bitrate_spinner) as Spinner
this.cacheSpinner = findViewById(R.id.streaming_disk_cache_spinner) as Spinner
this.sslCheckbox = findViewById(R.id.ssl_checkbox) as CheckBox
this.certCheckbox = findViewById(R.id.cert_validation) as CheckBox
this.addressText = this.findViewById<EditText>(R.id.address)
this.portText = this.findViewById<EditText>(R.id.port)
this.httpPortText = this.findViewById<EditText>(R.id.http_port)
this.passwordText = this.findViewById<EditText>(R.id.password)
this.albumArtCheckbox = findViewById<CheckBox>(R.id.album_art_checkbox)
this.messageCompressionCheckbox = findViewById<CheckBox>(R.id.message_compression)
this.softwareVolume = findViewById<CheckBox>(R.id.software_volume)
this.bitrateSpinner = findViewById<Spinner>(R.id.transcoder_bitrate_spinner)
this.cacheSpinner = findViewById<Spinner>(R.id.streaming_disk_cache_spinner)
this.sslCheckbox = findViewById<CheckBox>(R.id.ssl_checkbox)
this.certCheckbox = findViewById<CheckBox>(R.id.cert_validation)
}
private fun save() {

View File

@ -27,13 +27,13 @@ import io.casey.musikcube.remote.websocket.WebSocketService
import org.json.JSONObject
class TrackListActivity : WebSocketActivityBase(), Filterable {
private var tracks: TrackListSlidingWindow? = null
private var emptyView: EmptyListView? = null
private var transport: TransportFragment? = null
private var categoryType: String? = null
private lateinit var tracks: TrackListSlidingWindow
private lateinit var emptyView: EmptyListView
private lateinit var transport: TransportFragment
private var categoryType: String = ""
private var categoryId: Long = 0
private var lastFilter = ""
private var adapter: Adapter = Adapter()
private var adapter = Adapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -50,25 +50,27 @@ class TrackListActivity : WebSocketActivityBase(), Filterable {
val queryFactory = createCategoryQueryFactory(categoryType, categoryId)
val fastScroller = findViewById(R.id.fast_scroller) as RecyclerFastScroller
val recyclerView = findViewById(R.id.recycler_view) as RecyclerView
val fastScroller = findViewById<RecyclerFastScroller>(R.id.fast_scroller)
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
setupDefaultRecyclerView(recyclerView, fastScroller, adapter)
emptyView = findViewById(R.id.empty_list_view) as EmptyListView
emptyView?.capability = if (isOfflineTracks) Capability.OfflineOk else Capability.OnlineOnly
emptyView?.emptyMessage = emptyMessage
emptyView?.alternateView = recyclerView
emptyView = findViewById(R.id.empty_list_view)
emptyView.let {
it.capability = if (isOfflineTracks) Capability.OfflineOk else Capability.OnlineOnly
it.emptyMessage = emptyMessage
it.alternateView = recyclerView
}
tracks = TrackListSlidingWindow(
recyclerView, fastScroller, getWebSocketService(), queryFactory)
tracks?.setOnMetadataLoadedListener(slidingWindowListener)
tracks.setOnMetadataLoadedListener(slidingWindowListener)
transport = addTransportFragment(object: TransportFragment.OnModelChangedListener {
override fun onChanged(fragment: TransportFragment) {
adapter.notifyDataSetChanged()
}
})
})!!
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
@ -80,11 +82,11 @@ class TrackListActivity : WebSocketActivityBase(), Filterable {
override fun onPause() {
super.onPause()
tracks?.pause()
tracks.pause()
}
override fun onResume() {
tracks?.resume() /* needs to happen before */
tracks.resume() /* needs to happen before */
super.onResume()
requeryIfViewingOfflineCache()
}
@ -104,10 +106,10 @@ class TrackListActivity : WebSocketActivityBase(), Filterable {
override fun onStateChanged(newState: WebSocketService.State, oldState: WebSocketService.State) {
if (newState === WebSocketService.State.Connected) {
filterDebouncer.cancel()
tracks?.requery()
tracks.requery()
}
else {
emptyView?.update(newState, adapter.itemCount)
emptyView.update(newState, adapter.itemCount)
}
}
@ -119,7 +121,7 @@ class TrackListActivity : WebSocketActivityBase(), Filterable {
private val filterDebouncer = object : Debouncer<String>(350) {
override fun onDebounced(last: String?) {
if (!isPaused) {
tracks?.requery()
tracks.requery()
}
}
}
@ -128,7 +130,7 @@ class TrackListActivity : WebSocketActivityBase(), Filterable {
val index = view.tag as Int
if (isValidCategory(categoryType, categoryId)) {
playbackService?.play(categoryType!!, categoryId, index, lastFilter)
playbackService?.play(categoryType, categoryId, index, lastFilter)
}
else {
playbackService?.playAll(index, lastFilter)
@ -152,7 +154,7 @@ class TrackListActivity : WebSocketActivityBase(), Filterable {
if (entry != null) {
val entryExternalId = entry.optString(Metadata.Track.EXTERNAL_ID, "")
val playingExternalId = transport?.playbackService?.getTrackString(Metadata.Track.EXTERNAL_ID, "")
val playingExternalId = transport.playbackService?.getTrackString(Metadata.Track.EXTERNAL_ID, "")
if (entryExternalId == playingExternalId) {
titleColor = R.color.theme_green
@ -181,11 +183,11 @@ class TrackListActivity : WebSocketActivityBase(), Filterable {
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(tracks?.getTrack(position), position)
holder.bind(tracks.getTrack(position), position)
}
override fun getItemCount(): Int {
return if (tracks == null) 0 else tracks!!.count
return tracks.count
}
}
@ -203,7 +205,7 @@ class TrackListActivity : WebSocketActivityBase(), Filterable {
private fun requeryIfViewingOfflineCache() {
if (isOfflineTracks) {
tracks!!.requery()
tracks.requery()
}
}
@ -262,7 +264,7 @@ class TrackListActivity : WebSocketActivityBase(), Filterable {
private val slidingWindowListener = object : TrackListSlidingWindow.OnMetadataLoadedListener {
override fun onReloaded(count: Int) {
emptyView?.update(getWebSocketService().state, count)
emptyView.update(getWebSocketService().state, count)
}
override fun onMetadataLoaded(offset: Int, count: Int) {}

View File

@ -58,7 +58,7 @@ fun AppCompatActivity.enableUpNavigation() {
fun AppCompatActivity.addTransportFragment(
listener: TransportFragment.OnModelChangedListener? = null): TransportFragment?
{
val root = this.findViewById(android.R.id.content)
val root = findViewById<View>(android.R.id.content)
if (root != null) {
if (root.findViewById<View>(R.id.transport_container) != null) {
val fragment = TransportFragment.newInstance()

View File

@ -40,17 +40,17 @@ class MainMetadataView : FrameLayout {
private var isPaused = true
private var title: TextView? = null
private var artist: TextView? = null
private var album: TextView? = null
private var volume: TextView? = null
private var titleWithArt: TextView? = null
private var artistAndAlbumWithArt: TextView? = null
private var volumeWithArt: TextView? = null
private var mainTrackMetadataWithAlbumArt: View? = null
private var mainTrackMetadataNoAlbumArt: View? = null
private var buffering: View? = null
private var albumArtImageView: ImageView? = null
private lateinit var title: TextView
private lateinit var artist: TextView
private lateinit var album: TextView
private lateinit var volume: TextView
private lateinit var titleWithArt: TextView
private lateinit var artistAndAlbumWithArt: TextView
private lateinit var volumeWithArt: TextView
private lateinit var mainTrackMetadataWithAlbumArt: View
private lateinit var mainTrackMetadataNoAlbumArt: View
private lateinit var buffering: View
private lateinit var albumArtImageView: ImageView
private enum class DisplayMode {
Artwork, NoArtwork, Stopped
@ -109,24 +109,24 @@ class MainMetadataView : FrameLayout {
/* we don't display the volume amount when we're streaming -- the system has
overlays for drawing volume. */
if (streaming) {
this.volume?.visibility = View.GONE
this.volumeWithArt?.visibility = View.GONE
volume.visibility = View.GONE
volumeWithArt.visibility = View.GONE
}
else {
val volume = getString(R.string.status_volume, Math.round(playback.volume * 100))
this.volume?.visibility = View.VISIBLE
this.volumeWithArt?.visibility = View.VISIBLE
this.volume?.text = volume
this.volumeWithArt?.text = volume
this.volume.visibility = View.VISIBLE
this.volumeWithArt.visibility = View.VISIBLE
this.volume.text = volume
this.volumeWithArt.text = volume
}
this.title?.text = if (Strings.empty(title)) getString(if (buffering) R.string.buffering else R.string.unknown_title) else title
this.artist?.text = if (Strings.empty(artist)) getString(if (buffering) R.string.buffering else R.string.unknown_artist) else artist
this.album?.text = if (Strings.empty(album)) getString(if (buffering) R.string.buffering else R.string.unknown_album) else album
this.title.text = if (Strings.empty(title)) getString(if (buffering) R.string.buffering else R.string.unknown_title) else title
this.artist.text = if (Strings.empty(artist)) getString(if (buffering) R.string.buffering else R.string.unknown_artist) else artist
this.album.text = if (Strings.empty(album)) getString(if (buffering) R.string.buffering else R.string.unknown_album) else album
this.rebindAlbumArtistWithArtTextView(playback)
this.titleWithArt?.text = if (Strings.empty(title)) getString(if (buffering) R.string.buffering else R.string.unknown_title) else title
this.buffering?.visibility = if (buffering) View.VISIBLE else View.GONE
this.titleWithArt.text = if (Strings.empty(title)) getString(if (buffering) R.string.buffering else R.string.unknown_title) else title
this.buffering.visibility = if (buffering) View.VISIBLE else View.GONE
val albumArtEnabledInSettings = this.prefs?.getBoolean(
Prefs.Key.ALBUM_ART_ENABLED, Prefs.Default.ALBUM_ART_ENABLED) ?: false
@ -162,18 +162,18 @@ class MainMetadataView : FrameLayout {
lastDisplayMode = mode
if (mode == DisplayMode.Stopped) {
albumArtImageView?.setImageDrawable(null)
mainTrackMetadataWithAlbumArt?.visibility = View.GONE
mainTrackMetadataNoAlbumArt?.visibility = View.GONE
albumArtImageView.setImageDrawable(null)
mainTrackMetadataWithAlbumArt.visibility = View.GONE
mainTrackMetadataNoAlbumArt.visibility = View.GONE
}
else if (mode == DisplayMode.Artwork) {
mainTrackMetadataWithAlbumArt?.visibility = View.VISIBLE
mainTrackMetadataNoAlbumArt?.visibility = View.GONE
mainTrackMetadataWithAlbumArt.visibility = View.VISIBLE
mainTrackMetadataNoAlbumArt.visibility = View.GONE
}
else {
albumArtImageView?.setImageDrawable(null)
mainTrackMetadataWithAlbumArt?.visibility = View.GONE
mainTrackMetadataNoAlbumArt?.visibility = View.VISIBLE
albumArtImageView.setImageDrawable(null)
mainTrackMetadataWithAlbumArt.visibility = View.GONE
mainTrackMetadataNoAlbumArt.visibility = View.VISIBLE
}
}
@ -215,9 +215,9 @@ class MainMetadataView : FrameLayout {
builder.setSpan(artistColor, artistOffset, artistOffset + artist.length, 0)
builder.setSpan(artistClickable, artistOffset, artistOffset + artist.length, 0)
this.artistAndAlbumWithArt?.movementMethod = LinkMovementMethod.getInstance()
this.artistAndAlbumWithArt?.highlightColor = Color.TRANSPARENT
this.artistAndAlbumWithArt?.text = builder
artistAndAlbumWithArt.movementMethod = LinkMovementMethod.getInstance()
artistAndAlbumWithArt.highlightColor = Color.TRANSPARENT
artistAndAlbumWithArt.text = builder
}
private fun updateAlbumArt() {
@ -266,7 +266,7 @@ class MainMetadataView : FrameLayout {
}
}
})
.into(albumArtImageView!!)
.into(albumArtImageView)
}
else {
setMetadataDisplayMode(lastDisplayMode)
@ -290,8 +290,8 @@ class MainMetadataView : FrameLayout {
if (!albumArtModel.matches(artist, album)) {
AlbumArtModel("", artist, album, AlbumArtModel.Size.Mega) {
_: AlbumArtModel, url: String? ->
val width = albumArtImageView!!.width
val height = albumArtImageView!!.height
val width = albumArtImageView.width
val height = albumArtImageView.height
Glide.with(context).load(url).downloadOnly(width, height)
}
}
@ -321,8 +321,8 @@ class MainMetadataView : FrameLayout {
this.mainTrackMetadataNoAlbumArt = findViewById(R.id.main_track_metadata_without_art)
this.albumArtImageView = findViewById<ImageView>(R.id.album_art)
this.album?.setOnClickListener { _ -> navigateToCurrentAlbum() }
this.artist?.setOnClickListener { _ -> navigateToCurrentArtist() }
this.album.setOnClickListener { _ -> navigateToCurrentAlbum() }
this.artist.setOnClickListener { _ -> navigateToCurrentArtist() }
}
private fun navigateToCurrentArtist() {