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