Finally unify all icon activation states under the new grade modifier
in Material Symbols.
This provides similar clarify to the dot/greyed state, but without
inconsistent meanings. The shuffle icon did have to be bolded a little
more though, as the grade did not seem to do much.
Rework the UI flow for music loading to be more coherent with runtime
rescanning.
The loading progress is now shown as a card on the bottom of the
screen. This way, app use is not completely crippled when the app has
to rescan the music library, albeit the shuffle button still has to
be disabled during this period.
Audit usages of Synchronized throughout the app to prevent deadlocks.
This is primarily composed of not making long-running work
synchronized, instead only making mutations and reads synchronized.
This does cause minor issues, such as during a sanitization event
the playback state could be feasibly saved, changed, and then restored
back to the previous state unintentionally. However, preventing
deadlocks is generally better than trying to fix those.
Use the @Synchronized annotation instead of synchronized.
Makes my ability to manage thread-safety on the shared objects much
easier. Because I don't have to think about what I should guard
and what I shouldn't.
Finally enable runtime rescanning, opening the door for a ton of new
features and automatic rescanning later on.
More work needs to be done on making the shared mutable state in-app
safer to use.
Improve the indexer callback system to be more coherent and efficient.
This delegates the old Callback role to a new singular Callback and
Controller roles. IndexerService also handles the loading process
more gracefully, reducing the amount of time music loads take.
Rework the rounded covers option into a new "Round Mode" option.
This commit extends the rounded corners configuration to now the
widget, thus making the setting apply now to covers, the bar, and
the widget configuration. This makes a naming change useful.
Further rework the button layout to be alike to other modern widgets.
This changeset transforms the play button into a FAB-ish thing,
makes spacing coherent between the uses of each layout, and adds
spacers to make the buttons layout in a more appealing way.
Update the library update process to be on a co-routine, updating
callbacks on the main thread.
For some insane reason, the Main dispatcher used normally when
loading music just disappears sometimes. This leads to unpleasent
crashes as callbacks expect to be called on the app thread, not
any background threads.
Fix this by forcing the Main dispatcher during the update process.
This requires the music update process to also run on a background
thread, albeit that will be useful for automatic rescanning late ron.
Completely rework Auxio's iconography based on the new material symbols
icon set.
This does the following:
1. Switches the sharp + filled icon style to an outlined + round icon
style.
2. Removes 32dp icons from everywhere except the playback panel.
This does not:
1. Actually handle optical sizes right. This is going to take some more
work to make it harmonious with the current UI.
2. Update margins in some places to be harmonious with the new icons.
This is also going to take some more work to do properly.
Rework the bottom sheet layout process to accomodate the new rounded
corners and be far more efficient.
This removes the weird content layout code and moves it into the inset
code, which not only allows content to show in the corners, but also
allows us to minimize the amount of layouts that we normally perform.
Rework Sort again into a new class that leverages a better Mode design
and static comparator instances.
This somewhat improves efficiency, but is also far easier to work with
and has far less footguns with adding new sorts.
Add a utility to easily work with lifecycle-dependent fragment objects.
This reduces the code duplication required to maintain objects that
would leak after the destruction of a fragment. We normally would not
do this as a delegate, as that usually entails some lifecycle wizardry
that can easily break and crash the app in esoteric situations.
However, this this just extends the normal lifecycle without watching
any state, it seems to be pretty safe to use.
Revamp the shared object SettingsManager into a standalone utility
called Settings.
This makes many things easier in Auxio. It completely unifies the key
format that we use (Android Strings instead of Java consts), eliminates
the pretty dumb initialization method that we use, and eliminates the
dubiousness of holding a Context-related utility in a global field.
The only cost was having to migrate even more ViewModels to Android
ViewModels. Whatever.
Add a shortcut to shuffle all songs.
This is likely the only static shortcut Auxio will have. Top tracks
and recently added are completely useless for me, so I will never
add them. I may add more dynamic shortcuts for recently played items,
however.
Note that we use a basic black shuffle icon here. I will not add icon
customization to these shortcuts.
Use ServiceCompat.stopForeground instead of stopForeground.
This is preliminary preparation for Android 13. I can only change SDK
versions however when the Android Gradle Plugin makes a new release
though.
Remove the animated indicator, replacing it with a static one.
I wish I could have kept this, but once again android is a sh******ed
mess and makes it impossible to dynamically animate something depending
on the playing state. It will restart the animation, ignore calls to
stop, or just flat out now run the code path in the first place due to
race conditions.
Further separate backend implementations to remove redundant tasks.
Generally, if I have not encountered an issue where a field is not
present/sane, I don't want to put in a "well, maybe" fallback, as
that would tank performance. Only do it when we need to.
Switch the excluded directory system to StorageVolume.
This finally removes dependence on the in-house Volume constructs, and
also completely extends fully music folder selection support to all
versions that Auxio supports.
This is possibly one of the most invasive and risky reworks I have done
with Auxio's music loader, but it's also somewhat exciting, as no other
music player I know of handles Volumes like I do.
Leverage StorageVolume when working with file paths.
StorageVolume is android's navive API for handling external volumes.
Ideally, we would want to replace our built-in volume class with this
new API, however doing so is somewhat complicated as some methods only
exist on newer API levels. This is only the first step until we are
able to migrate the excluded directory system to this as well.
Only show codecs in the "format" field, if we are able to extract them.
This is primarily for consistency, as there is no way for us to
determine the container format outside of an extension (which could not
be sane).
Fix an API 21-specific bug that could result in covers not loading when
quality covers was enabled.
This stemmed from a use of `use` on MediaMetadataRetriever, which
relied on an interface not present on the class on API 21.
Completely rework the excluded directory system into a new
"Music Folders" system.
This is implemented alongside a new "Include" mode. This mode
allows the user to restrict music indexing to a parsicular folder.
I've been reluctant to add this feature, as having two separate
options seemed bad. This resolves it by effectively packing whether
to include/exclude directories into a single option.
Resolves#154.
Add a non-queue version of the song menu to the playback panel.
While the original UI flow of clicking on each TextView to navigate
to a particular item is still present, this simply makes the action
more clear to a first-time user.
Heavily improve the way Auxio handles shows formats in the song
properties view.
This is composed of the following:
- Using ExoPlayer to find a format-specific mime type before having to
fall back to other solutions
- Keeping around the format and extension mime types so that each is
picked in the best circumstances
- Using MediaFormat to also retrieve a format-specific mime type in the
case that ExoPlayer parsing is disabled
- Adding special names for the most common formats
Use basic scroll indicators when a dialog shows a list.
Mostly for material guidelines. Excluded dialogs and int pref dialog
have not been modified, as I am still working on revamping those.
Remove malformed songs that have a size of 0 bytes, but are still
present in MediaStore.
This issue only seems to occur when files are transferred via MTP, but
are not loaded due to storage issues.
Add support for file size, format, and parent directory values to the
MediaStore backend.
I hope that this handles API boundaries properly, especially regarding
path parsing. As a side-note, I have learned of a way to extend
external volume support to even earlier versions. Maybe.
Completely rework the way Auxio handles icons.
This is mostly two changes:
1. Removing ImageButton/StyledImageButton for MaterialButton. This is
done by abusing MaterialButton's theming options to make it only show
an icon.
2. Standardizing icon sizes into small, medium, and large categories.
Small is the default, Medium and Large are for edge-cases like the
playback icons which look horrible at 24dp.
3. Abusing the Toolbar to make it follow Material 3 guidelines. This
mostly involved removing the strange icon sizing and correctly padding
the view.
4. Reworking the playback bar to use more, smaller icons, making it
more like a Toolbar in the process (which I like).
Rework PrimitiveBackingData into SyncBackingData.
Google says that you should not use DiffUtil on the main thread, as it
is far too slow. In practice, the time it takes to diff is negligable,
even more so when costly diffs are filled in with a replace call
instead. Not only that, but switching to a synced list differ fixees
the horrible nightmare that is the queue adapter. Generally a win-win
for most use-cases in Auxio.
Rework the submitList animation to be less resource intensive and nicer
looking (at the cost of scroll positioning)
notifyDatasetChanged is slow and has no animation, but list diffing is
chaotic and basically useless outside of search. However, clearing the
adapter and then populating it with new items seems to work quite well,
albeit with the scroll position being lost sadly. Switch to that.
Extend the range of tags Auxio is capable of recognizing, removing some
edge-cases in the process.
This is mostly three changes:
1. Auxio no longer tolerates tracks/discs/years that are 0. These are
usually never valid.
2. Auxio now has support for original date/year values. This are niche
tags, but I was inspired to implement it by this HN discussion at
https://news.ycombinator.com/item?id=31659799 simply because it
differentiates Auxio.
3. Auxio can handle the more esoteric tag variations in vorbis, such
as "YEAR" or "ALBUM ARTIST".
Remove the version-specific display name hacks added previously.
Turns out RELATIVE_PATH only includes the directory structure. Oh.
Since this invalidates the purpose of version-specific display name
hacks, we just remove it.
Do not add a callback to a MetadataRetriever call in ExoPlayerBackend.
This fixes an issue where if an error occurs while a future completes,
the app will crash entirely. This is because Futures run on a different
Executor and thus exceptions will not bubble up to Indexer.
Make the detail UIs respond to automatic rescanning events.
This currently has no effect, but is instead a preparation step for the
seamless addition of automatic rescanning.
Make IndexerService only auto-index music when there is no library AND
no loading has occured.
This resolves an issue where if IndexerService dies after a failed
index, IndexerService would try to index music regardless, as there was
no library present.
Add support for excluding directories on other volumes, at least from
Android Q onwards.
Previously, Auxio only supported excluding the primary volume. This was
mostly out of laziness, as the excluded directory implementation was
shamelessly copied from Phonograph. This commit completely refactors
the excluded directory system, dumpstering the old database (which was
overkill anyway) for a new system based on SharedPreferences that is
actually capable of handling external volumes.
Now, limitations regarding external volumes still apply below Android
Q, as the VOLUME_NAME field does not exist on those versions. However,
this should resolve at least one major complaint regarding the
excluded directory system. Now theres just all of the other complaints.
Resolves#134.