Add bg/popup/play shuffled actions
This commit is contained in:
parent
96a57803a6
commit
b3b6cf30dc
@ -7,6 +7,7 @@ import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
import java.io.Serializable
|
||||
import java.util.Collections
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlinx.coroutines.reactive.awaitFirst
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueueEvent.AppendEvent
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueueEvent.ErrorEvent
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueueEvent.InitEvent
|
||||
@ -434,6 +435,59 @@ abstract class PlayQueue internal constructor(
|
||||
broadcast(ReorderEvent(originalIndex, 0))
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeatedly calls [fetch] until [isComplete] is `true` or some error happens, then shuffles
|
||||
* the whole queue without preserving [index]. [fetch] will be called at most 10 times to avoid
|
||||
* infinite loops, e.g. in case the playlist being fetched is infinite. This must be called only
|
||||
* to initialize the queue in an already shuffled state, and must not be called when the queue
|
||||
* is already being used e.g. by the player. The preconditions, which are also maintained as
|
||||
* postconditions, are thus that the queue is in a disposed / uninitialized state, and that
|
||||
* [index] is 0.
|
||||
*/
|
||||
suspend fun fetchAllAndShuffle() {
|
||||
if (eventBroadcast != null || this.index != 0) {
|
||||
throw UnsupportedOperationException(
|
||||
"Can call fetchAllAndShuffle() only on an uninitialized PlayQueue"
|
||||
)
|
||||
}
|
||||
|
||||
if (!isComplete) {
|
||||
init()
|
||||
var fetchCount = 0
|
||||
while (!isComplete) {
|
||||
if (fetchCount >= 10) {
|
||||
// Maybe the playlist is infinite, and anyway we don't want to overload the
|
||||
// servers by making too many requests. For reference, making 10 fetch requests
|
||||
// will mean fetching at most 1000 items on YouTube playlists, though this
|
||||
// changes among services.
|
||||
break
|
||||
}
|
||||
fetchCount += 1
|
||||
|
||||
fetch()
|
||||
|
||||
// Since `fetch()` does not return a Completable we can listen on, we have to wait
|
||||
// for events in `broadcastReceiver` produced by `fetch()`. This works reliably
|
||||
// because all `fetch()` implementations are supposed to notify all events (both
|
||||
// completion and errors) to `broadcastReceiver`.
|
||||
val event = broadcastReceiver!!
|
||||
.filter { !InitEvent::class.isInstance(it) }
|
||||
.awaitFirst()
|
||||
if (event !is AppendEvent || event.amount <= 0) {
|
||||
break // an AppendEvent with amount 0 indicates that an error occurred
|
||||
}
|
||||
}
|
||||
dispose()
|
||||
}
|
||||
|
||||
// Can't shuffle a list that's empty or only has one element
|
||||
if (size() <= 2) {
|
||||
return
|
||||
}
|
||||
backup = streams.toMutableList()
|
||||
streams.shuffle()
|
||||
}
|
||||
|
||||
/**
|
||||
* Unshuffles the current play queue if a backup play queue exists.
|
||||
*
|
||||
|
||||
@ -52,8 +52,11 @@ import org.schabi.newpipe.player.playqueue.PlayQueue
|
||||
import org.schabi.newpipe.player.playqueue.PlayQueueItem
|
||||
import org.schabi.newpipe.player.playqueue.PlaylistPlayQueue
|
||||
import org.schabi.newpipe.ui.components.menu.icons.BackgroundFromHere
|
||||
import org.schabi.newpipe.ui.components.menu.icons.BackgroundShuffled
|
||||
import org.schabi.newpipe.ui.components.menu.icons.PlayFromHere
|
||||
import org.schabi.newpipe.ui.components.menu.icons.PlayShuffled
|
||||
import org.schabi.newpipe.ui.components.menu.icons.PopupFromHere
|
||||
import org.schabi.newpipe.ui.components.menu.icons.PopupShuffled
|
||||
import org.schabi.newpipe.util.NavigationHelper
|
||||
import org.schabi.newpipe.util.external_communication.KoreUtils
|
||||
import org.schabi.newpipe.util.external_communication.ShareUtils
|
||||
@ -73,28 +76,31 @@ data class LongPressAction(
|
||||
@StringRes val label: Int,
|
||||
val icon: ImageVector
|
||||
) {
|
||||
Enqueue(0, R.string.enqueue, Icons.Default.AddToQueue),
|
||||
EnqueueNext(1, R.string.enqueue_next_stream, Icons.Default.QueuePlayNext),
|
||||
Background(2, R.string.controls_background_title, Icons.Default.Headset),
|
||||
Popup(3, R.string.controls_popup_title, Icons.Default.PictureInPicture),
|
||||
Play(4, R.string.play, Icons.Default.PlayArrow),
|
||||
BackgroundFromHere(5, R.string.background_from_here, Icons.Default.BackgroundFromHere),
|
||||
PopupFromHere(6, R.string.popup_from_here, Icons.Default.PopupFromHere),
|
||||
PlayFromHere(7, R.string.play_from_here, Icons.Default.PlayFromHere),
|
||||
PlayWithKodi(8, R.string.play_with_kodi_title, Icons.Default.Cast),
|
||||
Download(9, R.string.download, Icons.Default.Download),
|
||||
AddToPlaylist(10, R.string.add_to_playlist, Icons.AutoMirrored.Default.PlaylistAdd),
|
||||
Share(11, R.string.share, Icons.Default.Share),
|
||||
OpenInBrowser(12, R.string.open_in_browser, Icons.Default.OpenInBrowser),
|
||||
ShowChannelDetails(13, R.string.show_channel_details, Icons.Default.Person),
|
||||
MarkAsWatched(14, R.string.mark_as_watched, Icons.Default.Done),
|
||||
Delete(15, R.string.delete, Icons.Default.Delete),
|
||||
Rename(16, R.string.rename, Icons.Default.Edit),
|
||||
SetAsPlaylistThumbnail(17, R.string.set_as_playlist_thumbnail, Icons.Default.Image),
|
||||
UnsetPlaylistThumbnail(18, R.string.unset_playlist_thumbnail, Icons.Default.HideImage),
|
||||
Unsubscribe(19, R.string.unsubscribe, Icons.Default.Delete),
|
||||
ShowDetails(20, R.string.play_queue_stream_detail, Icons.Default.Info),
|
||||
Remove(21, R.string.play_queue_remove, Icons.Default.Delete);
|
||||
ShowDetails(0, R.string.play_queue_stream_detail, Icons.Default.Info),
|
||||
Enqueue(1, R.string.enqueue, Icons.Default.AddToQueue),
|
||||
EnqueueNext(2, R.string.enqueue_next_stream, Icons.Default.QueuePlayNext),
|
||||
Background(3, R.string.controls_background_title, Icons.Default.Headset),
|
||||
Popup(4, R.string.controls_popup_title, Icons.Default.PictureInPicture),
|
||||
Play(5, R.string.play, Icons.Default.PlayArrow),
|
||||
BackgroundFromHere(6, R.string.background_from_here, Icons.Default.BackgroundFromHere),
|
||||
PopupFromHere(7, R.string.popup_from_here, Icons.Default.PopupFromHere),
|
||||
PlayFromHere(8, R.string.play_from_here, Icons.Default.PlayFromHere),
|
||||
BackgroundShuffled(9, R.string.background_shuffled, Icons.Default.BackgroundShuffled),
|
||||
PopupShuffled(10, R.string.popup_shuffled, Icons.Default.PopupShuffled),
|
||||
PlayShuffled(11, R.string.play_shuffled, Icons.Default.PlayShuffled),
|
||||
PlayWithKodi(12, R.string.play_with_kodi_title, Icons.Default.Cast),
|
||||
Download(13, R.string.download, Icons.Default.Download),
|
||||
AddToPlaylist(14, R.string.add_to_playlist, Icons.AutoMirrored.Default.PlaylistAdd),
|
||||
Share(15, R.string.share, Icons.Default.Share),
|
||||
OpenInBrowser(16, R.string.open_in_browser, Icons.Default.OpenInBrowser),
|
||||
ShowChannelDetails(17, R.string.show_channel_details, Icons.Default.Person),
|
||||
MarkAsWatched(18, R.string.mark_as_watched, Icons.Default.Done),
|
||||
Rename(19, R.string.rename, Icons.Default.Edit),
|
||||
SetAsPlaylistThumbnail(20, R.string.set_as_playlist_thumbnail, Icons.Default.Image),
|
||||
UnsetPlaylistThumbnail(21, R.string.unset_playlist_thumbnail, Icons.Default.HideImage),
|
||||
Delete(22, R.string.delete, Icons.Default.Delete),
|
||||
Unsubscribe(23, R.string.unsubscribe, Icons.Default.Delete),
|
||||
Remove(24, R.string.play_queue_remove, Icons.Default.Delete);
|
||||
|
||||
fun buildAction(
|
||||
enabled: () -> Boolean = { true },
|
||||
@ -105,9 +111,9 @@ data class LongPressAction(
|
||||
// ShowChannelDetails is not enabled by default, since navigating to channel details can
|
||||
// also be done by clicking on the uploader name in the long press menu header
|
||||
val DefaultEnabledActions: List<Type> = listOf(
|
||||
ShowDetails, Enqueue, EnqueueNext, Background, Popup, BackgroundFromHere, Download,
|
||||
AddToPlaylist, Share, OpenInBrowser, MarkAsWatched, Delete,
|
||||
Rename, SetAsPlaylistThumbnail, UnsetPlaylistThumbnail, Unsubscribe, Remove
|
||||
ShowDetails, Enqueue, EnqueueNext, Background, Popup, BackgroundFromHere,
|
||||
BackgroundShuffled, Download, AddToPlaylist, Share, OpenInBrowser, MarkAsWatched,
|
||||
Rename, SetAsPlaylistThumbnail, UnsetPlaylistThumbnail, Delete, Unsubscribe, Remove
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -159,6 +165,25 @@ data class LongPressAction(
|
||||
)
|
||||
}
|
||||
|
||||
private fun buildPlayerShuffledActionList(queue: suspend (Context) -> PlayQueue): List<LongPressAction> {
|
||||
val shuffledQueue: suspend (Context) -> PlayQueue = { context ->
|
||||
val q = queue(context)
|
||||
q.fetchAllAndShuffle()
|
||||
q
|
||||
}
|
||||
return listOf(
|
||||
Type.BackgroundShuffled.buildAction { context ->
|
||||
NavigationHelper.playOnBackgroundPlayer(context, shuffledQueue(context), true)
|
||||
},
|
||||
Type.PopupShuffled.buildAction { context ->
|
||||
NavigationHelper.playOnPopupPlayer(context, shuffledQueue(context), true)
|
||||
},
|
||||
Type.PlayShuffled.buildAction { context ->
|
||||
NavigationHelper.playOnMainPlayer(context, shuffledQueue(context), false)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun buildShareActionList(item: InfoItem): List<LongPressAction> {
|
||||
return listOf(
|
||||
Type.Share.buildAction { context ->
|
||||
@ -337,6 +362,7 @@ data class LongPressAction(
|
||||
unsetPlaylistThumbnail: Runnable?
|
||||
): List<LongPressAction> {
|
||||
return buildPlayerActionList { LocalPlaylistPlayQueue(item) } +
|
||||
buildPlayerShuffledActionList { LocalPlaylistPlayQueue(item) } +
|
||||
listOf(
|
||||
Type.Rename.buildAction { onRename.run() },
|
||||
Type.Delete.buildAction { onDelete.run() },
|
||||
@ -352,6 +378,7 @@ data class LongPressAction(
|
||||
onDelete: Runnable
|
||||
): List<LongPressAction> {
|
||||
return buildPlayerActionList { PlaylistPlayQueue(item.serviceId, item.url) } +
|
||||
buildPlayerShuffledActionList { PlaylistPlayQueue(item.serviceId, item.url) } +
|
||||
buildShareActionList(
|
||||
item.orderingName ?: "",
|
||||
item.orderingName ?: "",
|
||||
@ -368,6 +395,7 @@ data class LongPressAction(
|
||||
onUnsubscribe: Runnable?
|
||||
): List<LongPressAction> {
|
||||
return buildPlayerActionList { ChannelTabPlayQueue(item.serviceId, item.url) } +
|
||||
buildPlayerShuffledActionList { ChannelTabPlayQueue(item.serviceId, item.url) } +
|
||||
buildShareActionList(item) +
|
||||
listOfNotNull(
|
||||
Type.ShowChannelDetails.buildAction { context ->
|
||||
@ -385,6 +413,7 @@ data class LongPressAction(
|
||||
@JvmStatic
|
||||
fun fromPlaylistInfoItem(item: PlaylistInfoItem): List<LongPressAction> {
|
||||
return buildPlayerActionList { PlaylistPlayQueue(item.serviceId, item.url) } +
|
||||
buildPlayerShuffledActionList { PlaylistPlayQueue(item.serviceId, item.url) } +
|
||||
buildShareActionList(item)
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
@file:Suppress("UnusedReceiverParameter")
|
||||
|
||||
package org.schabi.newpipe.ui.components.menu.icons
|
||||
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.materialIcon
|
||||
import androidx.compose.material.icons.materialPath
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Obtained by combining [androidx.compose.material.icons.filled.Headset]
|
||||
* and the tiny arrow in [androidx.compose.material.icons.filled.ContentPasteGo].
|
||||
*/
|
||||
val Icons.Filled.BackgroundShuffled: ImageVector by lazy {
|
||||
materialIcon(name = "Filled.BackgroundShuffled") {
|
||||
materialPath {
|
||||
moveTo(12.0f, 1.0f)
|
||||
curveToRelative(-4.97f, 0.0f, -9.0f, 4.03f, -9.0f, 9.0f)
|
||||
verticalLineToRelative(7.0f)
|
||||
curveToRelative(0.0f, 1.66f, 1.34f, 3.0f, 3.0f, 3.0f)
|
||||
horizontalLineToRelative(3.0f)
|
||||
verticalLineToRelative(-8.0f)
|
||||
horizontalLineTo(5.0f)
|
||||
verticalLineToRelative(-2.0f)
|
||||
curveToRelative(0.0f, -3.87f, 3.13f, -7.0f, 7.0f, -7.0f)
|
||||
reflectiveCurveToRelative(7.0f, 3.13f, 7.0f, 7.0f)
|
||||
horizontalLineToRelative(2.0f)
|
||||
curveToRelative(0.0f, -4.97f, -4.03f, -9.0f, -9.0f, -9.0f)
|
||||
close()
|
||||
}
|
||||
materialPath {
|
||||
moveTo(13f, 12f)
|
||||
moveToRelative(3.145f, 2.135f)
|
||||
lineToRelative(-2.140f, -2.135f)
|
||||
lineToRelative(-1.005f, 1.005f)
|
||||
lineToRelative(2.135f, 2.135f)
|
||||
close()
|
||||
moveToRelative(1.505f, -2.135f)
|
||||
lineToRelative(1.170f, 1.170f)
|
||||
lineToRelative(-5.820f, 5.815f)
|
||||
lineToRelative(1.005f, 1.005f)
|
||||
lineToRelative(5.825f, -5.820f)
|
||||
lineToRelative(1.170f, 1.170f)
|
||||
lineToRelative(0.000f, -3.340f)
|
||||
close()
|
||||
moveToRelative(1.215f, 4.855f)
|
||||
lineToRelative(-1.005f, 1.005f)
|
||||
lineToRelative(0.965f, 0.965f)
|
||||
lineToRelative(-1.175f, 1.175f)
|
||||
lineToRelative(3.350f, 0.000f)
|
||||
lineToRelative(0.000f, -3.350f)
|
||||
lineToRelative(-1.170f, 1.170f)
|
||||
close()
|
||||
}
|
||||
/*
|
||||
val thickness = 0.15f
|
||||
materialPath {
|
||||
moveTo(13f, 12f)
|
||||
moveToRelative(3.295f - thickness, 2.585f - 3 * thickness)
|
||||
lineToRelative(-2.590f + 3 * thickness, -2.585f + 3 * thickness)
|
||||
lineToRelative(-0.705f - 2 * thickness, 0.705f + 2 * thickness)
|
||||
lineToRelative(2.585f - 3 * thickness, 2.585f - 3 * thickness)
|
||||
close()
|
||||
moveToRelative(1.955f - 3 * thickness, -2.585f + 3 * thickness)
|
||||
lineToRelative(1.020f + thickness, 1.020f + thickness)
|
||||
lineToRelative(-6.270f + 3 * thickness, 6.265f - 3 * thickness)
|
||||
lineToRelative(0.705f + 2 * thickness, 0.705f + 2 * thickness)
|
||||
lineToRelative(6.275f - 3 * thickness, -6.270f + 3 * thickness)
|
||||
lineToRelative(1.020f + thickness, 1.020f + thickness)
|
||||
lineToRelative(0f, -2.74f - 4 * thickness)
|
||||
close()
|
||||
moveToRelative(0.165f + 7 * thickness, 4.705f + thickness)
|
||||
lineToRelative(-0.705f - 2 * thickness, 0.705f + 2 * thickness)
|
||||
lineToRelative(1.565f - 4 * thickness, 1.565f - 4 * thickness)
|
||||
lineToRelative(-1.025f - thickness, 1.025f + thickness)
|
||||
lineToRelative(2.750f + 4 * thickness, 0f)
|
||||
lineToRelative(0f, -2.750f - 4 * thickness)
|
||||
lineToRelative(-1.020f - thickness, 1.020f + thickness)
|
||||
close()
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF)
|
||||
@Composable
|
||||
private fun BackgroundShuffledPreview() {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.BackgroundShuffled,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(240.dp)
|
||||
)
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
@file:Suppress("UnusedReceiverParameter")
|
||||
|
||||
package org.schabi.newpipe.ui.components.menu.icons
|
||||
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.materialIcon
|
||||
import androidx.compose.material.icons.materialPath
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Obtained by combining [androidx.compose.material.icons.filled.PlayArrow]
|
||||
* and the tiny arrow in [androidx.compose.material.icons.filled.ContentPasteGo].
|
||||
*/
|
||||
val Icons.Filled.PlayShuffled: ImageVector by lazy {
|
||||
materialIcon(name = "Filled.PlayShuffled") {
|
||||
materialPath {
|
||||
moveTo(2.5f, 2.5f)
|
||||
verticalLineToRelative(14.0f)
|
||||
lineToRelative(11.0f, -7.0f)
|
||||
close()
|
||||
}
|
||||
materialPath {
|
||||
moveTo(14f, 12f)
|
||||
moveToRelative(3.145f, 2.135f)
|
||||
lineToRelative(-2.140f, -2.135f)
|
||||
lineToRelative(-1.005f, 1.005f)
|
||||
lineToRelative(2.135f, 2.135f)
|
||||
close()
|
||||
moveToRelative(1.505f, -2.135f)
|
||||
lineToRelative(1.170f, 1.170f)
|
||||
lineToRelative(-5.820f, 5.815f)
|
||||
lineToRelative(1.005f, 1.005f)
|
||||
lineToRelative(5.825f, -5.820f)
|
||||
lineToRelative(1.170f, 1.170f)
|
||||
lineToRelative(0.000f, -3.340f)
|
||||
close()
|
||||
moveToRelative(1.215f, 4.855f)
|
||||
lineToRelative(-1.005f, 1.005f)
|
||||
lineToRelative(0.965f, 0.965f)
|
||||
lineToRelative(-1.175f, 1.175f)
|
||||
lineToRelative(3.350f, 0.000f)
|
||||
lineToRelative(0.000f, -3.350f)
|
||||
lineToRelative(-1.170f, 1.170f)
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF)
|
||||
@Composable
|
||||
private fun PlayFromHerePreview() {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.PlayShuffled,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(240.dp)
|
||||
)
|
||||
}
|
||||
@ -0,0 +1,80 @@
|
||||
@file:Suppress("UnusedReceiverParameter")
|
||||
|
||||
package org.schabi.newpipe.ui.components.menu.icons
|
||||
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.materialIcon
|
||||
import androidx.compose.material.icons.materialPath
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Obtained by combining [androidx.compose.material.icons.filled.PictureInPicture]
|
||||
* and the tiny arrow in [androidx.compose.material.icons.filled.ContentPasteGo].
|
||||
*/
|
||||
val Icons.Filled.PopupShuffled: ImageVector by lazy {
|
||||
materialIcon(name = "Filled.PopupShuffled") {
|
||||
materialPath {
|
||||
moveTo(19.0f, 5.0f)
|
||||
horizontalLineToRelative(-8.0f)
|
||||
verticalLineToRelative(5.0f)
|
||||
horizontalLineToRelative(8.0f)
|
||||
verticalLineToRelative(-5.0f)
|
||||
close()
|
||||
moveTo(21.0f, 1.0f)
|
||||
horizontalLineToRelative(-18.0f)
|
||||
curveToRelative(-1.1f, 0.0f, -2.0f, 0.9f, -2.0f, 2.0f)
|
||||
verticalLineToRelative(14.0f)
|
||||
curveToRelative(0.0f, 1.1f, 0.9f, 2.0f, 2.0f, 2.0f)
|
||||
horizontalLineToRelative(10f)
|
||||
verticalLineToRelative(-2.0f)
|
||||
horizontalLineToRelative(-10f)
|
||||
verticalLineToRelative(-14.0f)
|
||||
horizontalLineToRelative(18.0f)
|
||||
verticalLineToRelative(7.0f)
|
||||
horizontalLineToRelative(2.0f)
|
||||
verticalLineToRelative(-7.0f)
|
||||
curveToRelative(0.0f, -1.1f, -0.9f, -2.0f, -2.0f, -2.0f)
|
||||
close()
|
||||
}
|
||||
materialPath {
|
||||
moveTo(15f, 12f)
|
||||
moveToRelative(3.145f, 2.135f)
|
||||
lineToRelative(-2.140f, -2.135f)
|
||||
lineToRelative(-1.005f, 1.005f)
|
||||
lineToRelative(2.135f, 2.135f)
|
||||
close()
|
||||
moveToRelative(1.505f, -2.135f)
|
||||
lineToRelative(1.170f, 1.170f)
|
||||
lineToRelative(-5.820f, 5.815f)
|
||||
lineToRelative(1.005f, 1.005f)
|
||||
lineToRelative(5.825f, -5.820f)
|
||||
lineToRelative(1.170f, 1.170f)
|
||||
lineToRelative(0.000f, -3.340f)
|
||||
close()
|
||||
moveToRelative(1.215f, 4.855f)
|
||||
lineToRelative(-1.005f, 1.005f)
|
||||
lineToRelative(0.965f, 0.965f)
|
||||
lineToRelative(-1.175f, 1.175f)
|
||||
lineToRelative(3.350f, 0.000f)
|
||||
lineToRelative(0.000f, -3.350f)
|
||||
lineToRelative(-1.170f, 1.170f)
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF)
|
||||
@Composable
|
||||
private fun PopupFromHerePreview() {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.PopupShuffled,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(240.dp)
|
||||
)
|
||||
}
|
||||
@ -912,4 +912,7 @@
|
||||
<string name="reset_to_defaults">Reset to defaults</string>
|
||||
<string name="long_press_menu_reset_to_defaults_confirm">Are you sure you want to reset to the default actions?</string>
|
||||
<string name="long_press_menu_actions_editor">Reorder and hide actions</string>
|
||||
<string name="background_shuffled">Background\nshuffled</string>
|
||||
<string name="popup_shuffled">Popup\nshuffled</string>
|
||||
<string name="play_shuffled">Play\nshuffled</string>
|
||||
</resources>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user