From 0cb4bda212f1abea24f7786ecdadc11371f57a6e Mon Sep 17 00:00:00 2001 From: Antoine POPINEAU Date: Tue, 5 Nov 2019 21:23:29 +0100 Subject: [PATCH] Added support for landscape mode. --- app/src/main/AndroidManifest.xml | 2 +- .../apognu/otter/activities/MainActivity.kt | 98 ++++++-- .../apognu/otter/fragments/AlbumsFragment.kt | 48 +++- .../otter/fragments/LandscapeQueueFragment.kt | 75 +++++++ .../apognu/otter/fragments/QueueFragment.kt | 28 ++- .../github/apognu/otter/utils/AppContext.kt | 2 - .../main/res/layout-land/activity_main.xml | 61 +++++ .../main/res/layout-land/fragment_albums.xml | 79 +++++++ .../main/res/layout-land/fragment_tracks.xml | 209 ++++++++++++++++++ .../res/layout-land/partial_now_playing.xml | 193 ++++++++++++++++ app/src/main/res/layout/fragment_queue.xml | 31 +-- app/src/main/res/layout/partial_queue.xml | 29 +++ app/src/main/res/menu-land/toolbar.xml | 25 +++ 13 files changed, 809 insertions(+), 71 deletions(-) create mode 100644 app/src/main/java/com/github/apognu/otter/fragments/LandscapeQueueFragment.kt create mode 100644 app/src/main/res/layout-land/activity_main.xml create mode 100644 app/src/main/res/layout-land/fragment_albums.xml create mode 100644 app/src/main/res/layout-land/fragment_tracks.xml create mode 100644 app/src/main/res/layout-land/partial_now_playing.xml create mode 100644 app/src/main/res/layout/partial_queue.xml create mode 100644 app/src/main/res/menu-land/toolbar.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d36037c..b8660be 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,7 +13,6 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" - android:screenOrientation="portrait" android:supportsRtl="true" android:theme="@style/AppTheme"> @@ -35,6 +34,7 @@ oldFragment.enterTransition = null @@ -206,6 +217,12 @@ class MainActivity : AppCompatActivity() { it.bottomMargin = it.bottomMargin / 2 } + landscape_queue?.let { landscape_queue -> + (landscape_queue.layoutParams as? ViewGroup.MarginLayoutParams)?.let { + it.bottomMargin = it.bottomMargin / 2 + } + } + now_playing.animate() .alpha(0.0f) .setDuration(400) @@ -233,6 +250,12 @@ class MainActivity : AppCompatActivity() { (container.layoutParams as? ViewGroup.MarginLayoutParams)?.let { it.bottomMargin = it.bottomMargin * 2 } + + landscape_queue?.let { landscape_queue -> + (landscape_queue.layoutParams as? ViewGroup.MarginLayoutParams)?.let { + it.bottomMargin = it.bottomMargin * 2 + } + } } now_playing_title.text = track.title @@ -251,33 +274,60 @@ class MainActivity : AppCompatActivity() { .centerCrop() .into(now_playing_cover) - Picasso.get() - .maybeLoad(maybeNormalizeUrl(track.album.cover.original)) - .fit() - .centerCrop() - .into(now_playing_details_cover) + now_playing_details_cover?.let { now_playing_details_cover -> + Picasso.get() + .maybeLoad(maybeNormalizeUrl(track.album.cover.original)) + .fit() + .centerCrop() + .into(now_playing_details_cover) + } - favoriteCheckRepository.fetch().untilNetwork(IO) { favorites, _, _ -> - GlobalScope.launch(Main) { - track.favorite = favorites.contains(track.id) + if (now_playing_details_cover == null) { + GlobalScope.launch(IO) { + val width = DisplayMetrics().apply { + windowManager.defaultDisplay.getMetrics(this) + }.widthPixels - when (track.favorite) { - true -> now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite)) - false -> now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground)) + val backgroundCover = Picasso.get() + .maybeLoad(maybeNormalizeUrl(track.album.cover.original)) + .get() + .run { Bitmap.createScaledBitmap(this, width, width, false).toDrawable(resources) } + .apply { + alpha = 20 + gravity = Gravity.CENTER + } + + withContext(Main) { + now_playing_details.background = backgroundCover } } } - now_playing_details_favorite.setOnClickListener { - when (track.favorite) { - true -> { - favoriteRepository.deleteFavorite(track.id) - now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground)) - } + now_playing_details_favorite?.let { now_playing_details_favorite -> + favoriteCheckRepository.fetch().untilNetwork(IO) { favorites, _, _ -> + GlobalScope.launch(Main) { + track.favorite = favorites.contains(track.id) - false -> { - favoriteRepository.addFavorite(track.id) - now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite)) + when (track.favorite) { + true -> now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite)) + false -> now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground)) + } + } + } + } + + now_playing_details_favorite?.let { now_playing_details_favorite -> + now_playing_details_favorite.setOnClickListener { + when (track.favorite) { + true -> { + favoriteRepository.deleteFavorite(track.id) + now_playing_details_favorite.setColorFilter(getColor(R.color.controlForeground)) + } + + false -> { + favoriteRepository.addFavorite(track.id) + now_playing_details_favorite.setColorFilter(getColor(R.color.colorFavorite)) + } } } diff --git a/app/src/main/java/com/github/apognu/otter/fragments/AlbumsFragment.kt b/app/src/main/java/com/github/apognu/otter/fragments/AlbumsFragment.kt index 2aeafd7..c7b1182 100644 --- a/app/src/main/java/com/github/apognu/otter/fragments/AlbumsFragment.kt +++ b/app/src/main/java/com/github/apognu/otter/fragments/AlbumsFragment.kt @@ -1,8 +1,12 @@ package com.github.apognu.otter.fragments +import android.graphics.Bitmap import android.os.Bundle +import android.util.DisplayMetrics +import android.view.Gravity import android.view.View import android.view.animation.AccelerateDecelerateInterpolator +import androidx.core.graphics.drawable.toDrawable import androidx.core.os.bundleOf import androidx.recyclerview.widget.RecyclerView import androidx.transition.Fade @@ -14,6 +18,12 @@ import com.github.apognu.otter.repositories.AlbumsRepository import com.github.apognu.otter.utils.* import com.squareup.picasso.Picasso import kotlinx.android.synthetic.main.fragment_albums.* +import kotlinx.android.synthetic.main.partial_now_playing.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import kotlin.math.min class AlbumsFragment : FunkwhaleFragment() { override val viewRes = R.layout.fragment_albums @@ -51,12 +61,38 @@ class AlbumsFragment : FunkwhaleFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - Picasso.get() - .maybeLoad(maybeNormalizeUrl(artistArt)) - .noFade() - .fit() - .centerCrop() - .into(cover) + cover?.let { cover -> + Picasso.get() + .maybeLoad(maybeNormalizeUrl(artistArt)) + .noFade() + .fit() + .centerCrop() + .into(cover) + } + + cover_background?.let { + activity?.let { activity -> + GlobalScope.launch(Dispatchers.IO) { + val width = DisplayMetrics().apply { + activity.windowManager.defaultDisplay.getMetrics(this) + }.widthPixels + + val backgroundCover = Picasso.get() + .maybeLoad(maybeNormalizeUrl(artistArt)) + .get() + .run { Bitmap.createScaledBitmap(this, width, width, false) } + .run { Bitmap.createBitmap(this, 0, 0, width, cover_background.height).toDrawable(resources) } + .apply { + alpha = 20 + gravity = Gravity.CENTER + } + + withContext(Dispatchers.Main) { + cover_background.background = backgroundCover + } + } + } + } artist.text = artistName } diff --git a/app/src/main/java/com/github/apognu/otter/fragments/LandscapeQueueFragment.kt b/app/src/main/java/com/github/apognu/otter/fragments/LandscapeQueueFragment.kt new file mode 100644 index 0000000..e5fc21e --- /dev/null +++ b/app/src/main/java/com/github/apognu/otter/fragments/LandscapeQueueFragment.kt @@ -0,0 +1,75 @@ +package com.github.apognu.otter.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.LinearLayoutManager +import com.github.apognu.otter.R +import com.github.apognu.otter.adapters.TracksAdapter +import com.github.apognu.otter.utils.* +import kotlinx.android.synthetic.main.partial_queue.* +import kotlinx.android.synthetic.main.partial_queue.view.* +import kotlinx.coroutines.Dispatchers.Main +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.launch + +class LandscapeQueueFragment : Fragment() { + private var adapter: TracksAdapter? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + watchEventBus() + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.partial_queue, container, false).apply { + adapter = TracksAdapter(context, fromQueue = true).also { + queue.layoutManager = LinearLayoutManager(context) + queue.adapter = it + } + } + } + + override fun onResume() { + super.onResume() + + queue?.visibility = View.GONE + placeholder?.visibility = View.VISIBLE + + refresh() + } + + private fun refresh() { + GlobalScope.launch(Main) { + RequestBus.send(Request.GetQueue).wait()?.let { response -> + adapter?.let { + it.data = response.queue.toMutableList() + it.notifyDataSetChanged() + + if (it.data.isEmpty()) { + queue?.visibility = View.GONE + placeholder?.visibility = View.VISIBLE + } else { + queue?.visibility = View.VISIBLE + placeholder?.visibility = View.GONE + } + } + } + } + } + + private fun watchEventBus() { + GlobalScope.launch(Main) { + EventBus.get().collect { message -> + when (message) { + is Event.TrackPlayed -> refresh() + is Event.QueueChanged -> refresh() + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/apognu/otter/fragments/QueueFragment.kt b/app/src/main/java/com/github/apognu/otter/fragments/QueueFragment.kt index cfab509..7b0baeb 100644 --- a/app/src/main/java/com/github/apognu/otter/fragments/QueueFragment.kt +++ b/app/src/main/java/com/github/apognu/otter/fragments/QueueFragment.kt @@ -15,6 +15,8 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialogFragment import kotlinx.android.synthetic.main.fragment_queue.* import kotlinx.android.synthetic.main.fragment_queue.view.* +import kotlinx.android.synthetic.main.partial_queue.* +import kotlinx.android.synthetic.main.partial_queue.view.* import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.collect @@ -50,6 +52,10 @@ class QueueFragment : BottomSheetDialogFragment() { adapter = TracksAdapter(context, FavoriteListener(), fromQueue = true).also { queue.layoutManager = LinearLayoutManager(context) queue.adapter = it + adapter = TracksAdapter(context, fromQueue = true).also { + included.queue.layoutManager = LinearLayoutManager(context) + included.queue.adapter = it + } } } } @@ -57,7 +63,7 @@ class QueueFragment : BottomSheetDialogFragment() { override fun onResume() { super.onResume() - queue?.visibility = View.GONE + included.queue?.visibility = View.GONE placeholder?.visibility = View.VISIBLE refresh() @@ -66,16 +72,18 @@ class QueueFragment : BottomSheetDialogFragment() { private fun refresh() { GlobalScope.launch(Main) { RequestBus.send(Request.GetQueue).wait()?.let { response -> - adapter?.let { - it.data = response.queue.toMutableList() - it.notifyDataSetChanged() + included?.let { + adapter?.let { + it.data = response.queue.toMutableList() + it.notifyDataSetChanged() - if (it.data.isEmpty()) { - queue?.visibility = View.GONE - placeholder?.visibility = View.VISIBLE - } else { - queue?.visibility = View.VISIBLE - placeholder?.visibility = View.GONE + if (it.data.isEmpty()) { + included.queue?.visibility = View.GONE + placeholder?.visibility = View.VISIBLE + } else { + included.queue?.visibility = View.VISIBLE + placeholder?.visibility = View.GONE + } } } } diff --git a/app/src/main/java/com/github/apognu/otter/utils/AppContext.kt b/app/src/main/java/com/github/apognu/otter/utils/AppContext.kt index cb2c267..30bb892 100644 --- a/app/src/main/java/com/github/apognu/otter/utils/AppContext.kt +++ b/app/src/main/java/com/github/apognu/otter/utils/AppContext.kt @@ -25,8 +25,6 @@ object AppContext { fun init(context: Activity) { setupNotificationChannels(context) - context.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT - // CastContext.getSharedInstance(context) FuelManager.instance.addResponseInterceptor { next -> diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml new file mode 100644 index 0000000..8b7fc49 --- /dev/null +++ b/app/src/main/res/layout-land/activity_main.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/fragment_albums.xml b/app/src/main/res/layout-land/fragment_albums.xml new file mode 100644 index 0000000..35ec3a1 --- /dev/null +++ b/app/src/main/res/layout-land/fragment_albums.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/fragment_tracks.xml b/app/src/main/res/layout-land/fragment_tracks.xml new file mode 100644 index 0000000..70590de --- /dev/null +++ b/app/src/main/res/layout-land/fragment_tracks.xml @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/partial_now_playing.xml b/app/src/main/res/layout-land/partial_now_playing.xml new file mode 100644 index 0000000..a466912 --- /dev/null +++ b/app/src/main/res/layout-land/partial_now_playing.xml @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_queue.xml b/app/src/main/res/layout/fragment_queue.xml index af0a3b8..6d98143 100644 --- a/app/src/main/res/layout/fragment_queue.xml +++ b/app/src/main/res/layout/fragment_queue.xml @@ -1,7 +1,6 @@ - - - - - - - + diff --git a/app/src/main/res/layout/partial_queue.xml b/app/src/main/res/layout/partial_queue.xml new file mode 100644 index 0000000..5961252 --- /dev/null +++ b/app/src/main/res/layout/partial_queue.xml @@ -0,0 +1,29 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu-land/toolbar.xml b/app/src/main/res/menu-land/toolbar.xml new file mode 100644 index 0000000..910c3ae --- /dev/null +++ b/app/src/main/res/menu-land/toolbar.xml @@ -0,0 +1,25 @@ + + + + + + + + + + \ No newline at end of file