diff --git a/.idea/.name b/.idea/.name
index 690430049..49f1fe95d 100644
--- a/.idea/.name
+++ b/.idea/.name
@@ -1 +1 @@
-Shuttle Music Player
\ No newline at end of file
+shuttle
\ No newline at end of file
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
index aa0e1ff97..68f01585a 100644
--- a/android/app/build.gradle.kts
+++ b/android/app/build.gradle.kts
@@ -220,6 +220,9 @@ android {
// ExoPlayer
implementation(libs.exoplayer.core)
implementation(libs.exoplayer.hls)
+ // Local AARs with 16KB-aligned native libs (for Android page size compatibility)
+ implementation(files("libs/extension-flac.aar"))
+ implementation(files("libs/extension-opus.aar"))
implementation(libs.androidx.drawerlayout)
diff --git a/android/app/libs/extension-flac.aar b/android/app/libs/extension-flac.aar
new file mode 100644
index 000000000..905cd6923
Binary files /dev/null and b/android/app/libs/extension-flac.aar differ
diff --git a/android/app/libs/extension-opus.aar b/android/app/libs/extension-opus.aar
new file mode 100644
index 000000000..1eed34fcf
Binary files /dev/null and b/android/app/libs/extension-opus.aar differ
diff --git a/android/app/src/main/assets/changelog.json b/android/app/src/main/assets/changelog.json
index f09ed49a1..796cc0884 100644
--- a/android/app/src/main/assets/changelog.json
+++ b/android/app/src/main/assets/changelog.json
@@ -1,16 +1,20 @@
[
{
"versionName": "1.0.8",
- "releaseDate": "03/11/2025",
+ "releaseDate": "10/01/2026",
"features": [
+ "Added app shortcut to toggle playback"
],
"fixes": [
- "Fixed an issue where some tags could not be read"
+ "Fixed an issue where some tags could not be read",
+ "Fixed a bluetooth metadata issue affecting the queue after track 7",
+ "Removed QuickLyric - no longer available on the Play Store"
],
"improvements": [
"Migrate some stuff to Compose (Thanks Àlex Magaz Graça)",
"Add support for hidden files in folder based artwork with `.` in filename (e.g. `.cover.jpg`) (Thnks a-gss)",
- "Ensure native libraries support 16kb page size (new Android requirement)"
+ "Ensure native libraries support 16kb page size (new Android requirement)",
+ "Improved native artwork detection"
],
"notes": [
"What's up? I want to make Shuttle great again. I just need more hours in the day, and more days in the week!"
diff --git a/android/app/src/main/java/com/simplecityapps/shuttle/ui/lyrics/QuickLyricManager.kt b/android/app/src/main/java/com/simplecityapps/shuttle/ui/lyrics/QuickLyricManager.kt
deleted file mode 100644
index e7038d5fc..000000000
--- a/android/app/src/main/java/com/simplecityapps/shuttle/ui/lyrics/QuickLyricManager.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.simplecityapps.shuttle.ui.lyrics
-
-import android.content.Context
-import android.content.Intent
-import android.content.pm.PackageManager
-import android.net.Uri
-
-object QuickLyricManager {
- fun isQuickLyricInstalled(context: Context): Boolean = try {
- context.packageManager.getPackageInfo("com.geecko.QuickLyric", PackageManager.GET_ACTIVITIES)
- true
- } catch (ignored: PackageManager.NameNotFoundException) {
- false
- }
-
- fun buildLyricsIntent(
- artistName: String,
- songName: String
- ): Intent = Intent("com.geecko.QuickLyric.getLyrics").apply {
- putExtra("TAGS", arrayOf(artistName, songName))
- }
-
- /**
- * @return true if the Play Store is available, and QuickLyric can be downloaded
- */
- fun canDownloadQuickLyric(context: Context): Boolean = quickLyricIntent.resolveActivity(context.packageManager) != null
-
- val quickLyricIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.geecko.QuickLyric"))
-}
diff --git a/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackContract.kt b/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackContract.kt
index bdde0e843..5e3014d35 100644
--- a/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackContract.kt
+++ b/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackContract.kt
@@ -39,15 +39,6 @@ interface PlaybackContract {
fun goToArtist(artist: com.simplecityapps.shuttle.model.AlbumArtist)
- fun launchQuickLyric(
- artistName: String,
- songName: String
- )
-
- fun getQuickLyric()
-
- fun showQuickLyricUnavailable()
-
fun showSongInfoDialog(song: com.simplecityapps.shuttle.model.Song)
fun displayLyrics(lyrics: String)
@@ -84,9 +75,7 @@ interface PlaybackContract {
fun showSongInfo()
- fun showOrLaunchLyrics()
-
- fun launchQuickLyric()
+ fun showLyrics()
fun clearQueue()
}
diff --git a/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackFragment.kt b/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackFragment.kt
index 2fef7beef..ff0019061 100644
--- a/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackFragment.kt
+++ b/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackFragment.kt
@@ -8,7 +8,6 @@ import android.view.ViewGroup
import android.widget.Button
import android.widget.SeekBar
import android.widget.TextView
-import android.widget.Toast
import androidx.appcompat.widget.Toolbar
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
@@ -42,7 +41,6 @@ import com.simplecityapps.shuttle.ui.common.view.fadeIn
import com.simplecityapps.shuttle.ui.common.view.fadeOut
import com.simplecityapps.shuttle.ui.common.view.multisheet.MultiSheetView
import com.simplecityapps.shuttle.ui.common.view.multisheet.findParentMultiSheetView
-import com.simplecityapps.shuttle.ui.lyrics.QuickLyricManager
import com.simplecityapps.shuttle.ui.screens.library.albumartists.detail.AlbumArtistDetailFragmentArgs
import com.simplecityapps.shuttle.ui.screens.library.albums.detail.AlbumDetailFragmentArgs
import com.simplecityapps.shuttle.ui.screens.queue.QueueFragment
@@ -88,7 +86,6 @@ class PlaybackFragment :
private var lyricsView: View by autoCleared()
private var lyricsText: TextView by autoCleared()
private var closeLyricsButton: Button by autoCleared()
- private var quickLyricButton: Button by autoCleared()
private var pendingScrollPosition: Int? = null
@@ -174,8 +171,6 @@ class PlaybackFragment :
lyricsText = view.findViewById(R.id.lyricsTextView)
closeLyricsButton = view.findViewById(R.id.closeLyricsButton)
closeLyricsButton.setOnClickListener { lyricsView.fadeOut() }
- quickLyricButton = view.findViewById(R.id.quickLyricButton)
- quickLyricButton.setOnClickListener { presenter.launchQuickLyric() }
recyclerView.adapter = adapter
recyclerView.setRecyclerListener(RecyclerListener())
@@ -197,24 +192,29 @@ class PlaybackFragment :
presenter.sleepTimerClicked()
true
}
+
R.id.lyrics -> {
- presenter.showOrLaunchLyrics()
+ presenter.showLyrics()
true
}
+
R.id.songInfo -> {
presenter.showSongInfo()
true
}
+
R.id.editTags -> {
queueManager.getCurrentItem()?.song?.let { song ->
TagEditorAlertDialog.newInstance(listOf(song)).show(childFragmentManager)
}
true
}
+
R.id.clearQueue -> {
presenter.clearQueue()
true
}
+
else -> false
}
}
@@ -274,6 +274,7 @@ class PlaybackFragment :
skipPrevButton.isVisible = false
skipButton.isVisible = false
}
+
else -> {
seekBackwardButton.isVisible = false
seekForwardButton.isVisible = false
@@ -290,7 +291,13 @@ class PlaybackFragment :
}
toolbar.menu.findItem(R.id.lyrics)?.let { menuItem ->
- menuItem.title = song.lyrics?.let { getString(R.string.lyrics_title) } ?: getString(R.string.lyrics_quicklyric_title)
+ val title = song.lyrics?.let { getString(R.string.lyrics_title) }
+ if (title == null) {
+ menuItem.isVisible = false
+ } else {
+ menuItem.title = title
+ menuItem.isVisible = true
+ }
}
}
}
@@ -369,24 +376,6 @@ class PlaybackFragment :
}, 200)
}
- override fun launchQuickLyric(
- artistName: String,
- songName: String
- ) {
- val intent = QuickLyricManager.buildLyricsIntent(artistName, songName)
- if (intent.resolveActivity(requireContext().packageManager) != null) {
- requireContext().startActivity(intent)
- }
- }
-
- override fun getQuickLyric() {
- requireContext().startActivity(QuickLyricManager.quickLyricIntent)
- }
-
- override fun showQuickLyricUnavailable() {
- Toast.makeText(requireContext(), getString(R.string.lyrics_quicklyric_unavailable), Toast.LENGTH_LONG).show()
- }
-
override fun showSongInfoDialog(song: Song) {
SongInfoDialogFragment.newInstance(song).show(childFragmentManager)
}
diff --git a/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackPresenter.kt b/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackPresenter.kt
index bb182954d..666bde310 100644
--- a/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackPresenter.kt
+++ b/android/app/src/main/java/com/simplecityapps/shuttle/ui/screens/playback/PlaybackPresenter.kt
@@ -15,7 +15,6 @@ import com.simplecityapps.playback.queue.QueueItem
import com.simplecityapps.playback.queue.QueueManager
import com.simplecityapps.playback.queue.QueueWatcher
import com.simplecityapps.shuttle.ui.common.mvp.BasePresenter
-import com.simplecityapps.shuttle.ui.lyrics.QuickLyricManager
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import kotlinx.coroutines.Job
@@ -219,27 +218,10 @@ constructor(
}
}
- override fun showOrLaunchLyrics() {
+ override fun showLyrics() {
queueManager.getCurrentItem()?.let { queueItem ->
queueItem.song.lyrics?.let { lyrics ->
view?.displayLyrics(lyrics)
- } ?: launchQuickLyric()
- }
- }
-
- override fun launchQuickLyric() {
- queueManager.getCurrentItem()?.let { queueItem ->
- if (QuickLyricManager.isQuickLyricInstalled(context)) {
- view?.launchQuickLyric(
- queueItem.song.albumArtist ?: context.getString(com.simplecityapps.core.R.string.unknown),
- queueItem.song.name ?: context.getString(com.simplecityapps.core.R.string.unknown)
- )
- } else {
- if (QuickLyricManager.canDownloadQuickLyric(context)) {
- view?.getQuickLyric()
- } else {
- view?.showQuickLyricUnavailable()
- }
}
}
}
diff --git a/android/app/src/main/res/layout/view_lyrics.xml b/android/app/src/main/res/layout/view_lyrics.xml
index 2377f6519..bde951b9c 100644
--- a/android/app/src/main/res/layout/view_lyrics.xml
+++ b/android/app/src/main/res/layout/view_lyrics.xml
@@ -51,20 +51,6 @@
-
-