diff --git a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt index 6e457c43c..7ed832468 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt @@ -143,7 +143,7 @@ class AlbumDetailFragment : true } R.id.action_share -> { - requireContext().shareSongs(currentAlbum.songs) + requireContext().share(currentAlbum) true } else -> false diff --git a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt index 0ea42c903..43e3e6993 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt @@ -138,7 +138,7 @@ class ArtistDetailFragment : true } R.id.action_share -> { - requireContext().shareSongs(currentArtist.songs) + requireContext().share(currentArtist) true } else -> false diff --git a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt index 403e4109f..581b2e18d 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt @@ -131,7 +131,7 @@ class GenreDetailFragment : true } R.id.action_share -> { - requireContext().shareSongs(currentGenre.songs) + requireContext().share(currentGenre) true } else -> false diff --git a/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt index d42bd5823..b1ef26f3e 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt @@ -131,7 +131,7 @@ class PlaylistDetailFragment : true } R.id.action_share -> { - requireContext().shareSongs(currentPlaylist.songs) + requireContext().share(currentPlaylist) true } else -> false diff --git a/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt b/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt index c4763d302..c9fca7b0e 100644 --- a/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt @@ -32,8 +32,7 @@ import org.oxycblt.auxio.music.* import org.oxycblt.auxio.navigation.MainNavigationAction import org.oxycblt.auxio.navigation.NavigationViewModel import org.oxycblt.auxio.util.logD -import org.oxycblt.auxio.util.shareSong -import org.oxycblt.auxio.util.shareSongs +import org.oxycblt.auxio.util.share import org.oxycblt.auxio.util.showToast /** @@ -102,7 +101,7 @@ abstract class ListFragment : navModel.exploreNavigateTo(song.album) } R.id.action_share -> { - requireContext().shareSong(song) + requireContext().share(song) } R.id.action_playlist_add -> { musicModel.addToPlaylist(song) @@ -153,7 +152,7 @@ abstract class ListFragment : musicModel.addToPlaylist(album) } R.id.action_share -> { - requireContext().shareSongs(album.songs) + requireContext().share(album) } else -> { error("Unexpected menu item selected") @@ -193,7 +192,7 @@ abstract class ListFragment : musicModel.addToPlaylist(artist) } R.id.action_share -> { - requireContext().shareSongs(artist.songs) + requireContext().share(artist) } else -> { error("Unexpected menu item selected") @@ -233,7 +232,7 @@ abstract class ListFragment : musicModel.addToPlaylist(genre) } R.id.action_share -> { - requireContext().shareSongs(genre.songs) + requireContext().share(genre) } else -> { error("Unexpected menu item selected") @@ -273,7 +272,7 @@ abstract class ListFragment : musicModel.deletePlaylist(playlist) } R.id.action_share -> { - requireContext().shareSongs(playlist.songs) + requireContext().share(playlist) } else -> { error("Unexpected menu item selected") diff --git a/app/src/main/java/org/oxycblt/auxio/list/selection/SelectionFragment.kt b/app/src/main/java/org/oxycblt/auxio/list/selection/SelectionFragment.kt index fd43f7653..2cb2403da 100644 --- a/app/src/main/java/org/oxycblt/auxio/list/selection/SelectionFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/list/selection/SelectionFragment.kt @@ -26,7 +26,7 @@ import org.oxycblt.auxio.R import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.ui.ViewBindingFragment -import org.oxycblt.auxio.util.shareSongs +import org.oxycblt.auxio.util.share import org.oxycblt.auxio.util.showToast /** @@ -88,7 +88,7 @@ abstract class SelectionFragment : true } R.id.action_selection_share -> { - requireContext().shareSongs(selectionModel.take()) + requireContext().share(selectionModel.take()) true } else -> false diff --git a/app/src/main/java/org/oxycblt/auxio/music/fs/Fs.kt b/app/src/main/java/org/oxycblt/auxio/music/fs/Fs.kt index cc5334945..63ef57a0c 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/fs/Fs.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/fs/Fs.kt @@ -147,6 +147,16 @@ data class MusicDirectories(val dirs: List, val shouldInclude: Boolea * @author Alexander Capehart (OxygenCobalt) */ data class MimeType(val fromExtension: String, val fromFormat: String?) { + + /** + * Return a mime-type such as "audio/ogg" + * + * @return A raw mime-type string. Will first try [fromFormat], then falling back to + * [fromExtension], and then null if that fails. + */ + val raw: String + get() = fromFormat ?: fromExtension + /** * Resolve the mime type into a human-readable format name, such as "Ogg Vorbis". * @@ -212,14 +222,4 @@ data class MimeType(val fromExtension: String, val fromFormat: String?) { MimeTypeMap.getSingleton().getExtensionFromMimeType(fromExtension)?.uppercase() } } - - /** - * Return a mime-type such as "audio/ogg" - * - * @return A raw mime-type string. Will first try [fromFormat], then falling back to - * [fromExtension], and then null if that fails. - */ - fun getRawType(): String { - return fromFormat ?: fromExtension - } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt index 64e3f9c1d..b02964c8d 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt @@ -42,7 +42,7 @@ import org.oxycblt.auxio.playback.state.RepeatMode import org.oxycblt.auxio.playback.ui.StyledSeekBar import org.oxycblt.auxio.ui.ViewBindingFragment import org.oxycblt.auxio.util.collectImmediately -import org.oxycblt.auxio.util.shareSong +import org.oxycblt.auxio.util.share import org.oxycblt.auxio.util.showToast import org.oxycblt.auxio.util.systemBarInsetsCompat @@ -174,7 +174,7 @@ class PlaybackPanelFragment : true } R.id.action_share -> { - playbackModel.song.value?.let { requireContext().shareSong(it) } + playbackModel.song.value?.let { requireContext().share(it) } true } else -> false diff --git a/app/src/main/java/org/oxycblt/auxio/util/FrameworkUtil.kt b/app/src/main/java/org/oxycblt/auxio/util/FrameworkUtil.kt index 14cd2a20e..abee5c248 100644 --- a/app/src/main/java/org/oxycblt/auxio/util/FrameworkUtil.kt +++ b/app/src/main/java/org/oxycblt/auxio/util/FrameworkUtil.kt @@ -27,6 +27,7 @@ import android.view.WindowInsets import androidx.annotation.RequiresApi import androidx.appcompat.widget.AppCompatButton import androidx.coordinatorlayout.widget.CoordinatorLayout +import androidx.core.app.ShareCompat import androidx.core.graphics.Insets import androidx.core.graphics.drawable.DrawableCompat import androidx.navigation.NavController @@ -34,6 +35,11 @@ import androidx.navigation.NavDirections import androidx.recyclerview.widget.RecyclerView import androidx.viewbinding.ViewBinding import java.lang.IllegalArgumentException +import org.oxycblt.auxio.music.Music +import org.oxycblt.auxio.music.MusicParent +import org.oxycblt.auxio.music.Song + +private const val MIME_TYPE_FALLBACK = "audio/*" /** * Get if this [View] contains the given [PointF], with optional leeway. @@ -248,3 +254,37 @@ fun WindowInsets.replaceSystemBarInsetsCompat( } } } + +/** + * Show system share sheet to share songs + * + * @param music the [Music] to share + */ +fun Context.share(music: Music) = share( + when (music) { + is Song -> listOf(music) + is MusicParent -> music.songs + } +) + +/** + * Show system share sheet to share multiple song + * + * @param songs the collection of [Song] to share + */ +fun Context.share(songs: Collection) { + if (songs.isEmpty()) { + return + } + val type = songs.mapTo(HashSet(songs.size)) { + it.mimeType.raw + }.singleOrNull() ?: MIME_TYPE_FALLBACK + ShareCompat.IntentBuilder(this) + .apply { + for (song in songs) { + addStream(song.uri) + } + } + .setType(type) + .startChooser() +} diff --git a/app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt b/app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt deleted file mode 100644 index 877795afc..000000000 --- a/app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2023 Auxio Project - * ShareUtil.kt is part of Auxio. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.oxycblt.auxio.util - -import android.content.Context -import androidx.core.app.ShareCompat -import org.oxycblt.auxio.music.Song - -private const val MIME_TYPE_FALLBACK = "audio/*" - -/** - * Show system share sheet to share song - * - * @param song the [Song] to share - */ -fun Context.shareSong(song: Song) { - ShareCompat.IntentBuilder(this) - .setStream(song.uri) - .setType(song.mimeType.getRawType()) - .startChooser() -} - -/** - * Show system share sheet to share multiple song - * - * @param songs the collection of [Song] to share - */ -fun Context.shareSongs(songs: Collection) { - if (songs.isEmpty()) { - return - } - if (songs.size == 1) { - shareSong(songs.first()) - return - } - val type = songs.mapTo(HashSet(songs.size)) { - it.mimeType.getRawType() - }.singleOrNull() ?: MIME_TYPE_FALLBACK - ShareCompat.IntentBuilder(this) - .apply { - for (song in songs) { - addStream(song.uri) - } - } - .setType(type) - .startChooser() -}