Skip to content

Commit

Permalink
Update remote controls (#910)
Browse files Browse the repository at this point in the history
**Background**

This PR introduces update for remote controls with UI improvements and
deeplink integration for local-flipper files

**Changes**

- Animated icons when emulating
- Fix bottom navigation paddings
- Save .ui.json file on flipper
- Fix save api paths usage
- Add Raw DeeplinkContent

**Test plan**

- Enable remote controls in debug options
- Open infrareds list screen
- Press add remote
- Select some brand and complete configuration for some device
- See grid screen, tap button and look at beautiful animation
  • Loading branch information
makeevrserg authored Aug 7, 2024
1 parent 6e79769 commit ff55dcd
Show file tree
Hide file tree
Showing 57 changed files with 709 additions and 379 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Attention: don't forget to add the flag for F-Droid before release
- [Feature] Infrared controls
- [Feature] Remove bond on retry pair
- [Feature] Add onetap widget
- [Refactor] Load RemoteControls from flipper, emulating animation
- [Refactor] Update to Kotlin 2.0
- [Refactor] Replace Ktorfit with Ktor requests in remote-controls
- [Refactor] Migrate :core:preference to KMP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.net.Uri
import android.os.Parcelable
import com.flipperdevices.bridge.dao.api.model.FlipperFileFormat
import com.flipperdevices.bridge.dao.api.model.FlipperKeyCrypto
import com.flipperdevices.core.ktx.jre.length
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
Expand Down Expand Up @@ -81,6 +82,7 @@ sealed class DeeplinkContent : Parcelable {
uri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
)

is InternalStorageFile -> file.delete()
is FFFContent -> {} // Nothing
is FFFCryptoContent -> {} // Nothing
Expand Down
2 changes: 0 additions & 2 deletions components/remote-controls/brands/api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ plugins {
android.namespace = "com.flipperdevices.remotecontrols.brands.api"

dependencies {
implementation(projects.components.deeplink.api)

implementation(projects.components.core.ui.decompose)

implementation(libs.compose.ui)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ abstract class BrandsScreenDecomposeComponent(
) : ScreenDecomposeComponent(componentContext) {

fun interface Factory {
fun createBrandsComponent(
operator fun invoke(
componentContext: ComponentContext,
categoryId: Long,
onBackClick: () -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
Expand Down Expand Up @@ -68,5 +69,6 @@ fun BrandsList(
)
}
}
item { Spacer(Modifier.navigationBarsPadding()) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.detectVerticalDragGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -93,5 +95,6 @@ internal fun <T> HeadersComposable(
}
)
}
Spacer(Modifier.navigationBarsPadding())
}
}
2 changes: 0 additions & 2 deletions components/remote-controls/categories/api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ plugins {
android.namespace = "com.flipperdevices.remotecontrols.categories.api"

dependencies {
implementation(projects.components.deeplink.api)

implementation(projects.components.core.ui.decompose)

implementation(libs.compose.ui)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ abstract class CategoriesScreenDecomposeComponent(
) : ScreenDecomposeComponent(componentContext) {

fun interface Factory {
fun invoke(
operator fun invoke(
componentContext: ComponentContext,
onBackClick: () -> Unit,
onCategoryClick: (categoryId: Long) -> Unit
Expand Down
2 changes: 2 additions & 0 deletions components/remote-controls/core-ui/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ dependencies {
// Compose
implementation(libs.compose.ui)
implementation(libs.compose.foundation)
implementation(libs.compose.tooling)
implementation(libs.compose.material)
implementation(libs.compose.material.icons.core)
implementation(libs.compose.material.icons.extended)
implementation(libs.compose.placeholder)

implementation(libs.bundles.decompose)
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ fun rememberImageBitmap(base64Image: String): ImageBitmap? {
@Composable
fun Base64ImageButton(
base64Icon: String,
isEmulating: Boolean,
modifier: Modifier = Modifier,
isEmulating: Boolean = false,
onClick: () -> Unit
) {
val imageBitmap = rememberImageBitmap(base64Icon)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import com.flipperdevices.ifrmvp.model.buttondata.TextButtonData
import com.flipperdevices.ifrmvp.model.buttondata.UnknownButtonData
import com.flipperdevices.ifrmvp.model.buttondata.VolumeButtonData

@Suppress("LongMethod")
@Composable
fun ButtonItemComposable(
buttonData: ButtonData,
emulatedKeyIdentifier: IfrKeyIdentifier?,
onKeyDataClick: (IfrKeyIdentifier) -> Unit,
modifier: Modifier = Modifier
) {
Expand All @@ -26,6 +28,7 @@ fun ButtonItemComposable(
SquareIconButton(
iconType = buttonData.iconId,
modifier = modifier,
isEmulating = emulatedKeyIdentifier == buttonData.keyIdentifier,
onClick = { onKeyDataClick.invoke(buttonData.keyIdentifier) }
)
}
Expand All @@ -35,6 +38,8 @@ fun ButtonItemComposable(
onNextClick = { onKeyDataClick.invoke(buttonData.addKeyIdentifier) },
onPrevClick = { onKeyDataClick.invoke(buttonData.reduceKeyIdentifier) },
modifier = modifier,
isEmulating = buttonData.reduceKeyIdentifier == emulatedKeyIdentifier ||
buttonData.addKeyIdentifier == emulatedKeyIdentifier
)
}

Expand All @@ -43,6 +48,8 @@ fun ButtonItemComposable(
onAddClick = { onKeyDataClick.invoke(buttonData.addKeyIdentifier) },
onReduceClick = { onKeyDataClick.invoke(buttonData.reduceKeyIdentifier) },
modifier = modifier,
isEmulating = buttonData.reduceKeyIdentifier == emulatedKeyIdentifier ||
buttonData.addKeyIdentifier == emulatedKeyIdentifier
)
}

Expand All @@ -62,6 +69,7 @@ fun ButtonItemComposable(
onClick = { onKeyDataClick.invoke(buttonData.keyIdentifier) },
text = buttonData.text,
background = LocalPalletV2.current.surface.menu.body.dufault,
isEmulating = emulatedKeyIdentifier == buttonData.keyIdentifier,
modifier = modifier,
)
}
Expand All @@ -71,6 +79,7 @@ fun ButtonItemComposable(
base64Icon = buttonData.pngBase64,
onClick = { onKeyDataClick.invoke(buttonData.keyIdentifier) },
modifier = modifier,
isEmulating = emulatedKeyIdentifier == buttonData.keyIdentifier,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ fun DoubleButton(
onLastClick: () -> Unit,
firstText: String,
lastText: String,
isEmulating: Boolean,
modifier: Modifier = Modifier,
text: String? = null,
) {
Expand All @@ -32,18 +33,21 @@ fun DoubleButton(
onClick = onFirstClick,
text = firstText,
background = LocalPalletV2.current.surface.menu.body.dufault,
isEmulating = isEmulating,
)
text?.let {
TextButton(
onClick = null,
text = text,
background = LocalPalletV2.current.surface.menu.body.dufault
background = LocalPalletV2.current.surface.menu.body.dufault,
isEmulating = isEmulating
)
}
TextButton(
onClick = onLastClick,
text = lastText,
background = LocalPalletV2.current.surface.menu.body.dufault,
isEmulating = isEmulating
)
}
}
Expand All @@ -52,6 +56,7 @@ fun DoubleButton(
fun VolumeButton(
onAddClick: () -> Unit,
onReduceClick: () -> Unit,
isEmulating: Boolean,
modifier: Modifier = Modifier
) {
DoubleButton(
Expand All @@ -60,14 +65,16 @@ fun VolumeButton(
text = "VOL",
firstText = "+",
lastText = "-",
modifier = modifier
modifier = modifier,
isEmulating = isEmulating
)
}

@Composable
fun ChannelButton(
onNextClick: () -> Unit,
onPrevClick: () -> Unit,
isEmulating: Boolean,
modifier: Modifier = Modifier,
) {
DoubleButton(
Expand All @@ -76,6 +83,7 @@ fun ChannelButton(
text = "CH",
firstText = "+",
lastText = "-",
modifier = modifier
modifier = modifier,
isEmulating = isEmulating
)
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
package com.flipperdevices.ifrmvp.core.ui.button.core

import androidx.compose.animation.Crossfade
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import com.flipperdevices.core.ui.ktx.placeholderConnecting
import com.flipperdevices.ifrmvp.core.ui.layout.core.sf
import com.flipperdevices.ifrmvp.core.ui.util.GridConstants

@Composable
fun SquareButton(
onClick: (() -> Unit)?,
background: Color,
isEmulating: Boolean,
modifier: Modifier = Modifier,
isEmulating: Boolean = false,
content: @Composable BoxScope.() -> Unit,
) {
Box(
Expand All @@ -38,6 +41,17 @@ fun SquareButton(
}
),
contentAlignment = Alignment.Center,
content = content
content = {
content.invoke(this)
Crossfade(isEmulating) { isEmulating ->
if (isEmulating) {
Box(
Modifier
.fillMaxSize()
.placeholderConnecting()
)
}
}
}
)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.flipperdevices.ifrmvp.core.ui.button.core

import android.content.res.Configuration.UI_MODE_NIGHT_YES
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Icon
Expand All @@ -8,6 +9,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.tooling.preview.Preview
import com.flipperdevices.core.ui.theme.FlipperThemeInternal
import com.flipperdevices.core.ui.theme.LocalPalletV2
import com.flipperdevices.ifrmvp.core.ui.ext.asPainter
import com.flipperdevices.ifrmvp.core.ui.ext.tintFor
Expand All @@ -34,7 +37,9 @@ fun SquareIconButton(
painter = painter,
contentDescription = contentDescription,
tint = iconTint,
modifier = Modifier.fillMaxSize().padding(12.sf)
modifier = Modifier
.fillMaxSize()
.padding(12.sf)
)
}
}
Expand All @@ -59,28 +64,46 @@ fun SquareImageButton(
bitmap = bitmap,
contentDescription = contentDescription,
tint = iconTint,
modifier = Modifier.fillMaxSize().padding(12.sf)
modifier = Modifier
.fillMaxSize()
.padding(12.sf)
)
}
}

@Composable
fun SquareIconButton(
iconType: IconButtonData.IconType,
isEmulating: Boolean,
modifier: Modifier = Modifier,
contentDescription: String? = null,
onClick: () -> Unit,
) {
SquareButton(
modifier = modifier,
onClick = onClick,
isEmulating = isEmulating,
background = LocalPalletV2.current.surface.menu.body.dufault
) {
Icon(
painter = iconType.asPainter(),
contentDescription = contentDescription,
tint = iconType.tintFor(),
modifier = Modifier.fillMaxSize().padding(12.sf)
modifier = Modifier
.fillMaxSize()
.padding(12.sf)
)
}
}

@Preview(uiMode = UI_MODE_NIGHT_YES)
@Composable
private fun SquareIconButtonPreview() {
FlipperThemeInternal {
SquareIconButton(
iconType = IconButtonData.IconType.POWER,
isEmulating = true,
onClick = {}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import com.flipperdevices.ifrmvp.core.ui.layout.core.sfp
@Composable
fun TextButton(
text: String,
isEmulating: Boolean,
modifier: Modifier = Modifier,
background: Color = MaterialTheme.colors.primaryVariant,
textColor: Color = MaterialTheme.colors.onPrimary,
isEmulating: Boolean = false,
onClick: (() -> Unit)?
) {
SquareButton(
Expand Down
Loading

0 comments on commit ff55dcd

Please sign in to comment.