diff --git a/app/src/main/java/org/schabi/newpipe/error/UserAction.kt b/app/src/main/java/org/schabi/newpipe/error/UserAction.kt index 1b0d35755..27fff3d99 100644 --- a/app/src/main/java/org/schabi/newpipe/error/UserAction.kt +++ b/app/src/main/java/org/schabi/newpipe/error/UserAction.kt @@ -40,5 +40,5 @@ enum class UserAction(val message: String) { GETTING_MAIN_SCREEN_TAB("getting main screen tab"), PLAY_ON_POPUP("play on popup"), SUBSCRIPTIONS("loading subscriptions"), - LONG_PRESS_MENU_ACTION("long press menu action"), + LONG_PRESS_MENU_ACTION("long press menu action") } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.kt b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.kt index 6d8a20630..9cdcb6cbd 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/fragments/detail/VideoDetailFragment.kt @@ -1425,7 +1425,10 @@ class VideoDetailFragment : if (info.viewCount >= 0) { binding.detailViewCountView.text = Localization.localizeViewCount( - activity, false, info.streamType, info.viewCount + activity, + false, + info.streamType, + info.viewCount ) binding.detailViewCountView.visibility = View.VISIBLE } else { diff --git a/app/src/main/java/org/schabi/newpipe/ktx/Scope.kt b/app/src/main/java/org/schabi/newpipe/ktx/Scope.kt index decf1c3a6..fd6f3069e 100644 --- a/app/src/main/java/org/schabi/newpipe/ktx/Scope.kt +++ b/app/src/main/java/org/schabi/newpipe/ktx/Scope.kt @@ -8,5 +8,4 @@ package org.schabi.newpipe.ktx * .letIf(someCondition) { padding(right = 4.dp) } * ``` */ -inline fun T.letIf(condition: Boolean, block: T.() -> T): T = - if (condition) block(this) else this +inline fun T.letIf(condition: Boolean, block: T.() -> T): T = if (condition) block(this) else this diff --git a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt index 30f47a613..322e94935 100644 --- a/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/local/feed/FeedFragment.kt @@ -425,8 +425,8 @@ class FeedFragment : BaseStateFragment() { // just in case Log.w(TAG, "Could not get full list of items on long press") return@fromStreamEntity SinglePlayQueue(item.stream.toStreamInfoItem()) - }, - ), + } + ) ) return true } diff --git a/app/src/main/java/org/schabi/newpipe/ui/GestureModifiers.kt b/app/src/main/java/org/schabi/newpipe/ui/GestureModifiers.kt index 164f28e72..2fe995823 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/GestureModifiers.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/GestureModifiers.kt @@ -79,7 +79,7 @@ fun Modifier.detectDragGestures( } handleDragGestureChange( change.position.toIntOffset(), - change.positionChange(), + change.positionChange() ) change.consume() } diff --git a/app/src/main/java/org/schabi/newpipe/ui/Toolbar.kt b/app/src/main/java/org/schabi/newpipe/ui/Toolbar.kt index 40a1458af..23a597a96 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/Toolbar.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/Toolbar.kt @@ -39,7 +39,7 @@ fun NavigationIcon() { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.back), - modifier = Modifier.padding(horizontal = SizeTokens.SpacingExtraSmall), + modifier = Modifier.padding(horizontal = SizeTokens.SpacingExtraSmall) ) } diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/common/ScaffoldWithToolbar.kt b/app/src/main/java/org/schabi/newpipe/ui/components/common/ScaffoldWithToolbar.kt index 82b3ffaf6..050f03970 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/common/ScaffoldWithToolbar.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/common/ScaffoldWithToolbar.kt @@ -42,7 +42,7 @@ fun ScaffoldWithToolbar( IconButton(onClick = onBackClick) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(R.string.back), + contentDescription = stringResource(R.string.back) ) } }, diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/items/stream/StreamListItem.kt b/app/src/main/java/org/schabi/newpipe/ui/components/items/stream/StreamListItem.kt index 3078a4aff..dac6d32ae 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/items/stream/StreamListItem.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/items/stream/StreamListItem.kt @@ -36,7 +36,7 @@ import org.schabi.newpipe.ui.theme.AppTheme fun StreamListItem( stream: StreamInfoItem, showProgress: Boolean, - onClick: (StreamInfoItem) -> Unit = {}, + onClick: (StreamInfoItem) -> Unit = {} ) { var showLongPressMenu by rememberSaveable { mutableStateOf(false) } @@ -81,7 +81,7 @@ fun StreamListItem( longPressable = LongPressable.fromStreamInfoItem(stream), // TODO queueFromHere: allow playing the whole list starting from one stream longPressActions = LongPressAction.fromStreamInfoItem(stream, null), - onDismissRequest = { showLongPressMenu = false }, + onDismissRequest = { showLongPressMenu = false } ) } } diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressAction.kt b/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressAction.kt index 95042e9e9..757ccf665 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressAction.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressAction.kt @@ -60,7 +60,7 @@ data class LongPressAction( val type: Type, @MainThread val action: suspend (context: Context) -> Unit, - val enabled: (isPlayerRunning: Boolean) -> Boolean = { true }, + val enabled: (isPlayerRunning: Boolean) -> Boolean = { true } ) { enum class Type( /** @@ -69,7 +69,7 @@ data class LongPressAction( */ val id: Int, @StringRes val label: Int, - val icon: ImageVector, + val icon: ImageVector ) { Enqueue(0, R.string.enqueue, Icons.Default.AddToQueue), EnqueueNext(1, R.string.enqueue_next_stream, Icons.Default.QueuePlayNext), @@ -92,7 +92,7 @@ data class LongPressAction( 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), + Remove(21, R.string.play_queue_remove, Icons.Default.Delete) ; // TODO allow actions to return disposables @@ -100,7 +100,7 @@ data class LongPressAction( fun buildAction( enabled: (isPlayerRunning: Boolean) -> Boolean = { true }, - action: suspend (context: Context) -> Unit, + action: suspend (context: Context) -> Unit ) = LongPressAction(this, action, enabled) companion object { @@ -109,7 +109,7 @@ data class LongPressAction( val DefaultEnabledActions: List = listOf( ShowDetails, Enqueue, EnqueueNext, Background, Popup, BackgroundFromHere, Download, AddToPlaylist, Share, OpenInBrowser, MarkAsWatched, Delete, - Rename, SetAsPlaylistThumbnail, UnsetPlaylistThumbnail, Unsubscribe, Remove, + Rename, SetAsPlaylistThumbnail, UnsetPlaylistThumbnail, Unsubscribe, Remove ) } } @@ -133,7 +133,7 @@ data class LongPressAction( }, Type.Play.buildAction { context -> NavigationHelper.playOnMainPlayer(context, queue(context), false) - }, + } ) } @@ -147,7 +147,7 @@ data class LongPressAction( }, Type.PlayFromHere.buildAction { context -> NavigationHelper.playOnMainPlayer(context, queueFromHere(), false) - }, + } ) } @@ -158,7 +158,7 @@ data class LongPressAction( }, Type.OpenInBrowser.buildAction { context -> ShareUtils.openUrlInBrowser(context, item.url) - }, + } ) } @@ -169,7 +169,7 @@ data class LongPressAction( }, Type.OpenInBrowser.buildAction { context -> ShareUtils.openUrlInBrowser(context, url) - }, + } ) } @@ -200,13 +200,16 @@ data class LongPressAction( }, Type.ShowChannelDetails.buildAction { context -> val uploaderUrl = fetchUploaderUrlIfSparse( - context, item.serviceId, item.url, item.uploaderUrl + context, + item.serviceId, + item.url, + item.uploaderUrl ) NavigationHelper.openChannelFragment( context.findFragmentActivity().supportFragmentManager, item.serviceId, uploaderUrl, - item.uploaderName, + item.uploaderName ) }, Type.MarkAsWatched.buildAction { context -> @@ -216,7 +219,7 @@ data class LongPressAction( }, Type.PlayWithKodi.buildAction { context -> KoreUtils.playWithKore(context, item.url.toUri()) - }, + } ) } @@ -227,7 +230,7 @@ data class LongPressAction( @JvmStatic fun fromStreamInfoItem( item: StreamInfoItem, - queueFromHere: (() -> PlayQueue)?, + queueFromHere: (() -> PlayQueue)? /* TODO isKodiEnabled: Boolean, */ ): List { return buildPlayerActionList { context -> fetchItemInfoIfSparse(context, item) } + @@ -239,7 +242,7 @@ data class LongPressAction( @JvmStatic fun fromStreamEntity( item: StreamEntity, - queueFromHere: (() -> PlayQueue)?, + queueFromHere: (() -> PlayQueue)? ): List { // TODO decide if it's fine to just convert to StreamInfoItem here (it poses an // unnecessary dependency on the extractor, when we want to just look at data; maybe @@ -251,38 +254,43 @@ data class LongPressAction( fun fromPlayQueueItem( item: PlayQueueItem, playQueueFromWhichToDelete: PlayQueue, - showDetails: Boolean, + showDetails: Boolean ): List { // TODO decide if it's fine to just convert to StreamInfoItem here (it poses an // unnecessary dependency on the extractor, when we want to just look at data; maybe // using something like LongPressable would work) val streamInfoItem = item.toStreamInfoItem() return buildShareActionList(streamInfoItem) + - buildAdditionalStreamActionList(streamInfoItem) + - if (showDetails) { - listOf( - Type.ShowDetails.buildAction { context -> - // playQueue is null since we don't want any queue change - NavigationHelper.openVideoDetail( - context, item.serviceId, item.url, item.title, null, false - ) - } - ) - } else { - listOf() - } + + buildAdditionalStreamActionList(streamInfoItem) + + if (showDetails) { listOf( - Type.Remove.buildAction { - val index = playQueueFromWhichToDelete.indexOf(item) - playQueueFromWhichToDelete.remove(index) + Type.ShowDetails.buildAction { context -> + // playQueue is null since we don't want any queue change + NavigationHelper.openVideoDetail( + context, + item.serviceId, + item.url, + item.title, + null, + false + ) } ) + } else { + listOf() + } + + listOf( + Type.Remove.buildAction { + val index = playQueueFromWhichToDelete.indexOf(item) + playQueueFromWhichToDelete.remove(index) + } + ) } @JvmStatic fun fromStreamStatisticsEntry( item: StreamStatisticsEntry, - queueFromHere: (() -> PlayQueue)?, + queueFromHere: (() -> PlayQueue)? ): List { return fromStreamEntity(item.streamEntity, queueFromHere) + listOf( @@ -304,7 +312,7 @@ data class LongPressAction( queueFromHere: (() -> PlayQueue)?, // TODO possibly embed these two actions here onDelete: Runnable, - onSetAsPlaylistThumbnail: Runnable, + onSetAsPlaylistThumbnail: Runnable ): List { return fromStreamEntity(item.streamEntity, queueFromHere) + listOf( @@ -318,7 +326,7 @@ data class LongPressAction( item: PlaylistMetadataEntry, onRename: Runnable, onDelete: Runnable, - unsetPlaylistThumbnail: Runnable?, + unsetPlaylistThumbnail: Runnable? ): List { return listOf( Type.Rename.buildAction { onRename.run() }, @@ -332,7 +340,7 @@ data class LongPressAction( @JvmStatic fun fromPlaylistRemoteEntity( item: PlaylistRemoteEntity, - onDelete: Runnable, + onDelete: Runnable ): List { return buildPlayerActionList { PlaylistPlayQueue(item.serviceId, item.url) } + buildShareActionList( @@ -341,14 +349,14 @@ data class LongPressAction( item.thumbnailUrl ) + listOf( - Type.Delete.buildAction { onDelete.run() }, + Type.Delete.buildAction { onDelete.run() } ) } @JvmStatic fun fromChannelInfoItem( item: ChannelInfoItem, - onUnsubscribe: Runnable?, + onUnsubscribe: Runnable? ): List { return buildPlayerActionList { ChannelTabPlayQueue(item.serviceId, item.url) } + buildShareActionList(item) + @@ -358,7 +366,7 @@ data class LongPressAction( context.findFragmentActivity().supportFragmentManager, item.serviceId, item.url, - item.name, + item.name ) }, onUnsubscribe?.let { r -> Type.Unsubscribe.buildAction { r.run() } } diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenu.kt b/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenu.kt index f92027c39..74a7cb4d6 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenu.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenu.kt @@ -79,6 +79,7 @@ import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import androidx.lifecycle.viewmodel.compose.viewModel import coil3.compose.AsyncImage +import java.time.OffsetDateTime import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -97,12 +98,11 @@ import org.schabi.newpipe.util.Either import org.schabi.newpipe.util.Localization import org.schabi.newpipe.util.text.FixedHeightCenteredText import org.schabi.newpipe.util.text.fadedMarquee -import java.time.OffsetDateTime fun openLongPressMenuInActivity( activity: Activity, longPressable: LongPressable, - longPressActions: List, + longPressActions: List ) { activity.addContentView( getLongPressMenuView(activity, longPressable, longPressActions), @@ -113,7 +113,7 @@ fun openLongPressMenuInActivity( fun getLongPressMenuView( context: Context, longPressable: LongPressable, - longPressActions: List, + longPressActions: List ): ComposeView { return ComposeView(context).apply { setContent { @@ -121,7 +121,7 @@ fun getLongPressMenuView( LongPressMenu( longPressable = longPressable, longPressActions = longPressActions, - onDismissRequest = { (this.parent as ViewGroup).removeView(this) }, + onDismissRequest = { (this.parent as ViewGroup).removeView(this) } ) } } @@ -135,7 +135,7 @@ internal val ThumbnailHeight = 60.dp fun LongPressMenu( longPressable: LongPressable, longPressActions: List, - onDismissRequest: () -> Unit, + onDismissRequest: () -> Unit ) { val viewModel: LongPressMenuViewModel = viewModel() val isHeaderEnabled by viewModel.isHeaderEnabled.collectAsState() @@ -152,7 +152,7 @@ fun LongPressMenu( ) { ScaffoldWithToolbar( title = stringResource(R.string.long_press_menu_actions_editor), - onBackClick = { showEditor = false }, + onBackClick = { showEditor = false } ) { paddingValues -> LongPressMenuEditor(modifier = Modifier.padding(paddingValues)) } @@ -179,7 +179,8 @@ fun LongPressMenu( action.action(ctx) } catch (t: Throwable) { ErrorUtil.showSnackbar( - ctx, ErrorInfo(t, LONG_PRESS_MENU_ACTION, "Running action ${action.type}") + ctx, + ErrorInfo(t, LONG_PRESS_MENU_ACTION, "Running action ${action.type}") ) } onDismissRequest() @@ -199,14 +200,14 @@ fun LongPressMenu( ModalBottomSheet( sheetState = sheetState, onDismissRequest = onDismissRequest, - dragHandle = { LongPressMenuDragHandle(onEditActions = { showEditor = true }) }, + dragHandle = { LongPressMenuDragHandle(onEditActions = { showEditor = true }) } ) { Box(modifier = Modifier.discardAllTouchesIf(isLoading)) { LongPressMenuContent( header = longPressable.takeIf { isHeaderEnabled }, onUploaderClick = onUploaderClick, actions = enabledLongPressActions, - runActionAndDismiss = ::runActionAndDismiss, + runActionAndDismiss = ::runActionAndDismiss ) // importing makes the ColumnScope overload be resolved, so we use qualified path... androidx.compose.animation.AnimatedVisibility( @@ -215,7 +216,7 @@ fun LongPressMenu( exit = fadeOut(), modifier = Modifier .matchParentSize() - .background(MaterialTheme.colorScheme.surfaceContainerLow), + .background(MaterialTheme.colorScheme.surfaceContainerLow) ) { Box(contentAlignment = Alignment.Center) { CircularProgressIndicator() @@ -231,7 +232,7 @@ private fun LongPressMenuContent( header: LongPressable?, onUploaderClick: (() -> Unit)?, actions: List, - runActionAndDismiss: (LongPressAction) -> Unit, + runActionAndDismiss: (LongPressAction) -> Unit ) { BoxWithConstraints( modifier = Modifier @@ -251,7 +252,7 @@ private fun LongPressMenuContent( while (actionIndex < actions.size) { Row( verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth(), + modifier = Modifier.fillMaxWidth() ) { var rowIndex = 0 while (rowIndex < buttonsPerRow) { @@ -263,7 +264,7 @@ private fun LongPressMenuContent( modifier = Modifier .height(buttonHeight) .fillMaxWidth() - .weight((buttonsPerRow - rowIndex).toFloat()), + .weight((buttonsPerRow - rowIndex).toFloat()) ) break } else if (actionIndex >= 0) { @@ -276,7 +277,7 @@ private fun LongPressMenuContent( modifier = Modifier .height(buttonHeight) .fillMaxWidth() - .weight(1F), + .weight(1F) ) rowIndex += 1 } else if (maxHeaderWidthInButtonsFullSpan >= buttonsPerRow) { @@ -290,7 +291,7 @@ private fun LongPressMenuContent( // leave the height as small as possible, since it's the // only item on the row anyway .fillMaxWidth() - .weight(maxHeaderWidthInButtonsFullSpan.toFloat()), + .weight(maxHeaderWidthInButtonsFullSpan.toFloat()) ) rowIndex += maxHeaderWidthInButtonsFullSpan } else { @@ -306,7 +307,7 @@ private fun LongPressMenuContent( .padding(start = 8.dp, top = 11.dp, bottom = 11.dp) .heightIn(min = ThumbnailHeight) .fillMaxWidth() - .weight(headerWidthInButtonsReducedSpan.toFloat()), + .weight(headerWidthInButtonsReducedSpan.toFloat()) ) rowIndex += headerWidthInButtonsReducedSpan } @@ -357,7 +358,7 @@ fun LongPressMenuDragHandle(onEditActions: () -> Unit) { tint = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier .padding(2.dp) - .size(16.dp), + .size(16.dp) ) } } @@ -378,7 +379,7 @@ private fun LongPressMenuDragHandlePreview() { fun LongPressMenuHeader( item: LongPressable, onUploaderClick: (() -> Unit)?, - modifier: Modifier = Modifier, + modifier: Modifier = Modifier ) { val ctx = LocalContext.current @@ -386,7 +387,7 @@ fun LongPressMenuHeader( color = MaterialTheme.colorScheme.surfaceContainer, contentColor = MaterialTheme.colorScheme.onSurfaceVariant, shape = MaterialTheme.shapes.large, - modifier = modifier, + modifier = modifier ) { Row(verticalAlignment = Alignment.CenterVertically) { Box { @@ -413,12 +414,12 @@ fun LongPressMenuHeader( modifier = Modifier .align(Alignment.BottomEnd) .padding(4.dp) - .clip(MaterialTheme.shapes.medium), + .clip(MaterialTheme.shapes.medium) ) { Text( text = Localization.getDurationString(decoration.duration), style = MaterialTheme.typography.bodySmall, - modifier = Modifier.padding(vertical = 2.dp, horizontal = 4.dp), + modifier = Modifier.padding(vertical = 2.dp, horizontal = 4.dp) ) } } @@ -433,7 +434,7 @@ fun LongPressMenuHeader( modifier = Modifier .align(Alignment.BottomEnd) .padding(4.dp) - .clip(MaterialTheme.shapes.medium), + .clip(MaterialTheme.shapes.medium) ) { Text( text = stringResource(R.string.duration_live).uppercase(), @@ -451,16 +452,16 @@ fun LongPressMenuHeader( modifier = Modifier .align(Alignment.TopEnd) .size(width = 40.dp, height = ThumbnailHeight) - .clip(MaterialTheme.shapes.large), + .clip(MaterialTheme.shapes.large) ) { Column( verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier.fillMaxWidth(), + modifier = Modifier.fillMaxWidth() ) { Icon( Icons.AutoMirrored.Default.PlaylistPlay, - contentDescription = null, + contentDescription = null ) Text( text = Localization.localizeStreamCountMini( @@ -468,7 +469,7 @@ fun LongPressMenuHeader( decoration.itemCount ), style = MaterialTheme.typography.labelMedium, - maxLines = 1, + maxLines = 1 ) } } @@ -479,7 +480,7 @@ fun LongPressMenuHeader( } Column( - modifier = Modifier.padding(vertical = 8.dp), + modifier = Modifier.padding(vertical = 8.dp) ) { Text( text = item.title, @@ -487,14 +488,14 @@ fun LongPressMenuHeader( maxLines = 1, modifier = Modifier .fillMaxWidth() - .fadedMarquee(edgeWidth = 12.dp), + .fadedMarquee(edgeWidth = 12.dp) ) val subtitle = getSubtitleAnnotatedString( item = item, showLink = onUploaderClick != null, linkColor = MaterialTheme.customColors.onSurfaceVariantLink, - ctx = ctx, + ctx = ctx ) if (subtitle.isNotBlank()) { Spacer(Modifier.height(1.dp)) @@ -509,7 +510,7 @@ fun LongPressMenuHeader( Modifier.clickable(onClick = onUploaderClick) } .fillMaxWidth() - .fadedMarquee(edgeWidth = 12.dp), + .fadedMarquee(edgeWidth = 12.dp) ) } } @@ -521,7 +522,7 @@ fun getSubtitleAnnotatedString( item: LongPressable, showLink: Boolean, linkColor: Color, - ctx: Context, + ctx: Context ) = buildAnnotatedString { var shouldAddSeparator = false if (showLink) { @@ -574,13 +575,13 @@ fun getSubtitleInlineContent() = mapOf( placeholder = Placeholder( width = MaterialTheme.typography.bodyMedium.fontSize, height = MaterialTheme.typography.bodyMedium.fontSize, - placeholderVerticalAlign = PlaceholderVerticalAlign.Center, + placeholderVerticalAlign = PlaceholderVerticalAlign.Center ) ) { Icon( imageVector = Icons.AutoMirrored.Filled.OpenInNew, contentDescription = null, - tint = MaterialTheme.customColors.onSurfaceVariantLink, + tint = MaterialTheme.customColors.onSurfaceVariantLink ) } ) @@ -591,7 +592,7 @@ fun LongPressMenuButton( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, - enabled: Boolean = true, + enabled: Boolean = true ) { // TODO possibly make it so that when you long-press on the button, the label appears on-screen // as a small popup, so in case the label text is cut off the users can still read it in full @@ -601,18 +602,18 @@ fun LongPressMenuButton( shape = MaterialTheme.shapes.large, contentPadding = PaddingValues(start = 3.dp, top = 8.dp, end = 3.dp, bottom = 2.dp), border = null, - modifier = modifier, + modifier = modifier ) { Column(horizontalAlignment = Alignment.CenterHorizontally) { Icon( imageVector = icon, contentDescription = null, - modifier = Modifier.size(32.dp), + modifier = Modifier.size(32.dp) ) FixedHeightCenteredText( text = text, lines = 2, - style = MaterialTheme.typography.bodySmall, + style = MaterialTheme.typography.bodySmall ) } } @@ -650,7 +651,7 @@ private class LongPressablePreviews : CollectionPreviewParameterProvider t.buildAction({ t != EnqueueNext }) { } }, - runActionAndDismiss = {}, + runActionAndDismiss = {} ) } } diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenuEditor.kt b/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenuEditor.kt index d705654a9..aa6026e7d 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenuEditor.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenuEditor.kt @@ -64,12 +64,12 @@ import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameter import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.toSize +import kotlin.math.floor import org.schabi.newpipe.R import org.schabi.newpipe.ktx.letIf import org.schabi.newpipe.ui.detectDragGestures import org.schabi.newpipe.ui.theme.AppTheme import org.schabi.newpipe.util.text.FixedHeightCenteredText -import kotlin.math.floor /** * When making changes to this composable and to [LongPressMenuEditorState], make sure to test the @@ -112,7 +112,7 @@ fun LongPressMenuEditor(modifier: Modifier = Modifier) { .detectDragGestures( beginDragGesture = state::beginDragGesture, handleDragGestureChange = state::handleDragGestureChange, - endDragGesture = state::completeDragGestureAndCleanUp, + endDragGesture = state::completeDragGestureAndCleanUp ) // `.focusTarget().onKeyEvent()` handles DPAD on Android TVs .focusTarget() @@ -120,12 +120,12 @@ fun LongPressMenuEditor(modifier: Modifier = Modifier) { // same width as the LongPressMenu columns = GridCells.Adaptive(MinButtonWidth), userScrollEnabled = false, - state = gridState, + state = gridState ) { itemsIndexed( state.items, key = { _, item -> item.stableUniqueKey() }, - span = { _, item -> GridItemSpan(item.columnSpan ?: maxLineSpan) }, + span = { _, item -> GridItemSpan(item.columnSpan ?: maxLineSpan) } ) { i, item -> ItemInListUi( item = item, @@ -151,7 +151,7 @@ fun LongPressMenuEditor(modifier: Modifier = Modifier) { .size(size) .offset { state.activeDragPosition } .offset(-size.width / 2, -size.height / 2) - .offset((-24).dp, (-24).dp), + .offset((-24).dp, (-24).dp) ) } } @@ -162,7 +162,7 @@ private fun Subheader( selected: Boolean, @StringRes title: Int, @StringRes description: Int, - modifier: Modifier = Modifier, + modifier: Modifier = Modifier ) { Column( modifier = modifier @@ -177,7 +177,7 @@ private fun Subheader( Text( text = stringResource(description), fontStyle = FontStyle.Italic, - style = MaterialTheme.typography.bodyMedium, + style = MaterialTheme.typography.bodyMedium ) } } @@ -190,7 +190,7 @@ private fun ActionOrHeaderBox( contentColor: Color, modifier: Modifier = Modifier, backgroundColor: Color = Color.Transparent, - horizontalPadding: Dp = 3.dp, + horizontalPadding: Dp = 3.dp ) { Surface( color = backgroundColor, @@ -199,19 +199,19 @@ private fun ActionOrHeaderBox( border = BorderStroke(2.dp, contentColor.copy(alpha = 1f)).takeIf { selected }, modifier = modifier.padding( horizontal = horizontalPadding, - vertical = 5.dp, - ), + vertical = 5.dp + ) ) { Column(horizontalAlignment = Alignment.CenterHorizontally) { Icon( imageVector = icon, contentDescription = null, - modifier = Modifier.size(32.dp), + modifier = Modifier.size(32.dp) ) FixedHeightCenteredText( text = stringResource(text), lines = 2, - style = MaterialTheme.typography.bodySmall, + style = MaterialTheme.typography.bodySmall ) } } @@ -221,7 +221,7 @@ private fun ActionOrHeaderBox( private fun ItemInListUi( item: ItemInList, selected: Boolean, - modifier: Modifier = Modifier, + modifier: Modifier = Modifier ) { when (item) { ItemInList.EnabledCaption -> { @@ -229,26 +229,29 @@ private fun ItemInListUi( modifier = modifier, selected = selected, title = R.string.long_press_menu_enabled_actions, - description = R.string.long_press_menu_enabled_actions_description, + description = R.string.long_press_menu_enabled_actions_description ) } + ItemInList.HiddenCaption -> { Subheader( modifier = modifier, selected = selected, title = R.string.long_press_menu_hidden_actions, - description = R.string.long_press_menu_hidden_actions_description, + description = R.string.long_press_menu_hidden_actions_description ) } + is ItemInList.Action -> { ActionOrHeaderBox( modifier = modifier, selected = selected, icon = item.type.icon, text = item.type.label, - contentColor = MaterialTheme.colorScheme.onSurface, + contentColor = MaterialTheme.colorScheme.onSurface ) } + ItemInList.HeaderBox -> { ActionOrHeaderBox( modifier = modifier, @@ -257,9 +260,10 @@ private fun ItemInListUi( text = R.string.long_press_menu_header, contentColor = MaterialTheme.colorScheme.onSurfaceVariant, backgroundColor = MaterialTheme.colorScheme.surfaceContainer, - horizontalPadding = 12.dp, + horizontalPadding = 12.dp ) } + ItemInList.NoneMarker -> { ActionOrHeaderBox( modifier = modifier, @@ -267,16 +271,17 @@ private fun ItemInListUi( icon = Icons.Default.Close, text = R.string.none, // 0.38f is the same alpha that the Material3 library applies for disabled buttons - contentColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f), + contentColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f) ) } + is ItemInList.DragMarker -> { ActionOrHeaderBox( modifier = modifier, selected = selected, icon = Icons.Default.DragHandle, text = R.string.detail_drag_description, - contentColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f), + contentColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f) ) } } diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenuEditorState.kt b/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenuEditorState.kt index f33f434c0..c1cf57a74 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenuEditorState.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressMenuEditorState.kt @@ -20,14 +20,14 @@ import androidx.compose.ui.input.key.key import androidx.compose.ui.input.key.type import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntSize +import kotlin.math.abs +import kotlin.math.max +import kotlin.math.min import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch -import kotlin.math.abs -import kotlin.math.max -import kotlin.math.min private const val TAG = "LongPressMenuEditorStat" @@ -43,7 +43,7 @@ private const val TAG = "LongPressMenuEditorStat" class LongPressMenuEditorState( context: Context, val gridState: LazyGridState, - val coroutineScope: CoroutineScope, + val coroutineScope: CoroutineScope ) { val items = run { // We get the current arrangement once and do not observe on purpose. @@ -99,10 +99,10 @@ class LongPressMenuEditorState( private fun autoScrollSpeedFromTouchPos( touchPos: IntOffset, maxSpeed: Float = 20f, - scrollIfCloseToBorderPercent: Float = 0.2f, + scrollIfCloseToBorderPercent: Float = 0.2f ): Float { val heightPosRatio = touchPos.y.toFloat() / - (gridState.layoutInfo.viewportEndOffset - gridState.layoutInfo.viewportStartOffset) + (gridState.layoutInfo.viewportEndOffset - gridState.layoutInfo.viewportStartOffset) // just a linear piecewise function, sets higher speeds the closer the finger is to the border return maxSpeed * max( // proportionally positive speed when close to the bottom border @@ -390,11 +390,12 @@ class LongPressMenuEditorState( sealed class ItemInList( val isDraggable: Boolean = false, val isCaption: Boolean = false, - open val columnSpan: Int? = 1, + // if null, then the item will occupy all of the line + open val columnSpan: Int? = 1 ) { // decoration items (i.e. text subheaders) - object EnabledCaption : ItemInList(isCaption = true, columnSpan = null /* i.e. all line */) - object HiddenCaption : ItemInList(isCaption = true, columnSpan = null /* i.e. all line */) + object EnabledCaption : ItemInList(isCaption = true, columnSpan = null) // i.e. span all line + object HiddenCaption : ItemInList(isCaption = true, columnSpan = null) // i.e. span all line // actual draggable actions (+ a header) object HeaderBox : ItemInList(isDraggable = true, columnSpan = 2) diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressable.kt b/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressable.kt index ebafa71b8..194cfdb9a 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressable.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/menu/LongPressable.kt @@ -1,6 +1,7 @@ package org.schabi.newpipe.ui.components.menu import androidx.compose.runtime.Stable +import java.time.OffsetDateTime import org.schabi.newpipe.database.playlist.PlaylistMetadataEntry import org.schabi.newpipe.database.playlist.model.PlaylistRemoteEntity import org.schabi.newpipe.database.stream.model.StreamEntity @@ -14,7 +15,6 @@ import org.schabi.newpipe.extractor.stream.StreamType.LIVE_STREAM import org.schabi.newpipe.player.playqueue.PlayQueueItem import org.schabi.newpipe.util.Either import org.schabi.newpipe.util.image.ImageStrategy -import java.time.OffsetDateTime @Stable data class LongPressable( @@ -26,7 +26,7 @@ data class LongPressable( val viewCount: Long?, val streamType: StreamType?, // only used to format the view count properly val uploadDate: Either?, - val decoration: Decoration?, + val decoration: Decoration? ) { sealed interface Decoration { data class Duration(val duration: Long) : Decoration @@ -34,12 +34,11 @@ data class LongPressable( data class Playlist(val itemCount: Long) : Decoration companion object { - internal fun from(streamType: StreamType, duration: Long) = - if (streamType == LIVE_STREAM || streamType == AUDIO_LIVE_STREAM) { - Live - } else { - duration.takeIf { it > 0 }?.let { Duration(it) } - } + internal fun from(streamType: StreamType, duration: Long) = if (streamType == LIVE_STREAM || streamType == AUDIO_LIVE_STREAM) { + Live + } else { + duration.takeIf { it > 0 }?.let { Duration(it) } + } } } @@ -55,7 +54,7 @@ data class LongPressable( streamType = item.streamType, uploadDate = item.uploadDate?.let { Either.right(it.offsetDateTime()) } ?: item.textualUploadDate?.let { Either.left(it) }, - decoration = Decoration.from(item.streamType, item.duration), + decoration = Decoration.from(item.streamType, item.duration) ) @JvmStatic @@ -69,7 +68,7 @@ data class LongPressable( streamType = item.streamType, uploadDate = item.uploadDate?.let { Either.right(it) } ?: item.textualUploadDate?.let { Either.left(it) }, - decoration = Decoration.from(item.streamType, item.duration), + decoration = Decoration.from(item.streamType, item.duration) ) @JvmStatic @@ -82,7 +81,7 @@ data class LongPressable( viewCount = null, streamType = item.streamType, uploadDate = null, - decoration = Decoration.from(item.streamType, item.duration), + decoration = Decoration.from(item.streamType, item.duration) ) @JvmStatic @@ -96,7 +95,7 @@ data class LongPressable( viewCount = null, streamType = null, uploadDate = null, - decoration = Decoration.Playlist(item.streamCount), + decoration = Decoration.Playlist(item.streamCount) ) @JvmStatic @@ -111,7 +110,7 @@ data class LongPressable( uploadDate = null, decoration = Decoration.Playlist( item.streamCount ?: ListExtractor.ITEM_COUNT_UNKNOWN - ), + ) ) @JvmStatic @@ -124,7 +123,7 @@ data class LongPressable( viewCount = null, streamType = null, uploadDate = null, - decoration = null, + decoration = null ) @JvmStatic @@ -137,7 +136,7 @@ data class LongPressable( viewCount = null, streamType = null, uploadDate = null, - decoration = Decoration.Playlist(item.streamCount), + decoration = Decoration.Playlist(item.streamCount) ) } } diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/menu/SparseItemUtil.kt b/app/src/main/java/org/schabi/newpipe/ui/components/menu/SparseItemUtil.kt index 33f03ad5c..e10a0e9a9 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/menu/SparseItemUtil.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/menu/SparseItemUtil.kt @@ -33,7 +33,7 @@ import org.schabi.newpipe.util.StreamTypeUtil @MainThread suspend fun fetchItemInfoIfSparse( context: Context, - item: StreamInfoItem, + item: StreamInfoItem ): SinglePlayQueue { if ((StreamTypeUtil.isLiveStream(item.streamType) || item.duration >= 0) && !Utils.isNullOrEmpty(item.uploaderUrl) @@ -66,7 +66,7 @@ suspend fun fetchUploaderUrlIfSparse( context: Context, serviceId: Int, url: String, - uploaderUrl: String?, + uploaderUrl: String? ): String? { if (!uploaderUrl.isNullOrEmpty()) { return uploaderUrl @@ -89,7 +89,7 @@ suspend fun fetchUploaderUrlIfSparse( suspend fun fetchStreamInfoAndSaveToDatabase( context: Context, serviceId: Int, - url: String, + url: String ): StreamInfo { Toast.makeText(context, R.string.loading_stream_details, Toast.LENGTH_SHORT).show() diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/BackgroundFromHere.kt b/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/BackgroundFromHere.kt index 573aa445c..9c3e2ce91 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/BackgroundFromHere.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/BackgroundFromHere.kt @@ -146,6 +146,6 @@ private fun BackgroundFromHerePreview() { Icon( imageVector = Icons.Filled.BackgroundFromHere, contentDescription = null, - modifier = Modifier.size(240.dp), + modifier = Modifier.size(240.dp) ) } diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/PlayFromHere.kt b/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/PlayFromHere.kt index 0af14bbe3..f736b40dc 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/PlayFromHere.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/PlayFromHere.kt @@ -122,6 +122,6 @@ private fun PlayFromHerePreview() { Icon( imageVector = Icons.Filled.PlayFromHere, contentDescription = null, - modifier = Modifier.size(240.dp), + modifier = Modifier.size(240.dp) ) } diff --git a/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/PopupFromHere.kt b/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/PopupFromHere.kt index b33648a96..f456b48d0 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/PopupFromHere.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/components/menu/icons/PopupFromHere.kt @@ -158,6 +158,6 @@ private fun PopupFromHerePreview() { Icon( imageVector = Icons.Filled.PopupFromHere, contentDescription = null, - modifier = Modifier.size(240.dp), + modifier = Modifier.size(240.dp) ) } diff --git a/app/src/main/java/org/schabi/newpipe/ui/theme/CustomColors.kt b/app/src/main/java/org/schabi/newpipe/ui/theme/CustomColors.kt index aac91ee04..832d71fc6 100644 --- a/app/src/main/java/org/schabi/newpipe/ui/theme/CustomColors.kt +++ b/app/src/main/java/org/schabi/newpipe/ui/theme/CustomColors.kt @@ -9,7 +9,7 @@ import androidx.compose.ui.graphics.Color @Immutable data class CustomColors( - val onSurfaceVariantLink: Color = Color.Unspecified, + val onSurfaceVariantLink: Color = Color.Unspecified ) val onSurfaceVariantLinkLight = Color(0xFF5060B0) diff --git a/app/src/main/java/org/schabi/newpipe/util/Either.kt b/app/src/main/java/org/schabi/newpipe/util/Either.kt index 9d1f8f0f2..e5b2b9451 100644 --- a/app/src/main/java/org/schabi/newpipe/util/Either.kt +++ b/app/src/main/java/org/schabi/newpipe/util/Either.kt @@ -9,7 +9,7 @@ import kotlin.reflect.safeCast data class Either( val value: Any, val classA: KClass, - val classB: KClass, + val classB: KClass ) { inline fun match(ifLeft: (A) -> R, ifRight: (B) -> R): R { return classA.safeCast(value)?.let { ifLeft(it) } @@ -17,9 +17,7 @@ data class Either( } companion object { - inline fun left(a: A): Either = - Either(a, A::class, B::class) - inline fun right(b: B): Either = - Either(b, A::class, B::class) + inline fun left(a: A): Either = Either(a, A::class, B::class) + inline fun right(b: B): Either = Either(b, A::class, B::class) } } diff --git a/app/src/main/java/org/schabi/newpipe/util/text/FixedHeightCenteredText.kt b/app/src/main/java/org/schabi/newpipe/util/text/FixedHeightCenteredText.kt index 57de24269..18ca425e6 100644 --- a/app/src/main/java/org/schabi/newpipe/util/text/FixedHeightCenteredText.kt +++ b/app/src/main/java/org/schabi/newpipe/util/text/FixedHeightCenteredText.kt @@ -18,7 +18,7 @@ fun FixedHeightCenteredText( text: String, lines: Int, modifier: Modifier = Modifier, - style: TextStyle = LocalTextStyle.current, + style: TextStyle = LocalTextStyle.current ) { Box(modifier = modifier) { // this allows making the box always the same height (i.e. the height of [lines] text @@ -26,7 +26,7 @@ fun FixedHeightCenteredText( Text( text = "", style = style, - minLines = lines, + minLines = lines ) Text( text = text,