Skip to content

Commit

Permalink
Merge pull request #659 from OxygenCobalt/dev
Browse files Browse the repository at this point in the history
Version 3.3.0
  • Loading branch information
OxygenCobalt authored Jan 3, 2024
2 parents d5017f8 + 43af2d8 commit 4e2e6f6
Show file tree
Hide file tree
Showing 186 changed files with 4,096 additions and 1,476 deletions.
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: [OxygenCobalt]
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug-crash-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ body:
attributes:
label: What android version do you use?
options:
- Android 14
- Android 13
- Android 12L
- Android 12
Expand Down
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,33 @@

## dev

## 3.3.0

#### What's New
- Added ability to rewind/skip tracks by swiping back/forward
- Added support for demo release type
- Added playlist importing/export from M3U files

#### What's Improved
- Music loading will now fail when it hangs

#### What's Changed
- Albums linked to an artist only as a collaborator are no longer included
in an artist's album count
- File name and parent path have been combined into "Path" in the Song Properties
view

#### What's Fixed
- Fixed music loading failing on all huawei devices
- Fixed prior music loads not cancelling when reloading music in settings
- Fixed certain FLAC files failing to play on some devices
- Fixed music loading failing when duplicate tags with different casing was present

#### Dev/Meta
- Revamped path management


## 3.2.1

