Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Compose Previews for NFC, Onboarding & Companion Views #4239

Merged
merged 6 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.homeassistant.companion.android.common.R as commonR

Expand Down Expand Up @@ -148,3 +149,9 @@ fun NfcTriggerExample(
NfcCodeContainer(text = example)
}
}

@Preview(showSystemUi = true)
@Composable
fun NfcEditViewPreview() {
NfcEditView(identifier = "identifier", showDeviceSample = true, onDuplicateClicked = {}, onFireEventClicked = {})
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.homeassistant.companion.android.common.R as commonR

Expand Down Expand Up @@ -70,3 +71,10 @@ fun NfcWelcomeView(
}
}
}

@Preview(showSystemUi = true)
@Composable
fun NfcWelcomeViewPreview() {
NfcWelcomeView(isNfcEnabled = true, onReadClicked = { }, onWriteClicked = {
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.mikepenz.iconics.compose.Image
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
Expand Down Expand Up @@ -109,3 +110,15 @@ fun NfcWriteIdentifierDialog(
onSave = { onSubmit(inputValue.value) }
)
}

@Preview(showSystemUi = true)
@Composable
fun NfcWriteView_NfcDisabled_Preview() {
vieck marked this conversation as resolved.
Show resolved Hide resolved
NfcWriteView(isNfcEnabled = false, identifier = "identifier")
}

@Preview(showSystemUi = true)
@Composable
fun NfcWriteView_NfcEnabled_Preview() {
vieck marked this conversation as resolved.
Show resolved Hide resolved
NfcWriteView(isNfcEnabled = true, identifier = "identifier", onSetIdentifier = {})
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.homeassistant.companion.android.common.R

Expand All @@ -34,3 +35,9 @@ fun TagReaderView() {
)
}
}

@Preview(showSystemUi = true)
@Composable
fun TagReaderViewPreview() {
TagReaderView()
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,51 @@ import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import io.homeassistant.companion.android.R
import io.homeassistant.companion.android.common.R as commonR
import io.homeassistant.companion.android.onboarding.OnboardingHeaderView
import io.homeassistant.companion.android.onboarding.OnboardingViewModel
import io.homeassistant.companion.android.util.homeAssistantInstance1
import io.homeassistant.companion.android.util.homeAssistantInstance2

@Composable
fun DiscoveryView(
onboardingViewModel: OnboardingViewModel,
manualSetupClicked: () -> Unit,
instanceClicked: (instance: HomeAssistantInstance) -> Unit
) {
DiscoveryView(foundInstances = onboardingViewModel.foundInstances, manualSetupClicked = manualSetupClicked, instanceClicked = instanceClicked)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why keep this around? You can update the fragment to use the 'new'/updated function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jpelgrom This is only for compose previews. Basically, if we use the second one we need to expand the parameters of un DiscoveryView(
onboardingViewModel: OnboardingViewModel,
manualSetupClicked: () -> Unit,
instanceClicked: (instance: HomeAssistantInstance) -> Unit
) {
to include everything that we use in onboardingViewModel

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jpelgrom Read here real quick https://developer.android.com/jetpack/compose/tooling/previews#preview-viewmodel
"If you want to preview a composable that uses a ViewModel, you should create another composable with the parameters from ViewModel passed as arguments of the composable. This way, you don't need to preview the composable that uses the ViewModel."

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand this is required for the Compose previews. My point was: if this is what we need, why keep the other function that uses a ViewModel as well instead of switching it to use this new constructor? I see little to no advantage, and with these changes you need to update both functions anyway.

if we use the second one we need to expand the parameters of un DiscoveryView (...) to include everything that we use in onboardingViewModel

You don't, as you've already proven with the function you've added. For DiscoveryView, you only need/use onboardingViewModel.foundInstances.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update this as requested (or give more arguments to convince why not :)) to proceed.


@Composable
fun DiscoveryView(
foundInstances: SnapshotStateList<HomeAssistantInstance>,
manualSetupClicked: () -> Unit,
instanceClicked: (instance: HomeAssistantInstance) -> Unit
) {
Column(
modifier = Modifier.fillMaxWidth()
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
OnboardingHeaderView(
icon = CommunityMaterial.Icon2.cmd_home_search,
title = stringResource(id = commonR.string.select_instance)
)
LinearProgressIndicator(
modifier = Modifier.fillMaxWidth(0.25f)
modifier = Modifier
.fillMaxWidth(0.25f)
.padding(vertical = 16.dp)
.height(2.dp)
.align(Alignment.CenterHorizontally)
Expand All @@ -55,8 +72,8 @@ fun DiscoveryView(
.fillMaxWidth()
.weight(1f)
) {
items(onboardingViewModel.foundInstances.size, { onboardingViewModel.foundInstances[it].url }) { index ->
val instance = onboardingViewModel.foundInstances[index]
items(foundInstances.size, { foundInstances[it].url }) { index ->
val instance = foundInstances[index]
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
Expand Down Expand Up @@ -92,3 +109,15 @@ fun DiscoveryView(
}
}
}

@Preview(showSystemUi = true)
@Composable
fun DiscoveryViewPreview() {
DiscoveryView(
foundInstances = remember {
mutableStateListOf(homeAssistantInstance1, homeAssistantInstance2)
},
manualSetupClicked = { },
instanceClicked = {}
)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.homeassistant.companion.android.onboarding.manual

import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
Expand All @@ -11,6 +12,9 @@ import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
Expand All @@ -19,6 +23,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import io.homeassistant.companion.android.common.R as commonR
Expand All @@ -30,6 +35,16 @@ import io.homeassistant.companion.android.onboarding.OnboardingViewModel
fun ManualSetupView(
onboardingViewModel: OnboardingViewModel,
connectedClicked: () -> Unit
) {
ManualSetupView(onboardingViewModel.manualUrl, onboardingViewModel::onManualUrlUpdated, onboardingViewModel.manualContinueEnabled, connectedClicked)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why keep this around? You can update the fragment to use the 'new'/updated function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


@Composable
fun ManualSetupView(
manualUrl: MutableState<String>,
onManualUrlUpdated: (String) -> Unit,
manualContinueEnabled: Boolean,
connectedClicked: () -> Unit
) {
val scrollState = rememberScrollState()
val keyboardController = LocalSoftwareKeyboardController.current
Expand All @@ -54,8 +69,8 @@ fun ManualSetupView(
)

TextField(
value = onboardingViewModel.manualUrl.value,
onValueChange = { onboardingViewModel.onManualUrlUpdated(it) },
value = manualUrl.value,
onValueChange = { onManualUrlUpdated(it) },
modifier = Modifier.align(Alignment.CenterHorizontally),
label = { Text(stringResource(id = commonR.string.input_url)) },
singleLine = true,
Expand All @@ -69,7 +84,7 @@ fun ManualSetupView(
)

Button(
enabled = onboardingViewModel.manualContinueEnabled,
enabled = manualContinueEnabled,
onClick = connectedClicked,
modifier = Modifier
.align(Alignment.CenterHorizontally)
Expand All @@ -79,3 +94,17 @@ fun ManualSetupView(
}
}
}

@Preview(showSystemUi = true)
vieck marked this conversation as resolved.
Show resolved Hide resolved
@Preview(showSystemUi = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun ManualSetupViewPreview() {
ManualSetupView(
manualUrl = remember {
mutableStateOf("test")
},
onManualUrlUpdated = {},
manualContinueEnabled = true,
connectedClicked = {}
)
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package io.homeassistant.companion.android.util

import io.homeassistant.companion.android.common.data.HomeAssistantVersion
import io.homeassistant.companion.android.common.data.integration.Entity
import io.homeassistant.companion.android.database.notification.NotificationItem
import io.homeassistant.companion.android.onboarding.discovery.HomeAssistantInstance
import java.net.URL
import java.util.Calendar

val notificationItem = NotificationItem(1, 1636389288682, "testing", "{\"message\":\"test\"}", "FCM", null)
Expand All @@ -26,3 +29,6 @@ val previewEntityList = mapOf(
)

val previewFavoritesList = listOf("light.test")

val homeAssistantInstance1 = HomeAssistantInstance(name = "Home", url = URL("https://google.com"), version = HomeAssistantVersion(year = 2024, month = 1, release = 1))
val homeAssistantInstance2 = HomeAssistantInstance(name = "Vacation Home", url = URL("http://localhost"), version = HomeAssistantVersion(year = 2024, month = 1, release = 1))
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.SnapshotStateList
Expand All @@ -16,11 +19,13 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.wear.compose.foundation.lazy.items
import androidx.wear.compose.material3.Button
import androidx.wear.compose.material3.ButtonDefaults
import androidx.wear.compose.material3.Text
import androidx.wear.tooling.preview.devices.WearDevices
import com.mikepenz.iconics.compose.Image
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import io.homeassistant.companion.android.common.R as commonR
Expand All @@ -30,6 +35,8 @@ import io.homeassistant.companion.android.common.util.capitalize
import io.homeassistant.companion.android.data.SimplifiedEntity
import io.homeassistant.companion.android.theme.WearAppTheme
import io.homeassistant.companion.android.theme.getFilledTonalButtonColors
import io.homeassistant.companion.android.util.playPreviewEntityScene1
import io.homeassistant.companion.android.util.playPreviewEntityScene2
import io.homeassistant.companion.android.util.stringForDomain
import java.util.Locale

Expand Down Expand Up @@ -150,3 +157,46 @@ private fun ChooseEntityChip(
colors = getFilledTonalButtonColors()
)
}

@Preview(device = WearDevices.LARGE_ROUND)
@Composable
fun ChooseEntityView_Empty_Preview() {
vieck marked this conversation as resolved.
Show resolved Hide resolved
ChooseEntityView(
entitiesByDomainOrder = remember {
mutableStateListOf()
},
entitiesByDomain = remember {
mutableStateMapOf()
},
favoriteEntityIds = remember { mutableStateOf(listOf()) },
onNoneClicked = {},
onEntitySelected = {},
allowNone = true
)
}

@Preview(device = WearDevices.LARGE_ROUND)
@Composable
fun ChooseEntityView_WithData_Preview() {
vieck marked this conversation as resolved.
Show resolved Hide resolved
ChooseEntityView(
entitiesByDomainOrder = remember {
mutableStateListOf(playPreviewEntityScene1.entityId, playPreviewEntityScene2.entityId)
},
entitiesByDomain = remember {
mutableStateMapOf(
Pair(
playPreviewEntityScene1.entityId,
mutableStateListOf(playPreviewEntityScene1)
),
Pair(
playPreviewEntityScene2.entityId,
mutableStateListOf(playPreviewEntityScene2)
)
)
},
favoriteEntityIds = remember { mutableStateOf(listOf(playPreviewEntityScene1.entityId)) },
onNoneClicked = {},
onEntitySelected = {},
allowNone = false
)
}