From 20dfbb54623d0d8aceb37b75d699f6f6b69095a5 Mon Sep 17 00:00:00 2001 From: casey langen Date: Thu, 13 Jul 2017 00:01:50 -0700 Subject: [PATCH] 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. --- src/musikdroid/app/build.gradle | 18 +- .../io/casey/musikcube/remote/Application.kt | 17 +- .../io/casey/musikcube/remote/MainActivity.kt | 165 ++++++++++-------- .../remote/injection/ActivityModule.kt | 11 ++ .../remote/injection/MainComponent.kt | 11 ++ .../musikcube/remote/injection/MainModule.kt | 8 + .../remote/ui/activity/AlbumBrowseActivity.kt | 6 +- .../ui/activity/CategoryBrowseActivity.kt | 6 +- .../remote/ui/activity/PlayQueueActivity.kt | 6 +- .../remote/ui/activity/SettingsActivity.kt | 22 +-- .../remote/ui/activity/TrackListActivity.kt | 50 +++--- .../remote/ui/extension/Extensions.kt | 2 +- .../remote/ui/view/MainMetadataView.kt | 76 ++++---- 13 files changed, 234 insertions(+), 164 deletions(-) create mode 100644 src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/ActivityModule.kt create mode 100644 src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/MainComponent.kt create mode 100644 src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/MainModule.kt diff --git a/src/musikdroid/app/build.gradle b/src/musikdroid/app/build.gradle index bcb625b84..4de7d428d 100644 --- a/src/musikdroid/app/build.gradle +++ b/src/musikdroid/app/build.gradle @@ -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 diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/Application.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/Application.kt index 49b684118..04c3d3bf2 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/Application.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/Application.kt @@ -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 -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 { + return activityInjector + } + companion object { var instance: Context? = null private set diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/MainActivity.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/MainActivity.kt index 9183d56e5..d3eb96b8b 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/MainActivity.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/MainActivity.kt @@ -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(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(R.id.main_metadata_view) + shuffleCb = findViewById(R.id.check_shuffle) + muteCb = findViewById(R.id.check_mute) + repeatCb = findViewById(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(R.id.button_play_pause) + currentTime = findViewById(R.id.current_time) + totalTime = findViewById(R.id.total_time) + seekbar = findViewById(R.id.seekbar) - findViewById(R.id.button_prev).setOnClickListener { _: View -> playback?.prev() } + findViewById(R.id.button_prev).setOnClickListener { _: View -> playback?.prev() } - findViewById(R.id.button_play_pause).setOnClickListener { _: View -> + findViewById(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(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(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(R.id.button_tracks).setOnClickListener { _: View -> + startActivity(TrackListActivity.getStartIntent(this@MainActivity)) + } - findViewById(R.id.button_albums).setOnClickListener { _: View -> startActivity(AlbumBrowseActivity.getStartIntent(this@MainActivity)) } + findViewById(R.id.button_albums).setOnClickListener { _: View -> + startActivity(AlbumBrowseActivity.getStartIntent(this@MainActivity)) + } - findViewById(R.id.button_play_queue).setOnClickListener { _ -> navigateToPlayQueue() } + findViewById(R.id.button_play_queue).setOnClickListener { _ -> navigateToPlayQueue() } - findViewById(R.id.metadata_container).setOnClickListener { _ -> + findViewById(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() } diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/ActivityModule.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/ActivityModule.kt new file mode 100644 index 000000000..66ff33d00 --- /dev/null +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/ActivityModule.kt @@ -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 +} diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/MainComponent.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/MainComponent.kt new file mode 100644 index 000000000..26ced4d7c --- /dev/null +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/MainComponent.kt @@ -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 { + +} diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/MainModule.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/MainModule.kt new file mode 100644 index 000000000..2a33ea071 --- /dev/null +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/injection/MainModule.kt @@ -0,0 +1,8 @@ +package io.casey.musikcube.remote.injection + +import dagger.Module + +@Module +class MainModule { + +} diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/AlbumBrowseActivity.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/AlbumBrowseActivity.kt index b859be46f..b383cae70 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/AlbumBrowseActivity.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/AlbumBrowseActivity.kt @@ -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(R.id.fast_scroller) + val recyclerView = findViewById(R.id.recycler_view) setupDefaultRecyclerView(recyclerView, fastScroller, adapter) - emptyView = findViewById(R.id.empty_list_view) as EmptyListView + emptyView = findViewById(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 diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/CategoryBrowseActivity.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/CategoryBrowseActivity.kt index 40554b0f8..df4dde7d5 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/CategoryBrowseActivity.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/CategoryBrowseActivity.kt @@ -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(R.id.fast_scroller) + val recyclerView = findViewById(R.id.recycler_view) setupDefaultRecyclerView(recyclerView, fastScroller, adapter) - emptyView = findViewById(R.id.empty_list_view) as EmptyListView + emptyView = findViewById(R.id.empty_list_view) emptyView?.capability = EmptyListView.Capability.OnlineOnly emptyView?.emptyMessage = getString(R.string.empty_no_items_format, getString(categoryTypeStringId)) emptyView?.alternateView = recyclerView diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/PlayQueueActivity.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/PlayQueueActivity.kt index f815eb4ac..289cf6e1f 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/PlayQueueActivity.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/PlayQueueActivity.kt @@ -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(R.id.fast_scroller) + val recyclerView = findViewById(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(R.id.empty_list_view) emptyView?.capability = EmptyListView.Capability.OfflineOk emptyView?.emptyMessage = getString(R.string.play_queue_empty) emptyView?.alternateView = recyclerView diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/SettingsActivity.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/SettingsActivity.kt index 1c3f3030c..0d9c7e11a 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/SettingsActivity.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/SettingsActivity.kt @@ -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(R.id.address) + this.portText = this.findViewById(R.id.port) + this.httpPortText = this.findViewById(R.id.http_port) + this.passwordText = this.findViewById(R.id.password) + this.albumArtCheckbox = findViewById(R.id.album_art_checkbox) + this.messageCompressionCheckbox = findViewById(R.id.message_compression) + this.softwareVolume = findViewById(R.id.software_volume) + this.bitrateSpinner = findViewById(R.id.transcoder_bitrate_spinner) + this.cacheSpinner = findViewById(R.id.streaming_disk_cache_spinner) + this.sslCheckbox = findViewById(R.id.ssl_checkbox) + this.certCheckbox = findViewById(R.id.cert_validation) } private fun save() { diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/TrackListActivity.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/TrackListActivity.kt index c9ca13a3f..3a22cf2b1 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/TrackListActivity.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/activity/TrackListActivity.kt @@ -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(R.id.fast_scroller) + val recyclerView = findViewById(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(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) {} diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/extension/Extensions.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/extension/Extensions.kt index 6f8a4e7f0..1bcf14623 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/extension/Extensions.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/extension/Extensions.kt @@ -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(android.R.id.content) if (root != null) { if (root.findViewById(R.id.transport_container) != null) { val fragment = TransportFragment.newInstance() diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/view/MainMetadataView.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/view/MainMetadataView.kt index 741edec99..8845613fd 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/view/MainMetadataView.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/ui/view/MainMetadataView.kt @@ -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(R.id.album_art) - this.album?.setOnClickListener { _ -> navigateToCurrentAlbum() } - this.artist?.setOnClickListener { _ -> navigateToCurrentArtist() } + this.album.setOnClickListener { _ -> navigateToCurrentAlbum() } + this.artist.setOnClickListener { _ -> navigateToCurrentArtist() } } private fun navigateToCurrentArtist() {