From 7915655c785234dfd339fe6cbaa4265c426916c2 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Thu, 18 May 2023 10:23:34 +0300 Subject: [PATCH 1/4] Songs sharing --- .../org/oxycblt/auxio/list/ListFragment.kt | 4 ++ .../auxio/list/selection/SelectionFragment.kt | 5 ++ .../java/org/oxycblt/auxio/music/fs/Fs.kt | 10 +++ .../java/org/oxycblt/auxio/util/ShareUtil.kt | 63 +++++++++++++++++++ .../main/res/menu/menu_selection_actions.xml | 4 ++ app/src/main/res/menu/menu_song_actions.xml | 3 + app/src/main/res/values/strings.xml | 1 + 7 files changed, 90 insertions(+) create mode 100644 app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt 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 f2e050e40..a17a666b9 100644 --- a/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt @@ -32,6 +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.showToast /** @@ -99,6 +100,9 @@ abstract class ListFragment : R.id.action_go_album -> { navModel.exploreNavigateTo(song.album) } + R.id.action_song_share -> { + requireContext().shareSong(song) + } R.id.action_playlist_add -> { musicModel.addToPlaylist(song) } 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 bcba5195e..fd43f7653 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,6 +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.showToast /** @@ -86,6 +87,10 @@ abstract class SelectionFragment : playbackModel.shuffle(selectionModel.take()) true } + R.id.action_selection_share -> { + requireContext().shareSongs(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 defbb7c3f..f169f8bde 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 @@ -212,4 +212,14 @@ 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/util/ShareUtil.kt b/app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt new file mode 100644 index 000000000..05a71ef94 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt @@ -0,0 +1,63 @@ +/* + * 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() +} diff --git a/app/src/main/res/menu/menu_selection_actions.xml b/app/src/main/res/menu/menu_selection_actions.xml index 568d04a62..e596b97a6 100644 --- a/app/src/main/res/menu/menu_selection_actions.xml +++ b/app/src/main/res/menu/menu_selection_actions.xml @@ -21,4 +21,8 @@ android:id="@+id/action_selection_shuffle" android:title="@string/lbl_shuffle_selected" app:showAsAction="never"/> + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_song_actions.xml b/app/src/main/res/menu/menu_song_actions.xml index abb176fb5..dbb15382e 100644 --- a/app/src/main/res/menu/menu_song_actions.xml +++ b/app/src/main/res/menu/menu_song_actions.xml @@ -15,6 +15,9 @@ + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c4e356c7a..f40e849d7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -118,6 +118,7 @@ Go to artist Go to album View properties + Share Song properties File name From 7f11e886f7b4e4e15ab8d20d6575f6474ddef917 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Thu, 18 May 2023 12:07:00 +0300 Subject: [PATCH 2/4] Sharing albums, artists, genres and playlists --- .../oxycblt/auxio/detail/AlbumDetailFragment.kt | 4 ++++ .../oxycblt/auxio/detail/ArtistDetailFragment.kt | 4 ++++ .../oxycblt/auxio/detail/GenreDetailFragment.kt | 4 ++++ .../auxio/detail/PlaylistDetailFragment.kt | 4 ++++ .../java/org/oxycblt/auxio/list/ListFragment.kt | 15 ++++++++++++++- .../main/java/org/oxycblt/auxio/music/fs/Fs.kt | 4 ++-- .../auxio/playback/PlaybackPanelFragment.kt | 5 +++++ .../main/java/org/oxycblt/auxio/util/ShareUtil.kt | 2 +- app/src/main/res/menu/menu_album_actions.xml | 3 +++ app/src/main/res/menu/menu_album_detail.xml | 3 +++ app/src/main/res/menu/menu_album_song_actions.xml | 3 +++ .../main/res/menu/menu_artist_album_actions.xml | 3 +++ .../main/res/menu/menu_artist_song_actions.xml | 3 +++ app/src/main/res/menu/menu_parent_actions.xml | 3 +++ app/src/main/res/menu/menu_parent_detail.xml | 3 +++ app/src/main/res/menu/menu_playback.xml | 3 +++ app/src/main/res/menu/menu_playlist_actions.xml | 3 +++ app/src/main/res/menu/menu_playlist_detail.xml | 3 +++ app/src/main/res/menu/menu_song_actions.xml | 2 +- 19 files changed, 69 insertions(+), 5 deletions(-) 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 42d6bb341..6e457c43c 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt @@ -142,6 +142,10 @@ class AlbumDetailFragment : musicModel.addToPlaylist(currentAlbum) true } + R.id.action_share -> { + requireContext().shareSongs(currentAlbum.songs) + 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 4578f664d..0ea42c903 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt @@ -137,6 +137,10 @@ class ArtistDetailFragment : musicModel.addToPlaylist(currentArtist) true } + R.id.action_share -> { + requireContext().shareSongs(currentArtist.songs) + 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 2028c3610..403e4109f 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt @@ -130,6 +130,10 @@ class GenreDetailFragment : musicModel.addToPlaylist(currentGenre) true } + R.id.action_share -> { + requireContext().shareSongs(currentGenre.songs) + 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 d1214f6b2..d42bd5823 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt @@ -130,6 +130,10 @@ class PlaylistDetailFragment : musicModel.deletePlaylist(currentPlaylist) true } + R.id.action_share -> { + requireContext().shareSongs(currentPlaylist.songs) + 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 a17a666b9..c4763d302 100644 --- a/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/list/ListFragment.kt @@ -33,6 +33,7 @@ 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.showToast /** @@ -100,7 +101,7 @@ abstract class ListFragment : R.id.action_go_album -> { navModel.exploreNavigateTo(song.album) } - R.id.action_song_share -> { + R.id.action_share -> { requireContext().shareSong(song) } R.id.action_playlist_add -> { @@ -151,6 +152,9 @@ abstract class ListFragment : R.id.action_playlist_add -> { musicModel.addToPlaylist(album) } + R.id.action_share -> { + requireContext().shareSongs(album.songs) + } else -> { error("Unexpected menu item selected") } @@ -188,6 +192,9 @@ abstract class ListFragment : R.id.action_playlist_add -> { musicModel.addToPlaylist(artist) } + R.id.action_share -> { + requireContext().shareSongs(artist.songs) + } else -> { error("Unexpected menu item selected") } @@ -225,6 +232,9 @@ abstract class ListFragment : R.id.action_playlist_add -> { musicModel.addToPlaylist(genre) } + R.id.action_share -> { + requireContext().shareSongs(genre.songs) + } else -> { error("Unexpected menu item selected") } @@ -262,6 +272,9 @@ abstract class ListFragment : R.id.action_delete -> { musicModel.deletePlaylist(playlist) } + R.id.action_share -> { + requireContext().shareSongs(playlist.songs) + } else -> { error("Unexpected menu item selected") } 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 f169f8bde..cc5334945 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 @@ -216,8 +216,8 @@ 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. + * @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 636e2e2ca..64e3f9c1d 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackPanelFragment.kt @@ -42,6 +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.showToast import org.oxycblt.auxio.util.systemBarInsetsCompat @@ -172,6 +173,10 @@ class PlaybackPanelFragment : } true } + R.id.action_share -> { + playbackModel.song.value?.let { requireContext().shareSong(it) } + true + } else -> false } diff --git a/app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt b/app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt index 05a71ef94..877795afc 100644 --- a/app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt +++ b/app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt @@ -15,7 +15,7 @@ * 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 diff --git a/app/src/main/res/menu/menu_album_actions.xml b/app/src/main/res/menu/menu_album_actions.xml index 7292d9016..6f9f28aff 100644 --- a/app/src/main/res/menu/menu_album_actions.xml +++ b/app/src/main/res/menu/menu_album_actions.xml @@ -18,4 +18,7 @@ + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_album_detail.xml b/app/src/main/res/menu/menu_album_detail.xml index 4c5d8d7d5..2da5cee9b 100644 --- a/app/src/main/res/menu/menu_album_detail.xml +++ b/app/src/main/res/menu/menu_album_detail.xml @@ -9,4 +9,7 @@ + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_album_song_actions.xml b/app/src/main/res/menu/menu_album_song_actions.xml index 256322f3e..d356eeedb 100644 --- a/app/src/main/res/menu/menu_album_song_actions.xml +++ b/app/src/main/res/menu/menu_album_song_actions.xml @@ -12,6 +12,9 @@ + diff --git a/app/src/main/res/menu/menu_artist_album_actions.xml b/app/src/main/res/menu/menu_artist_album_actions.xml index c94d6886f..a39b0127e 100644 --- a/app/src/main/res/menu/menu_artist_album_actions.xml +++ b/app/src/main/res/menu/menu_artist_album_actions.xml @@ -18,4 +18,7 @@ + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_artist_song_actions.xml b/app/src/main/res/menu/menu_artist_song_actions.xml index 4b20abd21..aaad4040a 100644 --- a/app/src/main/res/menu/menu_artist_song_actions.xml +++ b/app/src/main/res/menu/menu_artist_song_actions.xml @@ -12,6 +12,9 @@ + diff --git a/app/src/main/res/menu/menu_parent_actions.xml b/app/src/main/res/menu/menu_parent_actions.xml index 4e6112035..b741fd51b 100644 --- a/app/src/main/res/menu/menu_parent_actions.xml +++ b/app/src/main/res/menu/menu_parent_actions.xml @@ -12,6 +12,9 @@ + diff --git a/app/src/main/res/menu/menu_parent_detail.xml b/app/src/main/res/menu/menu_parent_detail.xml index 3a2225ea3..e73829b41 100644 --- a/app/src/main/res/menu/menu_parent_detail.xml +++ b/app/src/main/res/menu/menu_parent_detail.xml @@ -9,4 +9,7 @@ + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_playback.xml b/app/src/main/res/menu/menu_playback.xml index fd9e761a0..601b54b68 100644 --- a/app/src/main/res/menu/menu_playback.xml +++ b/app/src/main/res/menu/menu_playback.xml @@ -14,6 +14,9 @@ android:id="@+id/action_go_album" android:title="@string/lbl_go_album" app:showAsAction="never" /> + + diff --git a/app/src/main/res/menu/menu_playlist_detail.xml b/app/src/main/res/menu/menu_playlist_detail.xml index c3e30e8b9..761c42dd5 100644 --- a/app/src/main/res/menu/menu_playlist_detail.xml +++ b/app/src/main/res/menu/menu_playlist_detail.xml @@ -6,6 +6,9 @@ + diff --git a/app/src/main/res/menu/menu_song_actions.xml b/app/src/main/res/menu/menu_song_actions.xml index dbb15382e..cba78013b 100644 --- a/app/src/main/res/menu/menu_song_actions.xml +++ b/app/src/main/res/menu/menu_song_actions.xml @@ -16,7 +16,7 @@ android:id="@+id/action_playlist_add" android:title="@string/lbl_playlist_add" /> Date: Thu, 18 May 2023 19:27:50 +0300 Subject: [PATCH 3/4] Fix style issues --- .../auxio/detail/AlbumDetailFragment.kt | 2 +- .../auxio/detail/ArtistDetailFragment.kt | 2 +- .../auxio/detail/GenreDetailFragment.kt | 2 +- .../auxio/detail/PlaylistDetailFragment.kt | 2 +- .../org/oxycblt/auxio/list/ListFragment.kt | 13 ++-- .../auxio/list/selection/SelectionFragment.kt | 4 +- .../java/org/oxycblt/auxio/music/fs/Fs.kt | 20 +++--- .../auxio/playback/PlaybackPanelFragment.kt | 4 +- .../org/oxycblt/auxio/util/FrameworkUtil.kt | 40 ++++++++++++ .../java/org/oxycblt/auxio/util/ShareUtil.kt | 63 ------------------- 10 files changed, 64 insertions(+), 88 deletions(-) delete mode 100644 app/src/main/java/org/oxycblt/auxio/util/ShareUtil.kt 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() -} From d3c8304a0d2892fbe339bc2011879e07a9deff1b Mon Sep 17 00:00:00 2001 From: Koitharu Date: Thu, 25 May 2023 19:31:36 +0300 Subject: [PATCH 4/4] Add missing imports --- .../main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt | 1 + .../main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt | 1 + .../main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt | 1 + .../main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt | 1 + 4 files changed, 4 insertions(+) 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 1813f5cd4..d5932974e 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt @@ -57,6 +57,7 @@ import org.oxycblt.auxio.util.collectImmediately import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.navigateSafe import org.oxycblt.auxio.util.setFullWidthLookup +import org.oxycblt.auxio.util.share import org.oxycblt.auxio.util.showToast import org.oxycblt.auxio.util.unlikelyToBeNull 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 cd25fde8c..4dca06a0e 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt @@ -54,6 +54,7 @@ import org.oxycblt.auxio.util.collectImmediately import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.navigateSafe import org.oxycblt.auxio.util.setFullWidthLookup +import org.oxycblt.auxio.util.share import org.oxycblt.auxio.util.showToast import org.oxycblt.auxio.util.unlikelyToBeNull 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 d302f41a8..b3d417761 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt @@ -55,6 +55,7 @@ import org.oxycblt.auxio.util.collectImmediately import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.navigateSafe import org.oxycblt.auxio.util.setFullWidthLookup +import org.oxycblt.auxio.util.share import org.oxycblt.auxio.util.showToast import org.oxycblt.auxio.util.unlikelyToBeNull 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 1ceb225ec..5b63806ad 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/PlaylistDetailFragment.kt @@ -58,6 +58,7 @@ import org.oxycblt.auxio.util.collectImmediately import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.navigateSafe import org.oxycblt.auxio.util.setFullWidthLookup +import org.oxycblt.auxio.util.share import org.oxycblt.auxio.util.showToast import org.oxycblt.auxio.util.unlikelyToBeNull