Skip to content

Commit

Permalink
introduce a reference device annotation to group composable previews (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
thebino committed Jul 26, 2023
1 parent d9a35d4 commit 3ad327f
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 163 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2020-2023 Photos.network developers
*
* 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 photos.network.ui.common

import android.content.res.Configuration
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview

@Preview(showBackground = true, name = "phone • light", device = Devices.PHONE, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(showBackground = true, name = "phone • dark", device = Devices.PHONE, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview(showBackground = true, name = "foldable", device = Devices.FOLDABLE)
@Preview(showBackground = true, name = "tablet", device = "spec:width=1280dp,height=800dp,dpi=480")
// @Preview(showBackground = true, name = "desktop", device = "spec:width=1920dp,height=1080dp,dpi=480")
annotation class ReferenceDevices
174 changes: 11 additions & 163 deletions ui/settings/src/main/kotlin/photos/network/ui/settings/SettingsScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@
*/
package photos.network.ui.settings

import android.content.res.Configuration
import android.widget.Toast
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
Expand All @@ -40,8 +35,6 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.TextField
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.KeyboardArrowRight
import androidx.compose.material3.Divider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
Expand All @@ -55,24 +48,22 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import org.koin.androidx.compose.getViewModel
import photos.network.api.ServerStatus
import photos.network.ui.common.components.AppLogo
import photos.network.ui.common.ReferenceDevices
import photos.network.ui.common.navigation.Destination
import photos.network.ui.common.theme.AppTheme
import photos.network.ui.settings.composable.ServerSetupItem
import photos.network.ui.settings.composable.SettingsHeader

/**
* stateful
Expand Down Expand Up @@ -110,6 +101,7 @@ fun SettingsScreen(

Column(
modifier = modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
.verticalScroll(verticalScrollState),
) {
Expand All @@ -118,6 +110,7 @@ fun SettingsScreen(
Text(
modifier = Modifier.padding(horizontal = 16.dp),
text = stringResource(id = R.string.settings_features_pre),
color = MaterialTheme.colorScheme.onBackground,
)
val map = listOf(
stringResource(id = R.string.feature_sharing_title) to stringResource(id = R.string.feature_sharing_description),
Expand All @@ -137,17 +130,19 @@ fun SettingsScreen(
modifier = Modifier
.padding(start = 8.dp, end = 8.dp)
.size(8.dp)
.background(Color.Black, shape = CircleShape),
.background(MaterialTheme.colorScheme.onBackground, shape = CircleShape),
)

Text(
text = it.first,
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.onBackground,
)
}
Text(
modifier = Modifier.padding(start = 24.dp),
text = it.second,
color = MaterialTheme.colorScheme.onBackground,
)
}
}
Expand All @@ -157,6 +152,7 @@ fun SettingsScreen(
.padding(horizontal = 16.dp)
.padding(bottom = 16.dp),
text = stringResource(id = R.string.settings_features_post),
color = MaterialTheme.colorScheme.onBackground,
)

Divider()
Expand Down Expand Up @@ -196,143 +192,6 @@ fun SettingsScreen(
}
}

@Suppress("MagicNumber")
@Composable
internal fun SettingsHeader(
modifier: Modifier = Modifier,
serverStatus: ServerStatus,
) {
// header + icon
Box(
modifier = modifier.background(MaterialTheme.colorScheme.surface),
) {
// header gradient
Box(
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.background(MaterialTheme.colorScheme.primary)
.background(
brush = Brush.verticalGradient(
colors = listOf(
Color(0x55000000),
Color(0x00000000),
),
),
),
)

// app name
Text(
modifier = Modifier
.padding(top = 32.dp)
.testTag("SETTINGS_HEADER_TITLE")
.fillMaxWidth(),
text = stringResource(id = R.string.app_name_full),
style = MaterialTheme.typography.headlineLarge,
textAlign = TextAlign.Center,
color = Color.White,
)

// logo with status indicator
AppLogo(
modifier = Modifier
.padding(top = 125.dp)
.testTag("SETTINGS_HEADER_LOGO")
.fillMaxWidth()
.align(Alignment.Center),
size = 150.dp,
serverStatus = serverStatus,
)
}
}

@Composable
fun ServerSetupItem(
modifier: Modifier = Modifier,
isExpanded: Boolean = false,
serverHost: String = "",
onServerHostUpdated: (String) -> Unit = {},
isHostVerified: Boolean = false,
clientId: String = "",
onClientIdUpdated: (String) -> Unit = {},
isClientIdVerified: Boolean = false,
serverStatus: ServerStatus = ServerStatus.UNAVAILABLE,
onServerSetupClicked: () -> Unit = {},
) {
val serverSetupLabel = if (serverStatus != ServerStatus.AVAILABLE) {
stringResource(id = R.string.settings_item_server_setup)
} else {
stringResource(id = R.string.settings_item_server_update)
}
Surface(
modifier = modifier
.clickable(
onClickLabel = serverSetupLabel,
) {
onServerSetupClicked()
},
) {
Row(
modifier = Modifier
.padding(16.dp),
) {
Text(
modifier = Modifier.weight(1f),
text = serverSetupLabel,
)
if (isExpanded) {
Icon(
imageVector = Icons.Default.KeyboardArrowDown,
contentDescription = null,
)
} else {
Icon(
imageVector = Icons.Default.KeyboardArrowRight,
contentDescription = null,
)
}
}
}

Column {
// server host
AnimatedVisibility(
visible = isExpanded,
enter = fadeIn(animationSpec = tween(durationMillis = 1000)) + expandVertically(),
exit = shrinkVertically(animationSpec = tween(durationMillis = 500, delayMillis = 0)),
) {
FormInput(
modifier = modifier,
label = "Host",
value = serverHost,
hint = "https://",
onValueChanged = {
onServerHostUpdated(it)
},
showTrailingIcon = isHostVerified,
)
}

// client id
AnimatedVisibility(
visible = isExpanded && isHostVerified,
enter = fadeIn(animationSpec = tween(durationMillis = 1000)) + expandVertically(),
exit = shrinkVertically(animationSpec = tween(durationMillis = 500, delayMillis = 0)),
) {
FormInput(
modifier = modifier,
label = "Client ID",
value = clientId,
onValueChanged = {
onClientIdUpdated(it)
},
showTrailingIcon = isClientIdVerified,
)
}
}
}

@Composable
fun FormInput(
modifier: Modifier = Modifier,
Expand Down Expand Up @@ -456,20 +315,9 @@ fun AccountSetupItem(
}
}

@Preview(
"Account",
showSystemUi = true,
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_NO,
)
@Preview(
"Account • Dark",
showSystemUi = true,
showBackground = true,
uiMode = Configuration.UI_MODE_NIGHT_YES,
)
@ReferenceDevices
@Composable
private fun PreviewAccount(
private fun Settings(
@PreviewParameter(PreviewAccountProvider::class) uiState: SettingsUiState,
) {
AppTheme {
Expand Down
Loading

0 comments on commit 3ad327f

Please sign in to comment.