add detailed song information to Now Playing

Signed-off-by: Holger Müller <github@euhm.de>
This commit is contained in:
Holger Müller 2022-03-18 20:46:38 +01:00
parent dee4675715
commit ae2055e324
No known key found for this signature in database
GPG Key ID: 016F07C42F7AC2B1
6 changed files with 58 additions and 36 deletions

View File

@ -13,26 +13,13 @@ import android.graphics.Point
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.view.ContextMenu import android.text.TextUtils
import android.view.*
import android.view.ContextMenu.ContextMenuInfo import android.view.ContextMenu.ContextMenuInfo
import android.view.GestureDetector
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.animation.AnimationUtils import android.view.animation.AnimationUtils
import android.widget.*
import android.widget.AdapterView.AdapterContextMenuInfo import android.widget.AdapterView.AdapterContextMenuInfo
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener import android.widget.SeekBar.OnSeekBarChangeListener
import android.widget.TextView
import android.widget.ViewFlipper
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.Navigation import androidx.navigation.Navigation
@ -42,24 +29,12 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.LinearSmoothScroller import androidx.recyclerview.widget.LinearSmoothScroller
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.disposables.Disposable
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.ArrayList
import java.util.Date
import java.util.Locale
import java.util.concurrent.CancellationException
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit
import kotlin.math.abs
import kotlin.math.max
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
import org.koin.core.component.get
import org.moire.ultrasonic.R import org.moire.ultrasonic.R
import org.moire.ultrasonic.adapters.BaseAdapter import org.moire.ultrasonic.adapters.BaseAdapter
import org.moire.ultrasonic.adapters.TrackViewBinder import org.moire.ultrasonic.adapters.TrackViewBinder
@ -79,14 +54,19 @@ import org.moire.ultrasonic.service.RxBus
import org.moire.ultrasonic.subsonic.ImageLoaderProvider import org.moire.ultrasonic.subsonic.ImageLoaderProvider
import org.moire.ultrasonic.subsonic.NetworkAndStorageChecker import org.moire.ultrasonic.subsonic.NetworkAndStorageChecker
import org.moire.ultrasonic.subsonic.ShareHandler import org.moire.ultrasonic.subsonic.ShareHandler
import org.moire.ultrasonic.util.CancellationToken import org.moire.ultrasonic.util.*
import org.moire.ultrasonic.util.CommunicationError
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.Util
import org.moire.ultrasonic.view.AutoRepeatButton import org.moire.ultrasonic.view.AutoRepeatButton
import org.moire.ultrasonic.view.VisualizerView import org.moire.ultrasonic.view.VisualizerView
import timber.log.Timber import timber.log.Timber
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.CancellationException
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.TimeUnit
import kotlin.math.abs
import kotlin.math.max
/** /**
* Contains the Music Player screen of Ultrasonic with playback controls and the playlist * Contains the Music Player screen of Ultrasonic with playback controls and the playlist
@ -139,6 +119,7 @@ class PlayerFragment :
private lateinit var songTitleTextView: TextView private lateinit var songTitleTextView: TextView
private lateinit var albumTextView: TextView private lateinit var albumTextView: TextView
private lateinit var artistTextView: TextView private lateinit var artistTextView: TextView
private lateinit var detailsTextView: TextView
private lateinit var albumArtImageView: ImageView private lateinit var albumArtImageView: ImageView
private lateinit var playlistView: RecyclerView private lateinit var playlistView: RecyclerView
private lateinit var positionTextView: TextView private lateinit var positionTextView: TextView
@ -176,6 +157,7 @@ class PlayerFragment :
songTitleTextView = view.findViewById(R.id.current_playing_song) songTitleTextView = view.findViewById(R.id.current_playing_song)
albumTextView = view.findViewById(R.id.current_playing_album) albumTextView = view.findViewById(R.id.current_playing_album)
artistTextView = view.findViewById(R.id.current_playing_artist) artistTextView = view.findViewById(R.id.current_playing_artist)
detailsTextView = view.findViewById(R.id.current_playing_details)
albumArtImageView = view.findViewById(R.id.current_playing_album_art_image) albumArtImageView = view.findViewById(R.id.current_playing_album_art_image)
positionTextView = view.findViewById(R.id.current_playing_position) positionTextView = view.findViewById(R.id.current_playing_position)
downloadTrackTextView = view.findViewById(R.id.current_playing_track) downloadTrackTextView = view.findViewById(R.id.current_playing_track)
@ -981,6 +963,21 @@ class PlayerFragment :
songTitleTextView.text = currentSong!!.title songTitleTextView.text = currentSong!!.title
albumTextView.text = currentSong!!.album albumTextView.text = currentSong!!.album
artistTextView.text = currentSong!!.artist artistTextView.text = currentSong!!.artist
val fileFormat: String? =
if (TextUtils.isEmpty(currentSong!!.transcodedSuffix) ||
currentSong!!.transcodedSuffix == currentSong!!.suffix ||
currentSong!!.isVideo)
currentSong!!.suffix
else
String.format(Locale.ROOT, "%s > %s", currentSong!!.suffix, currentSong!!.transcodedSuffix)
val details: String =
String.format(
Util.appContext().getString(R.string.song_details_nowplaying),
currentSong!!.genre, currentSong!!.year, currentSong!!.bitRate, fileFormat)
detailsTextView.text = details
detailsTextView.visibility = if (Settings.showNowPlayingDetails) View.VISIBLE else View.GONE
downloadTrackTextView.text = trackFormat downloadTrackTextView.text = trackFormat
downloadTotalDurationTextView.text = duration downloadTotalDurationTextView.text = duration
imageLoaderProvider.getImageLoader() imageLoaderProvider.getImageLoader()
@ -991,6 +988,7 @@ class PlayerFragment :
songTitleTextView.text = null songTitleTextView.text = null
albumTextView.text = null albumTextView.text = null
artistTextView.text = null artistTextView.text = null
detailsTextView.text = null
downloadTrackTextView.text = null downloadTrackTextView.text = null
downloadTotalDurationTextView.text = null downloadTotalDurationTextView.text = null
imageLoaderProvider.getImageLoader() imageLoaderProvider.getImageLoader()

View File

@ -90,6 +90,7 @@ object Constants {
const val PREFERENCES_KEY_CLEAR_SEARCH_HISTORY = "clearSearchHistory" const val PREFERENCES_KEY_CLEAR_SEARCH_HISTORY = "clearSearchHistory"
const val PREFERENCES_KEY_DOWNLOAD_TRANSITION = "transitionToDownloadOnPlay" const val PREFERENCES_KEY_DOWNLOAD_TRANSITION = "transitionToDownloadOnPlay"
const val PREFERENCES_KEY_INCREMENT_TIME = "incrementTime" const val PREFERENCES_KEY_INCREMENT_TIME = "incrementTime"
const val PREFERENCES_KEY_SHOW_NOW_PLAYING_DETAILS = "showNowPlayingDetails"
const val PREFERENCES_KEY_ID3_TAGS = "useId3Tags" const val PREFERENCES_KEY_ID3_TAGS = "useId3Tags"
const val PREFERENCES_KEY_SHOW_ARTIST_PICTURE = "showArtistPicture" const val PREFERENCES_KEY_SHOW_ARTIST_PICTURE = "showArtistPicture"
const val PREFERENCES_KEY_TEMP_LOSS = "tempLoss" const val PREFERENCES_KEY_TEMP_LOSS = "tempLoss"

View File

@ -189,6 +189,10 @@ object Settings {
true true
) )
@JvmStatic
var showNowPlayingDetails
by BooleanSetting(Constants.PREFERENCES_KEY_SHOW_NOW_PLAYING_DETAILS, false)
@JvmStatic @JvmStatic
var shouldUseId3Tags var shouldUseId3Tags
by BooleanSetting(Constants.PREFERENCES_KEY_ID3_TAGS, false) by BooleanSetting(Constants.PREFERENCES_KEY_ID3_TAGS, false)

View File

@ -9,6 +9,7 @@
a:layout_marginEnd="12dp" > a:layout_marginEnd="12dp" >
<LinearLayout <LinearLayout
a:id="@+id/current_playing"
a:layout_width="wrap_content" a:layout_width="wrap_content"
a:layout_height="wrap_content" a:layout_height="wrap_content"
a:layout_alignParentLeft="true" a:layout_alignParentLeft="true"
@ -19,9 +20,9 @@
a:layout_width="wrap_content" a:layout_width="wrap_content"
a:layout_height="wrap_content" a:layout_height="wrap_content"
a:layout_marginEnd="10dip" a:layout_marginEnd="10dip"
a:paddingRight="30dip"
a:ellipsize="marquee" a:ellipsize="marquee"
a:gravity="left" a:gravity="left"
a:paddingRight="30dip"
a:singleLine="true" a:singleLine="true"
a:textAppearance="?android:attr/textAppearanceLarge" a:textAppearance="?android:attr/textAppearanceLarge"
a:textStyle="bold" a:textStyle="bold"
@ -78,5 +79,15 @@
</LinearLayout> </LinearLayout>
<TextView
a:id="@+id/current_playing_details"
a:layout_width="fill_parent"
a:layout_height="wrap_content"
a:layout_below="@id/current_playing"
a:ellipsize="start"
a:gravity="center_horizontal"
a:singleLine="true"
a:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Details" />
</RelativeLayout> </RelativeLayout>

View File

@ -323,6 +323,8 @@
<string name="settings.summary.enable_ldap_users_support">This forces the app to always send the password unencrypted. Useful if the Subsonic server does not support the new authentication API for the users.</string> <string name="settings.summary.enable_ldap_users_support">This forces the app to always send the password unencrypted. Useful if the Subsonic server does not support the new authentication API for the users.</string>
<string name="settings.use_folder_for_album_artist">Use Folders For Artist Name</string> <string name="settings.use_folder_for_album_artist">Use Folders For Artist Name</string>
<string name="settings.use_folder_for_album_artist_summary">Assume top-level folder is the name of the album artist</string> <string name="settings.use_folder_for_album_artist_summary">Assume top-level folder is the name of the album artist</string>
<string name="settings.show_now_playing_details_summary">Show more song details in Now Playing (genre, year, bitrate)</string>
<string name="settings.show_now_playing_details">Show details in Now Playing</string>
<string name="settings.use_id3">Browse Using ID3 Tags</string> <string name="settings.use_id3">Browse Using ID3 Tags</string>
<string name="settings.use_id3_summary">Use ID3 tag methods instead of file system based methods</string> <string name="settings.use_id3_summary">Use ID3 tag methods instead of file system based methods</string>
<string name="settings.show_artist_picture">Show artist picture in artist list</string> <string name="settings.show_artist_picture">Show artist picture in artist list</string>
@ -332,6 +334,7 @@
<string name="settings.wifi_required_title">Download on Wi-Fi only</string> <string name="settings.wifi_required_title">Download on Wi-Fi only</string>
<string name="song_details.all">%1$s%2$s</string> <string name="song_details.all">%1$s%2$s</string>
<string name="song_details.kbps">%d kbps</string> <string name="song_details.kbps">%d kbps</string>
<string name="song_details.nowplaying">%1$s&#160;&#160;%2$d&#160;&#160;%3$d kbps %4$s</string>
<string name="util.bytes_format.byte">0 B</string> <string name="util.bytes_format.byte">0 B</string>
<string name="util.bytes_format.gigabyte">0.00 GB</string> <string name="util.bytes_format.gigabyte">0.00 GB</string>
<string name="util.bytes_format.kilobyte">0 KB</string> <string name="util.bytes_format.kilobyte">0 KB</string>
@ -468,7 +471,6 @@
<!-- Subsonic features --> <!-- Subsonic features -->
<string name="settings.features_title">Features</string> <string name="settings.features_title">Features</string>
<string name="settings.five_star_rating_title">Use five star rating for songs</string> <string name="settings.five_star_rating_title">Use five star rating for songs</string>
<string name="settings.five_star_rating_description">Use five star rating system for songs instead of simply starring/unstarring items. <string name="settings.five_star_rating_description">Use five star rating system for songs instead of simply starring/unstarring items.</string>
</string>
</resources> </resources>

View File

@ -53,6 +53,12 @@
a:title="@string/settings.playback_control_title" a:title="@string/settings.playback_control_title"
a:key="playbackControlSettings" a:key="playbackControlSettings"
app:iconSpaceReserved="false"> app:iconSpaceReserved="false">
<CheckBoxPreference
a:defaultValue="false"
a:key="showNowPlayingDetails"
a:summary="@string/settings.show_now_playing_details_summary"
a:title="@string/settings.show_now_playing_details"
app:iconSpaceReserved="false"/>
<CheckBoxPreference <CheckBoxPreference
a:defaultValue="true" a:defaultValue="true"
a:key="useId3Tags" a:key="useId3Tags"