#### What's Improved
- Added support for native M4A multi-value tags based on duplicate atoms
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<h1 align="center"><b>Auxio</b></h1>
<h4 align="center">A simple, rational music player for android.</h4>
<p align="center">
<a href="https://github.com/oxygencobalt/Auxio/releases/tag/v3.2.0">
<img alt="Latest Version" src="https://img.shields.io/static/v1?label=tag&message=v3.2.0&color=64B5F6&style=flat">
<a href="https://github.com/oxygencobalt/Auxio/releases/tag/v3.3.0">
<img alt="Latest Version" src="https://img.shields.io/static/v1?label=tag&message=v3.3.0&color=64B5F6&style=flat">
</a>
<a href="https://github.com/oxygencobalt/Auxio/releases/">
<img alt="Releases" src="https://img.shields.io/github/downloads/OxygenCobalt/Auxio/total.svg?color=4B95DE&style=flat">
Expand Down
19 changes: 12 additions & 7 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ android {
// it here so that binary stripping will work.
// TODO: Eventually you might just want to start vendoring the FFMpeg extension so the
// NDK use is unified
ndkVersion = "23.2.8568313"
ndkVersion = "25.2.9519653"
namespace "org.oxycblt.auxio"

defaultConfig {
applicationId namespace
versionName "3.2.1"
versionCode 36
versionName "3.3.0"
versionCode 37

minSdk 24
targetSdk 34
Expand All @@ -31,6 +31,7 @@ android {
}

compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
Expand Down Expand Up @@ -87,8 +88,8 @@ dependencies {
// General
implementation "androidx.core:core-ktx:1.12.0"
implementation "androidx.appcompat:appcompat:1.6.1"
implementation "androidx.activity:activity-ktx:1.8.0"
implementation "androidx.fragment:fragment-ktx:1.6.1"
implementation "androidx.activity:activity-ktx:1.8.2"
implementation "androidx.fragment:fragment-ktx:1.6.2"

// Components
// Deliberately kept on 1.2.1 to prevent a bug where the queue sheet will not collapse on
Expand All @@ -111,13 +112,13 @@ dependencies {
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"

// Media
implementation "androidx.media:media:1.6.0"
implementation "androidx.media:media:1.7.0"

// Preferences
implementation "androidx.preference:preference-ktx:1.2.1"

// Database
def room_version = '2.6.0-rc01'
def room_version = '2.6.1'
implementation "androidx.room:room-runtime:$room_version"
ksp "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
Expand All @@ -127,6 +128,7 @@ dependencies {
// Exoplayer (Vendored)
implementation project(":media-lib-exoplayer")
implementation project(":media-lib-decoder-ffmpeg")
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.4"

// Image loading
implementation 'io.coil-kt:coil-base:2.4.0'
Expand All @@ -145,6 +147,9 @@ dependencies {
// Logging
implementation 'com.jakewharton.timber:timber:5.0.1'

// Speed dial
implementation "com.leinardi.android:speed-dial:3.3.0"

// Testing
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
testImplementation "junit:junit:4.13.2"
Expand Down
26 changes: 26 additions & 0 deletions app/src/main/java/org/oxycblt/auxio/MainFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class MainFragment :
private var sheetBackCallback: SheetBackPressedCallback? = null
private var detailBackCallback: DetailBackPressedCallback? = null
private var selectionBackCallback: SelectionBackPressedCallback? = null
private var speedDialBackCallback: SpeedDialBackPressedCallback? = null
private var selectionNavigationListener: DialogAwareNavigationListener? = null
private var lastInsets: WindowInsets? = null
private var elevationNormal = 0f
Expand Down Expand Up @@ -109,6 +110,8 @@ class MainFragment :
DetailBackPressedCallback(detailModel).also { detailBackCallback = it }
val selectionBackCallback =
SelectionBackPressedCallback(listModel).also { selectionBackCallback = it }
val speedDialBackCallback =
SpeedDialBackPressedCallback(homeModel).also { speedDialBackCallback = it }

selectionNavigationListener = DialogAwareNavigationListener(listModel::dropSelection)

Expand Down Expand Up @@ -158,6 +161,7 @@ class MainFragment :
collect(detailModel.toShow.flow, ::handleShow)
collectImmediately(detailModel.editedPlaylist, detailBackCallback::invalidateEnabled)
collectImmediately(homeModel.showOuter.flow, ::handleShowOuter)
collectImmediately(homeModel.speedDialOpen, speedDialBackCallback::invalidateEnabled)
collectImmediately(listModel.selected, selectionBackCallback::invalidateEnabled)
collectImmediately(playbackModel.song, ::updateSong)
collectImmediately(playbackModel.openPanel.flow, ::handlePanel)
Expand All @@ -181,6 +185,7 @@ class MainFragment :
// navigation, navigation out of detail views, etc. We have to do this here in
// onResume or otherwise the FragmentManager will have precedence.
requireActivity().onBackPressedDispatcher.apply {
addCallback(viewLifecycleOwner, requireNotNull(speedDialBackCallback))
addCallback(viewLifecycleOwner, requireNotNull(selectionBackCallback))
addCallback(viewLifecycleOwner, requireNotNull(detailBackCallback))
addCallback(viewLifecycleOwner, requireNotNull(sheetBackCallback))
Expand All @@ -197,6 +202,7 @@ class MainFragment :

override fun onDestroyBinding(binding: FragmentMainBinding) {
super.onDestroyBinding(binding)
speedDialBackCallback = null
sheetBackCallback = null
detailBackCallback = null
selectionBackCallback = null
Expand All @@ -218,6 +224,13 @@ class MainFragment :
binding.queueSheet.coordinatorLayoutBehavior as QueueBottomSheetBehavior?

val playbackRatio = max(playbackSheetBehavior.calculateSlideOffset(), 0f)
if (playbackRatio > 0f && homeModel.speedDialOpen.value) {
// Stupid hack to prevent you from sliding the sheet up without closing the speed
// dial. Filtering out ACTION_MOVE events will cause back gestures to close the speed
// dial, which is super finicky behavior.
homeModel.setSpeedDialOpen(false)
}

val outPlaybackRatio = 1 - playbackRatio
val halfOutRatio = min(playbackRatio * 2, 1f)
val halfInPlaybackRatio = max(playbackRatio - 0.5f, 0f) * 2
Expand Down Expand Up @@ -493,4 +506,17 @@ class MainFragment :
isEnabled = selection.isNotEmpty()
}
}

private inner class SpeedDialBackPressedCallback(private val homeModel: HomeViewModel) :
OnBackPressedCallback(false) {
override fun handleOnBackPressed() {
if (homeModel.speedDialOpen.value) {
homeModel.setSpeedDialOpen(false)
}
}

fun invalidateEnabled(open: Boolean) {
isEnabled = open
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.PlaylistDecision
import org.oxycblt.auxio.music.PlaylistMessage
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.info.Disc
import org.oxycblt.auxio.playback.PlaybackDecision
Expand All @@ -55,6 +56,7 @@ import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.overrideOnOverflowMenuClick
import org.oxycblt.auxio.util.setFullWidthLookup
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull

/**
Expand Down Expand Up @@ -126,6 +128,7 @@ class AlbumDetailFragment :
collect(listModel.menu.flow, ::handleMenu)
collectImmediately(listModel.selected, ::updateSelection)
collect(musicModel.playlistDecision.flow, ::handlePlaylistDecision)
collect(musicModel.playlistMessage.flow, ::handlePlaylistMessage)
collectImmediately(
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
collect(playbackModel.playbackDecision.flow, ::handlePlaybackDecision)
Expand Down Expand Up @@ -273,12 +276,20 @@ class AlbumDetailFragment :
decision.songs.map { it.uid }.toTypedArray())
}
is PlaylistDecision.New,
is PlaylistDecision.Import,
is PlaylistDecision.Rename,
is PlaylistDecision.Delete -> error("Unexpected playlist decision $decision")
is PlaylistDecision.Delete,
is PlaylistDecision.Export -> error("Unexpected playlist decision $decision")
}
findNavController().navigateSafe(directions)
}

private fun handlePlaylistMessage(message: PlaylistMessage?) {
if (message == null) return
requireContext().showToast(message.stringRes)
musicModel.playlistMessage.consume()
}

private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
albumListAdapter.setPlaying(
song.takeIf { parent == detailModel.currentAlbum.value }, isPlaying)
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.PlaylistDecision
import org.oxycblt.auxio.music.PlaylistMessage
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackDecision
import org.oxycblt.auxio.playback.PlaybackViewModel
Expand All @@ -54,6 +55,7 @@ import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.overrideOnOverflowMenuClick
import org.oxycblt.auxio.util.setFullWidthLookup
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull

/**
Expand Down Expand Up @@ -128,6 +130,7 @@ class ArtistDetailFragment :
collect(listModel.menu.flow, ::handleMenu)
collectImmediately(listModel.selected, ::updateSelection)
collect(musicModel.playlistDecision.flow, ::handlePlaylistDecision)
collect(musicModel.playlistMessage.flow, ::handlePlaylistMessage)
collectImmediately(
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
collect(playbackModel.playbackDecision.flow, ::handlePlaybackDecision)
Expand Down Expand Up @@ -276,12 +279,20 @@ class ArtistDetailFragment :
decision.songs.map { it.uid }.toTypedArray())
}
is PlaylistDecision.New,
is PlaylistDecision.Import,
is PlaylistDecision.Rename,
is PlaylistDecision.Export,
is PlaylistDecision.Delete -> error("Unexpected playlist decision $decision")
}
findNavController().navigateSafe(directions)
}

private fun handlePlaylistMessage(message: PlaylistMessage?) {
if (message == null) return
requireContext().showToast(message.stringRes)
musicModel.playlistMessage.consume()
}

private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
val currentArtist = unlikelyToBeNull(detailModel.currentArtist.value)
val playingItem =
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ constructor(
is ReleaseType.Soundtrack -> AlbumGrouping.SOUNDTRACKS
is ReleaseType.Mix -> AlbumGrouping.DJMIXES
is ReleaseType.Mixtape -> AlbumGrouping.MIXTAPES
is ReleaseType.Demo -> AlbumGrouping.DEMOS
}
}
}
Expand Down Expand Up @@ -709,6 +710,7 @@ constructor(
SOUNDTRACKS(R.string.lbl_soundtracks),
DJMIXES(R.string.lbl_mixes),
MIXTAPES(R.string.lbl_mixtapes),
DEMOS(R.string.lbl_demos),
APPEARANCES(R.string.lbl_appears_on),
LIVE(R.string.lbl_live_group),
REMIXES(R.string.lbl_remix_group),
Expand Down
15 changes: 13 additions & 2 deletions app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.PlaylistDecision
import org.oxycblt.auxio.music.PlaylistMessage
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackDecision
import org.oxycblt.auxio.playback.PlaybackViewModel
Expand All @@ -54,6 +55,7 @@ import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.overrideOnOverflowMenuClick
import org.oxycblt.auxio.util.setFullWidthLookup
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull

/**
Expand Down Expand Up @@ -125,7 +127,8 @@ class GenreDetailFragment :
collect(detailModel.toShow.flow, ::handleShow)
collect(listModel.menu.flow, ::handleMenu)
collectImmediately(listModel.selected, ::updateSelection)
collect(musicModel.playlistDecision.flow, ::handleDecision)
collect(musicModel.playlistDecision.flow, ::handlePlaylistDecision)
collect(musicModel.playlistMessage.flow, ::handlePlaylistMessage)
collectImmediately(
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
collect(playbackModel.playbackDecision.flow, ::handlePlaybackDecision)
Expand Down Expand Up @@ -259,7 +262,7 @@ class GenreDetailFragment :
}
}

private fun handleDecision(decision: PlaylistDecision?) {
private fun handlePlaylistDecision(decision: PlaylistDecision?) {
if (decision == null) return
val directions =
when (decision) {
Expand All @@ -269,12 +272,20 @@ class GenreDetailFragment :
decision.songs.map { it.uid }.toTypedArray())
}
is PlaylistDecision.New,
is PlaylistDecision.Import,
is PlaylistDecision.Rename,
is PlaylistDecision.Export,
is PlaylistDecision.Delete -> error("Unexpected playlist decision $decision")
}
findNavController().navigateSafe(directions)
}

private fun handlePlaylistMessage(message: PlaylistMessage?) {
if (message == null) return
requireContext().showToast(message.stringRes)
musicModel.playlistMessage.consume()
}

private fun updatePlayback(song: Song?, parent: MusicParent?, isPlaying: Boolean) {
val currentGenre = unlikelyToBeNull(detailModel.currentGenre.value)
val playingItem =
Expand Down
Loading

0 comments on commit 4e2e6f6

Please sign in to comment.