Skip to content

Commit

Permalink
Add InfoScreen to datalayer wear sample (#1895)
Browse files Browse the repository at this point in the history
  • Loading branch information
luizgrp authored Dec 19, 2023
1 parent a88e91c commit 47abc88
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.google.android.horologist.datalayer.sample

import com.google.android.horologist.datalayer.sample.screens.info.infoScreenRoute

sealed class Screen(
val route: String,
) {
Expand All @@ -26,4 +28,5 @@ sealed class Screen(

data object AppHelperTrackingScreen : Screen("appHelperTrackingScreen")
data object AppHelperNodesActionsScreen : Screen("appHelperNodesActionsScreen")
data object InfoScreen : Screen(infoScreenRoute)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import com.google.android.horologist.compose.navscaffold.WearNavScaffold
import com.google.android.horologist.compose.navscaffold.scrollable
import com.google.android.horologist.datalayer.sample.screens.MainScreen
import com.google.android.horologist.datalayer.sample.screens.datalayer.DataLayerScreen
import com.google.android.horologist.datalayer.sample.screens.info.infoScreen
import com.google.android.horologist.datalayer.sample.screens.info.navigateToInfoScreen
import com.google.android.horologist.datalayer.sample.screens.nodes.DataLayerNodesScreen
import com.google.android.horologist.datalayer.sample.screens.nodesactions.NodesActionsScreen
import com.google.android.horologist.datalayer.sample.screens.tracking.TrackingScreen
Expand Down Expand Up @@ -53,12 +55,18 @@ fun WearApp(
scrollable(route = Screen.ListNodesScreen.route) {
DataLayerNodesScreen(columnState = it.columnState)
}
scrollable(route = Screen.AppHelperTrackingScreen.route) {
TrackingScreen(columnState = it.columnState)
scrollable(route = Screen.AppHelperTrackingScreen.route) { scrolllableScaffoldContext ->
TrackingScreen(
onDisplayInfoClicked = navController::navigateToInfoScreen,
columnState = scrolllableScaffoldContext.columnState,
)
}
scrollable(route = Screen.AppHelperNodesActionsScreen.route) {
NodesActionsScreen(columnState = it.columnState)
}
infoScreen(
onDismissClick = navController::popBackStack,
)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.horologist.datalayer.sample.screens.info

import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Done
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.wear.compose.material.Text
import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
import com.google.android.horologist.compose.layout.ScalingLazyColumn
import com.google.android.horologist.compose.layout.ScalingLazyColumnState
import com.google.android.horologist.compose.layout.belowTimeTextPreview
import com.google.android.horologist.compose.material.Button
import com.google.android.horologist.datalayer.sample.R

@Composable
fun InfoScreen(
onDismissClick: () -> Unit,
columnState: ScalingLazyColumnState,
modifier: Modifier = Modifier,
infoScreenViewModel: InfoScreenViewModel = hiltViewModel(),
) {
InfoScreen(
message = infoScreenViewModel.message,
onDismissClick = onDismissClick,
columnState = columnState,
modifier = modifier,
)
}

@Composable
fun InfoScreen(
message: String,
onDismissClick: () -> Unit,
columnState: ScalingLazyColumnState,
modifier: Modifier = Modifier,
) {
ScalingLazyColumn(
columnState = columnState,
modifier = modifier
.fillMaxSize(),
) {
item {
Text(text = message, modifier = Modifier.padding(top = 20.dp))
}
item {
Button(
imageVector = Icons.Default.Done,
contentDescription = stringResource(id = R.string.info_done_button_content_description),
onClick = onDismissClick,
modifier = Modifier.padding(top = 10.dp),
)
}
}
}

@WearPreviewDevices
@Composable
fun InfoScreenPreview() {
InfoScreen(
message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor " +
"incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " +
"exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
onDismissClick = { },
columnState = belowTimeTextPreview(),
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.horologist.datalayer.sample.screens.info

import androidx.lifecycle.SavedStateHandle
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.google.android.horologist.compose.navscaffold.scrollable
import com.google.android.horologist.datalayer.sample.Screen
import java.net.URLDecoder
import java.net.URLEncoder

private const val messageArg = "message"
private const val routePrefix = "infoScreen"

private val URL_CHARACTER_ENCODING = Charsets.UTF_8.name()

const val infoScreenRoute = "$routePrefix/{$messageArg}"

internal class InfoScreenArgs(val message: String) {
constructor(savedStateHandle: SavedStateHandle) :
this(URLDecoder.decode(checkNotNull(savedStateHandle[messageArg]), URL_CHARACTER_ENCODING))
}

fun NavController.navigateToInfoScreen(message: String) {
val encodedMessage = URLEncoder.encode(message, URL_CHARACTER_ENCODING)
this.navigate("$routePrefix/$encodedMessage")
}

fun NavGraphBuilder.infoScreen(
onDismissClick: () -> Unit,
) {
scrollable(
route = Screen.InfoScreen.route,
arguments = listOf(
navArgument(messageArg) { type = NavType.StringType },
),
) {
InfoScreen(
onDismissClick = onDismissClick,
columnState = it.columnState,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.android.horologist.datalayer.sample.screens.info

import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel

class InfoScreenViewModel(
savedStateHandle: SavedStateHandle,
) : ViewModel() {

private val infoScreenArgs: InfoScreenArgs = InfoScreenArgs(savedStateHandle)

val message: String
get() = infoScreenArgs.message
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.google.android.horologist.datalayer.sample.R

@Composable
fun TrackingScreen(
onDisplayInfoClicked: (info: String) -> Unit,
columnState: ScalingLazyColumnState,
modifier: Modifier = Modifier,
viewModel: TrackingScreenViewModel = hiltViewModel(),
Expand All @@ -54,7 +55,7 @@ fun TrackingScreen(
onSetupCompletedCheckedChanged = viewModel::onSetupCompletedCheckedChanged,
onTileCheckedChanged = viewModel::onTileCheckedChanged,
onComplicationCheckedChanged = viewModel::onComplicationCheckedChanged,
onDisplayInfoClicked = { /* TODO */ },
onDisplayInfoClicked = onDisplayInfoClicked,
columnState = columnState,
modifier = modifier,
)
Expand Down Expand Up @@ -156,7 +157,7 @@ fun TrackingScreen(
for (complicationEntry in state.complicationsInstalled) {
item {
val info = stringResource(
id = R.string.apphelper_tracking_tile_installation_info,
id = R.string.apphelper_tracking_complication_installation_info,
complicationEntry.key,
)
SplitToggleChip(
Expand Down
2 changes: 2 additions & 0 deletions datalayer/sample/wear/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
<string name="data_layer_error_message">Error: %1$s</string>
<string name="data_layer_value_message">Value: %1$s</string>

<string name="info_done_button_content_description">Close</string>

<string name="apphelper_tracking_title">AppHelper Tracking</string>
<string name="apphelper_tracking_message">Tap on an item to learn more about it.</string>
<string name="apphelper_tracking_activity_launched_chip_label">Activity launched once</string>
Expand Down

0 comments on commit 47abc88

Please sign in to comment.