Commit 8afbde01 authored by Nicolas Pomepuy's avatar Nicolas Pomepuy

Audio player redesign

parent ce246978
package org.videolan.tools
import android.content.Context
import android.content.res.Resources
import android.util.TypedValue
import android.view.View
import androidx.annotation.AttrRes
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
......@@ -59,3 +62,12 @@ fun CoroutineScope.conflatedActor(time: Long = 2000L, action: () -> Unit) = acto
delay(time)
}
}
fun Context.getColorFromAttr(
@AttrRes attrColor: Int,
typedValue: TypedValue = TypedValue(),
resolveRefs: Boolean = true
): Int {
theme.resolveAttribute(attrColor, typedValue, resolveRefs)
return typedValue.data
}
......@@ -185,21 +185,20 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/songs_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:maxWidth="800dp"
app:layout_constraintTop_toBottomOf="@+id/header"
app:layout_constraintBottom_toTopOf="@+id/play_pause"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_centerHorizontal="true"
android:clipToPadding="false"
android:visibility="@{showCover ? View.GONE : View.VISIBLE}"
android:layout_gravity="center_horizontal"
android:background="?attr/background_default"
android:layout_marginBottom="@dimen/audio_player_cover_margin"
android:paddingBottom="@dimen/listview_bottom_padding" />
android:id="@+id/songs_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:maxWidth="800dp"
app:layout_constraintTop_toBottomOf="@+id/header"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_centerHorizontal="true"
android:clipToPadding="false"
android:visibility="@{showCover ? View.GONE : View.VISIBLE}"
android:layout_gravity="center_horizontal"
android:background="?attr/background_default"
android:paddingBottom="@dimen/listview_bottom_padding"
app:layout_constraintBottom_toTopOf="@+id/bottom_bar"/>
<org.videolan.vlc.gui.view.CoverMediaSwitcher
android:id="@+id/cover_media_switcher"
......@@ -221,59 +220,66 @@
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/header" />
<include
layout="@layout/shadow_bottom"
android:layout_width="0dp"
android:layout_height="6dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@+id/play_pause"
android:layout_marginBottom="@dimen/audio_player_cover_margin"
android:id="@+id/include"/>
<View
android:layout_width="0dp"
android:layout_height="72dp"
android:id="@+id/bottom_bar"
android:background="?attr/audio_player_transparent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/backgroundView"
/>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|start"
android:layout_marginStart="@dimen/default_margin"
android:clickable="true"
android:focusable="true"
android:onClick="@{fragment::onTimeLabelClick}"
android:text="@string/time_0"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/timeline"
app:layout_constraintStart_toStartOf="parent" />
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|start"
android:layout_marginStart="@dimen/default_margin"
android:clickable="true"
android:focusable="true"
android:onClick="@{fragment::onTimeLabelClick}"
android:textColor="?attr/font_audio_light"
android:text="@string/time_0"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/length"
app:layout_constraintBottom_toBottomOf="@+id/length"/>
<SeekBar
android:id="@+id/timeline"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="@dimen/half_default_margin"
android:focusable="true"
android:maxHeight="1dip"
android:minHeight="1dip"
android:paddingLeft="@dimen/half_default_margin"
android:paddingRight="@dimen/half_default_margin"
android:progressDrawable="@drawable/po_seekbar"
android:splitTrack="false"
android:thumb="@drawable/seekbar_thumb"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
android:id="@+id/timeline"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:focusable="true"
android:maxHeight="1dip"
android:minHeight="1dip"
android:paddingEnd="0dp"
android:paddingStart="0dp"
android:padding="0dp"
android:progressDrawable="@drawable/po_seekbar"
android:splitTrack="false"
android:thumb="@drawable/seekbar_thumb"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_bar"
app:layout_constraintTop_toTopOf="@+id/bottom_bar"/>
<TextView
android:id="@+id/length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|end"
android:layout_marginEnd="@dimen/default_margin"
android:contentDescription="@string/length"
android:text="@string/time_0"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/timeline"
app:layout_constraintEnd_toEndOf="parent" />
android:id="@+id/length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|end"
android:layout_marginEnd="@dimen/default_margin"
android:contentDescription="@string/length"
android:textColor="?attr/font_audio_light"
android:text="@string/time_0"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/repeat"
app:layout_constraintEnd_toEndOf="parent"
/>
<ImageView
android:id="@+id/shuffle"
......@@ -306,18 +312,18 @@
app:srcCompat="@drawable/ic_repeat"/>
<ImageView
android:id="@+id/play_pause"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginBottom="@dimen/audioplayer_controls_margin"
android:contentDescription="@string/play"
android:focusable="true"
android:onClick="@{fragment::onPlayPauseClick}"
android:onLongClick="@{fragment::onStopClick}"
android:scaleType="fitXY"
app:layout_constraintBottom_toTopOf="@+id/time"
app:layout_constraintLeft_toRightOf="@+id/previous"
app:layout_constraintRight_toLeftOf="@+id/next" />
android:id="@+id/play_pause"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginBottom="8dp"
android:contentDescription="@string/play"
android:focusable="true"
android:onClick="@{fragment::onPlayPauseClick}"
android:onLongClick="@{fragment::onStopClick}"
android:scaleType="fitXY"
app:layout_constraintLeft_toRightOf="@+id/previous"
app:layout_constraintRight_toLeftOf="@+id/next"
app:layout_constraintBottom_toBottomOf="@+id/backgroundView"/>
<ImageView
android:id="@+id/next"
......
......@@ -92,7 +92,7 @@
android:singleLine="true"
android:ellipsize="middle"
android:text="@{media.title}"
android:textSize="16sp"
android:textSize="14sp"
android:textColor="?attr/font_default"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_bias="0.5"
......@@ -113,7 +113,7 @@
android:paddingRight="8dp"
android:singleLine="true"
android:ellipsize="middle"
android:textColor="?attr/font_default"
android:textColor="?attr/font_audio_light"
android:fontFamily="sans-serif"
android:textSize="12sp"
android:visibility="@{TextUtils.isEmpty(subTitle) ? View.GONE : View.VISIBLE}"
......
......@@ -23,6 +23,7 @@
<attr name="audio_browser_separator" format="reference|color" />
<attr name="playlist_item_drag_shadow" format="reference|color" />
<attr name="audio_player_header_time" format="reference|color" />
<attr name="audio_player_transparent" format="reference|color"/>
<attr name="list_menu" format="reference|color" />
<attr name="list_subtitle" format="reference|color" />
<attr name="list_title_last" format="reference|color" />
......
......@@ -52,6 +52,8 @@
<color name="whitetransparent">#b4ffffff</color>
<color name="ripple_white">#88ffffff</color>
<color name="white_more_transparent">#33ffffff</color>
<color name="white_audio_player_transparent">#aaffffff</color>
<color name="black_audio_player_transparent">#ee2a2a2a</color>
<color name="transparent">#00000000</color>
<color name="white_selection_transparent">#44ffffff</color>
......
......@@ -39,6 +39,7 @@
<item name="background_header">@color/grey300</item>
<item name="background_audio_tips">@color/grey50transparent</item>
<item name="audio_player_background_tint">@color/whitetransparent</item>
<item name="audio_player_transparent">@color/white_audio_player_transparent</item>
<item name="audio_browser_separator">@color/orange500</item>
<item name="playlist_item_drag_shadow">@color/orange500</item>
<item name="audio_player_header_time">@color/orange500</item>
......@@ -88,7 +89,7 @@
<item name="ic_abrepeat_setb">@drawable/ic_abrepeat_setb</item>
<item name="ic_abrepeat_reset">@drawable/ic_abrepeat_reset</item>
<item name="ic_dial">@drawable/ic_dial</item>
<item name="progress_background">@color/grey300</item>
<item name="progress_background">@color/grey400</item>
<item name="ariane_text_color">@color/grey50</item>
<item name="player_icon_color">@color/black</item>
</style>
......@@ -141,6 +142,7 @@
<item name="background_header">@color/grey900</item>
<item name="background_audio_tips">@color/grey900transparent</item>
<item name="audio_player_background_tint">@color/grey900transparent</item>
<item name="audio_player_transparent">@color/black_audio_player_transparent</item>
<item name="audio_browser_separator">@color/orange500</item>
<item name="playlist_item_drag_shadow">@color/orange500</item>
<item name="audio_player_header_time">@color/orange500</item>
......
......@@ -301,7 +301,7 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, CoroutineS
binding.backgroundView.setImageBitmap(blurredCover)
binding.backgroundView.visibility = View.VISIBLE
binding.songsList.setBackgroundResource(0)
if (playerState == com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED) binding.header.setBackgroundResource(0)
binding.header.setBackgroundColor(UiTools.getColorFromAttribute(requireContext(), R.attr.audio_player_transparent))
} else setDefaultBackground()
}
}
......@@ -566,7 +566,7 @@ class AudioPlayer : Fragment(), PlaylistAdapter.IPlayer, TextWatcher, CoroutineS
setHeaderVisibilities(advFuncVisible = false, playlistSwitchVisible = false, headerPlayPauseVisible = true, progressBarVisible = true, headerTimeVisible = true, searchVisible = false)
}
BottomSheetBehavior.STATE_EXPANDED -> {
binding.header.setBackgroundResource(0)
binding.header.setBackgroundColor(UiTools.getColorFromAttribute(requireContext(), R.attr.audio_player_transparent))
setHeaderVisibilities(advFuncVisible = true, playlistSwitchVisible = true, headerPlayPauseVisible = false, progressBarVisible = false, headerTimeVisible = false, searchVisible = true)
showPlaylistTips()
playlistAdapter.currentIndex = playlistModel.currentMediaPosition
......
......@@ -25,6 +25,7 @@ package org.videolan.vlc.gui.audio
import android.annotation.TargetApi
import android.content.Context
import android.graphics.Typeface
import android.graphics.drawable.BitmapDrawable
import android.os.Build
import android.os.Message
......@@ -109,10 +110,12 @@ class PlaylistAdapter(private val player: IPlayer) : DiffUtilAdapter<AbstractMed
if (mModel?.playing != false) holder.binding.playing.start() else holder.binding.playing.stop()
holder.binding.playing.visibility = View.VISIBLE
holder.binding.coverImage.visibility = View.INVISIBLE
holder.binding.audioItemTitle.setTypeface(null, Typeface.BOLD)
currentPlayingVisu = holder.binding.playing
} else {
holder.binding.playing.stop()
holder.binding.playing.visibility = View.INVISIBLE
holder.binding.audioItemTitle.typeface = null
holder.binding.coverImage.visibility = View.VISIBLE
}
......
......@@ -30,7 +30,7 @@ import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.media.MediaRouter
import android.net.Uri
......@@ -63,8 +63,8 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.launch
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.medialibrary.MLServiceLocator
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.tools.isStarted
......@@ -78,8 +78,7 @@ import org.videolan.vlc.gui.dialogs.SavePlaylistDialog
import org.videolan.vlc.media.MediaUtils
import org.videolan.vlc.providers.medialibrary.MedialibraryProvider
import org.videolan.vlc.util.*
import java.util.Locale
import java.util.TreeMap
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.component1
import kotlin.collections.component2
......
......@@ -20,14 +20,14 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.actor
import org.videolan.libvlc.util.AndroidUtil
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.medialibrary.MLServiceLocator
import org.videolan.medialibrary.Tools
import org.videolan.medialibrary.interfaces.AbstractMedialibrary
import org.videolan.medialibrary.interfaces.media.AbstractAlbum
import org.videolan.medialibrary.interfaces.media.AbstractFolder
import org.videolan.medialibrary.interfaces.media.AbstractMediaWrapper
import org.videolan.medialibrary.interfaces.media.AbstractPlaylist
import org.videolan.medialibrary.media.*
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.vlc.PlaybackService
import org.videolan.vlc.R
import org.videolan.vlc.VLCApplication
......@@ -286,13 +286,13 @@ object MediaUtils : CoroutineScope {
var subtitle = media.nowPlaying ?: media.artist
if (media.length > 0L) {
subtitle = if (TextUtils.isEmpty(subtitle)) Tools.millisToString(media.length)
else "$subtitle - ${Tools.millisToString(media.length)}"
else "$subtitle ${Tools.millisToString(media.length)}"
}
return subtitle
}
fun getMediaTitle(mediaWrapper: AbstractMediaWrapper) = mediaWrapper.title
?: FileUtils.getFileNameFromPath(mediaWrapper.location)!!
?: FileUtils.getFileNameFromPath(mediaWrapper.location)
fun getContentMediaUri(data: Uri) = try {
VLCApplication.appContext.contentResolver.query(data,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment