Skip to content

Commit

Permalink
Infrared Editor (#701)
Browse files Browse the repository at this point in the history
**Background**

Now we can delete and reorder remotes in infrared key

**Changes**

* Infrared Parser (to State and to Key) + Test
* UI with states
* Save/Cancel changes

**Test plan**

Try reorder and delete remote
  • Loading branch information
Programistich authored Sep 21, 2023
1 parent 13d66e2 commit fccf0a6
Show file tree
Hide file tree
Showing 29 changed files with 1,071 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# 1.6.5 - In progress

- [Feature] Infrared Editor
- [Feature] Scroll on Infrared Screen
- [Feature] Redesign for FapHub
- [Feature] Check Self Update App in Options (only for github)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ enum class FeatureScreenRootRoute {
UPDATER,
KEY_RECEIVE,
SHAKE2REPORT,
INFRARED
INFRARED,
INFRARED_EDITOR
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ data class FlipperPallet(
val tabSwitchBackgroundColor: Color = Color(0xFFFFFFFF).copy(alpha = 0.5f)

val accentShareSheetStatusBarColor = Color(0xFFD96F00)

val infraredEditorDrag = Color(0xFFFFFFFF).copy(alpha = 0.5f)
val infraredEditorKeyName = Color(0xFFFFFFFF)
}

internal fun FlipperPallet.toMaterialColors(isLight: Boolean) = Colors(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ data class FlipperTypography(
fontFamily = FontFamily(Font(R.font.flipper)),
fontWeight = FontWeight.W500
),
val infraredEditButton: TextStyle = TextStyle(
fontSize = 32.sp,
fontFamily = FontFamily(Font(R.font.flipper)),
fontWeight = FontWeight.W400
),
)

fun getTypography(): FlipperTypography {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.flipperdevices.infrared.api

import com.flipperdevices.bridge.dao.api.model.FlipperKeyPath
import com.flipperdevices.core.ui.navigation.ComposableFeatureEntry
import com.flipperdevices.core.ui.navigation.FeatureScreenRootRoute

interface InfraredEditorFeatureEntry : ComposableFeatureEntry {
override val ROUTE: FeatureScreenRootRoute
get() = FeatureScreenRootRoute.INFRARED_EDITOR

fun getInfraredEditorScreen(keyPath: FlipperKeyPath): String
}
1 change: 1 addition & 0 deletions components/infrared/editor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
54 changes: 54 additions & 0 deletions components/infrared/editor/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
plugins {
id("flipper.android-compose")
id("flipper.anvil")
}

android.namespace = "com.flipperdevices.infrared.editor"

dependencies {
implementation(projects.components.infrared.api)
implementation(projects.components.keyscreen.api)
implementation(projects.components.keyscreen.shared)
implementation(projects.components.keyemulate.api)
implementation(projects.components.keyparser.api)
implementation(projects.components.keyedit.api)
implementation(projects.components.share.api)

implementation(projects.components.bridge.dao.api)
implementation(projects.components.bridge.synchronization.api)

implementation(projects.components.core.di)
implementation(projects.components.core.ui.navigation)
implementation(projects.components.core.ui.theme)
implementation(projects.components.core.ui.tabswitch)
implementation(projects.components.core.ui.ktx)
implementation(projects.components.core.ui.res)
implementation(projects.components.core.ui.dialog)

// Compose
implementation(libs.compose.ui)
implementation(libs.compose.tooling)
implementation(libs.compose.foundation)
implementation(libs.compose.material)
implementation(libs.compose.navigation)
implementation(libs.compose.drag.drop)

// ViewModel
implementation(libs.lifecycle.compose)
implementation(libs.lifecycle.viewmodel.ktx)
implementation(libs.tangle.viewmodel.compose)
implementation(libs.tangle.viewmodel.api)
anvil(libs.tangle.viewmodel.compiler)

implementation(libs.kotlin.serialization.json)
implementation(libs.kotlin.immutable.collections)

// Testing
testImplementation(projects.components.core.test)
testImplementation(libs.junit)
testImplementation(libs.mockk)
testImplementation(libs.ktx.testing)
testImplementation(libs.roboelectric)
testImplementation(libs.lifecycle.test)
testImplementation(libs.kotlin.coroutines.test)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.flipperdevices.infrared.editor.api

import android.net.Uri
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
import com.flipperdevices.bridge.dao.api.model.FlipperKeyPath
import com.flipperdevices.bridge.dao.api.model.navigation.FlipperKeyPathType
import com.flipperdevices.core.di.AppGraph
import com.flipperdevices.core.ui.navigation.ComposableFeatureEntry
import com.flipperdevices.infrared.api.InfraredEditorFeatureEntry
import com.flipperdevices.infrared.editor.compose.screen.ComposableInfraredEditorScreen
import com.squareup.anvil.annotations.ContributesBinding
import com.squareup.anvil.annotations.ContributesMultibinding
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import javax.inject.Inject

internal const val EXTRA_KEY_PATH = "flipper_key_path"

@ContributesBinding(AppGraph::class, InfraredEditorFeatureEntry::class)
@ContributesMultibinding(AppGraph::class, ComposableFeatureEntry::class)
class InfraredFeatureEntryImpl @Inject constructor() : InfraredEditorFeatureEntry {

override fun getInfraredEditorScreen(keyPath: FlipperKeyPath): String {
return "@${ROUTE.name}?infrared_editor_key_path=${Uri.encode(Json.encodeToString(keyPath))}"
}

private val navArguments = listOf(
navArgument(EXTRA_KEY_PATH) {
nullable = false
type = FlipperKeyPathType()
}
)

override fun NavGraphBuilder.composable(navController: NavHostController) {
composable(
route = "@${ROUTE.name}?infrared_editor_key_path={$EXTRA_KEY_PATH}",
arguments = navArguments
) {
ComposableInfraredEditorScreen(
onBack = navController::popBackStack
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.flipperdevices.infrared.editor.compose

import android.content.res.Configuration
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.tooling.preview.Preview
import com.flipperdevices.core.ui.dialog.composable.multichoice.FlipperMultiChoiceDialog
import com.flipperdevices.core.ui.dialog.composable.multichoice.FlipperMultiChoiceDialogModel
import com.flipperdevices.core.ui.theme.FlipperThemeInternal
import com.flipperdevices.infrared.editor.R

@Composable
internal fun ComposableInfraredEditorDialog(
isShow: Boolean,
onSave: () -> Unit,
onDoNotSave: () -> Unit,
onDismissDialog: () -> Unit
) {
if (isShow.not()) {
return
}

val dialogModel = remember(onSave, onDoNotSave) {
FlipperMultiChoiceDialogModel.Builder()
.setTitle(R.string.infrared_editor_dialog_title)
.setDescription(R.string.infrared_editor_dialog_desc)
.setOnDismissRequest(onDismissDialog)
.addButton(R.string.infrared_editor_dialog_save, onSave, isActive = true)
.addButton(R.string.infrared_editor_dialog_do_not_save, onDoNotSave)
.build()
}

FlipperMultiChoiceDialog(model = dialogModel)
}

@Preview
@Composable
private fun PreviewComposableInfraredEditorDialogLight() {
FlipperThemeInternal {
ComposableInfraredEditorDialog(
isShow = true,
onSave = {},
onDoNotSave = {},
onDismissDialog = {}
)
}
}

@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun PreviewComposableInfraredEditorDialogDark() {
FlipperThemeInternal {
ComposableInfraredEditorDialog(
isShow = true,
onSave = {},
onDoNotSave = {},
onDismissDialog = {}
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.flipperdevices.infrared.editor.compose.components

import android.content.res.Configuration
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.flipperdevices.core.ui.theme.FlipperThemeInternal
import com.flipperdevices.core.ui.theme.LocalPallet
import com.flipperdevices.infrared.editor.R
import com.flipperdevices.keyscreen.shared.bar.ComposableBarSimpleText
import com.flipperdevices.keyscreen.shared.bar.ComposableBarTitleWithName
import com.flipperdevices.keyscreen.shared.bar.ComposableKeyScreenAppBar

@Composable
internal fun ComposableInfraredEditorAppBar(
keyName: String,
onCancel: () -> Unit,
onSave: () -> Unit
) {
ComposableKeyScreenAppBar(
startBlock = {
ComposableBarSimpleText(
modifier = it,
text = stringResource(id = R.string.infrared_editor_cancel),
onClick = onCancel,
color = LocalPallet.current.text100
)
},
centerBlock = {
ComposableBarTitleWithName(
modifier = it,
title = keyName,
name = null
)
},
endBlock = {
ComposableBarSimpleText(
modifier = it,
text = stringResource(id = R.string.infrared_editor_save),
onClick = onSave,
color = LocalPallet.current.accentSecond
)
}
)
}

@Composable
@Preview
private fun PreviewComposableInfraredEditorAppBarLight() {
FlipperThemeInternal {
ComposableInfraredEditorAppBar(
keyName = "Samsung TV",
onCancel = {},
onSave = {}
)
}
}

@Composable
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun PreviewComposableInfraredEditorAppBarDark() {
FlipperThemeInternal {
ComposableInfraredEditorAppBar(
keyName = "Samsung TV",
onCancel = {},
onSave = {}
)
}
}
Loading

0 comments on commit fccf0a6

Please sign in to comment.