Otter-App-Android-Funkwhale/app/src/main/java/com/github/apognu/otter/activities/MainActivity.kt

304 lines
9.5 KiB
Kotlin

package com.github.apognu.otter.activities
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.github.apognu.otter.R
import com.github.apognu.otter.fragments.BrowseFragment
import com.github.apognu.otter.fragments.QueueFragment
import com.github.apognu.otter.playback.MediaControlsManager
import com.github.apognu.otter.playback.PlayerService
import com.github.apognu.otter.repositories.FavoritesRepository
import com.github.apognu.otter.repositories.Repository
import com.github.apognu.otter.utils.*
import com.preference.PowerPreference
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.partial_now_playing.*
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
private val favoriteRepository = FavoritesRepository(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppContext.init(this)
setContentView(R.layout.activity_main)
setSupportActionBar(appbar)
when (intent.action) {
MediaControlsManager.NOTIFICATION_ACTION_OPEN_QUEUE.toString() -> launchDialog(QueueFragment())
}
supportFragmentManager
.beginTransaction()
.replace(R.id.container, BrowseFragment())
.commit()
startService(Intent(this, PlayerService::class.java))
watchEventBus()
CommandBus.send(Command.RefreshService)
}
override fun onResume() {
super.onResume()
now_playing_toggle.setOnClickListener {
CommandBus.send(Command.ToggleState)
}
now_playing_next.setOnClickListener {
CommandBus.send(Command.NextTrack)
}
now_playing_details_previous.setOnClickListener {
CommandBus.send(Command.PreviousTrack)
}
now_playing_details_next.setOnClickListener {
CommandBus.send(Command.NextTrack)
}
now_playing_details_toggle.setOnClickListener {
CommandBus.send(Command.ToggleState)
}
now_playing_details_progress.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onStopTrackingTouch(view: SeekBar?) {}
override fun onStartTrackingTouch(view: SeekBar?) {}
override fun onProgressChanged(view: SeekBar?, progress: Int, fromUser: Boolean) {
if (fromUser) {
CommandBus.send(Command.Seek(progress))
}
}
})
}
override fun onBackPressed() {
if (now_playing.isOpened()) {
now_playing.close()
return
}
super.onBackPressed()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.toolbar, menu)
// CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.cast)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
now_playing.close()
(supportFragmentManager.fragments.last() as? BrowseFragment)?.let {
it.selectTabAt(0)
return true
}
launchFragment(BrowseFragment())
}
R.id.nav_queue -> launchDialog(QueueFragment())
R.id.nav_search -> startActivity(Intent(this, SearchActivity::class.java))
R.id.settings -> startActivity(Intent(this, SettingsActivity::class.java))
}
return true
}
private fun launchFragment(fragment: Fragment) {
supportFragmentManager.fragments.lastOrNull()?.also { oldFragment ->
oldFragment.enterTransition = null
oldFragment.exitTransition = null
supportFragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
}
supportFragmentManager
.beginTransaction()
.setCustomAnimations(0, 0, 0, 0)
.replace(R.id.container, fragment)
.commit()
}
private fun launchDialog(fragment: DialogFragment) {
supportFragmentManager.beginTransaction().let {
fragment.show(it, "")
}
}
@SuppressLint("NewApi")
private fun watchEventBus() {
GlobalScope.launch(Main) {
for (message in EventBus.asChannel<Event>()) {
when (message) {
is Event.LogOut -> {
PowerPreference.clearAllData()
startActivity(Intent(this@MainActivity, LoginActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NO_HISTORY
})
finish()
}
is Event.PlaybackError -> toast(message.message)
is Event.Buffering -> {
when (message.value) {
true -> now_playing_buffering.visibility = View.VISIBLE
false -> now_playing_buffering.visibility = View.GONE
}
}
is Event.PlaybackStopped -> {
if (now_playing.visibility == View.VISIBLE) {
(container.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
it.bottomMargin = it.bottomMargin / 2
}
now_playing.animate()
.alpha(0.0f)
.setDuration(400)
.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animator: Animator?) {
now_playing.visibility = View.GONE
}
})
.start()
}
}
is Event.TrackPlayed -> {
message.track?.let { track ->
if (now_playing.visibility == View.GONE) {
now_playing.visibility = View.VISIBLE
now_playing.alpha = 0f
now_playing.animate()
.alpha(1.0f)
.setDuration(400)
.setListener(null)
.start()
(container.layoutParams as? ViewGroup.MarginLayoutParams)?.let {
it.bottomMargin = it.bottomMargin * 2
}
}
now_playing_title.text = track.title
now_playing_album.text = track.artist.name
now_playing_toggle.icon = getDrawable(R.drawable.pause)
now_playing_progress.progress = 0
now_playing_details_title.text = track.title
now_playing_details_artist.text = track.artist.name
now_playing_details_toggle.icon = getDrawable(R.drawable.pause)
now_playing_details_progress.progress = 0
Picasso.get()
.load(normalizeUrl(track.album.cover.original))
.fit()
.centerCrop()
.into(now_playing_cover)
Picasso.get()
.load(normalizeUrl(track.album.cover.original))
.fit()
.centerCrop()
.into(now_playing_details_cover)
favoriteRepository.fetch().untilNetwork(IO) { favorites ->
GlobalScope.launch(Main) {
val favorites = favorites.map { it.track.id }
track.favorite = favorites.contains(track.id)
when (track.favorite) {
true -> now_playing_details_favorite.setColorFilter(resources.getColor(R.color.colorFavorite))
false -> now_playing_details_favorite.setColorFilter(resources.getColor(R.color.controlForeground))
}
}
}
now_playing_details_favorite.setOnClickListener {
when (track.favorite) {
true -> {
favoriteRepository.deleteFavorite(track.id)
now_playing_details_favorite.setColorFilter(resources.getColor(R.color.controlForeground))
}
false -> {
favoriteRepository.addFavorite(track.id)
now_playing_details_favorite.setColorFilter(resources.getColor(R.color.colorFavorite))
}
}
track.favorite = !track.favorite
favoriteRepository.fetch(Repository.Origin.Network.origin)
}
}
}
is Event.StateChanged -> {
when (message.playing) {
true -> {
now_playing_toggle.icon = getDrawable(R.drawable.pause)
now_playing_details_toggle.icon = getDrawable(R.drawable.pause)
}
false -> {
now_playing_toggle.icon = getDrawable(R.drawable.play)
now_playing_details_toggle.icon = getDrawable(R.drawable.play)
}
}
}
}
}
}
GlobalScope.launch(Main) {
for ((current, duration, percent) in ProgressBus.asChannel()) {
now_playing_progress.progress = percent
now_playing_details_progress.progress = percent
val currentMins = (current / 1000) / 60
val currentSecs = (current / 1000) % 60
val durationMins = duration / 60
val durationSecs = duration % 60
now_playing_details_progress_current.text = "%02d:%02d".format(currentMins, currentSecs)
now_playing_details_progress_duration.text = "%02d:%02d".format(durationMins, durationSecs)
}
}
}
}