Skip to content

Commit 4c53463

Browse files
cmaierFabtron
andauthored
ui-toolkit: Add VersionWidget to display the app and sdk version (#87)
Add a VersionWidget for the DynamicView and Sections to be able to display the App and SDK version. Co-authored-by: Fabian Bender <[email protected]>
1 parent 262080b commit 4c53463

File tree

8 files changed

+159
-1
lines changed

8 files changed

+159
-1
lines changed

kotlin-sample/src/main/assets/profileConfig.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@
8888
"id": "4",
8989
"text": "Profile.licences",
9090
"padding": [16, 8]
91+
},
92+
{
93+
"type": "snabble.version",
94+
"id": "5",
95+
"padding": [16, 8]
9196
}
9297
]
9398
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.snabble.sdk.dynamicview.data.dto
2+
3+
import io.snabble.sdk.dynamicview.domain.model.VersionItem
4+
import kotlinx.serialization.SerialName
5+
import kotlinx.serialization.Serializable
6+
7+
@Serializable
8+
@SerialName("snabble.version")
9+
internal data class VersionDto(
10+
@SerialName("id") override val id: String,
11+
@SerialName("padding") val padding: PaddingDto,
12+
) : WidgetDto
13+
14+
internal fun VersionDto.toVersion(): VersionItem = VersionItem(
15+
id = id,
16+
padding = padding.toPadding()
17+
)

ui-toolkit/src/main/kotlin/io/snabble/sdk/dynamicview/data/dto/mapper/ConfigMapper.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import io.snabble.sdk.dynamicview.data.dto.SsidProvider
1616
import io.snabble.sdk.dynamicview.data.dto.StartShoppingDto
1717
import io.snabble.sdk.dynamicview.data.dto.TextDto
1818
import io.snabble.sdk.dynamicview.data.dto.ToggleDto
19+
import io.snabble.sdk.dynamicview.data.dto.VersionDto
1920
import io.snabble.sdk.dynamicview.data.dto.WidgetDto
2021
import io.snabble.sdk.dynamicview.data.dto.toButton
2122
import io.snabble.sdk.dynamicview.data.dto.toConnectWlan
@@ -29,6 +30,7 @@ import io.snabble.sdk.dynamicview.data.dto.toSeeAllStores
2930
import io.snabble.sdk.dynamicview.data.dto.toStartShopping
3031
import io.snabble.sdk.dynamicview.data.dto.toText
3132
import io.snabble.sdk.dynamicview.data.dto.toToggle
33+
import io.snabble.sdk.dynamicview.data.dto.toVersion
3234
import io.snabble.sdk.dynamicview.domain.model.Configuration
3335
import io.snabble.sdk.dynamicview.domain.model.DynamicConfig
3436
import io.snabble.sdk.dynamicview.domain.model.SectionItem
@@ -95,6 +97,8 @@ internal class ConfigMapperImpl(private val context: Context, private val ssidPr
9597
)
9698

9799
is ToggleDto -> toToggle(text = "${context.resolveResourceString(text)}")
100+
101+
is VersionDto -> toVersion()
98102
}
99103
}
100104
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package io.snabble.sdk.dynamicview.domain.model
2+
3+
data class VersionItem(
4+
override val id: String,
5+
val padding: Padding,
6+
) : Widget

ui-toolkit/src/main/kotlin/io/snabble/sdk/dynamicview/ui/DynamicView.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import io.snabble.sdk.dynamicview.domain.model.SeeAllStoresItem
1919
import io.snabble.sdk.dynamicview.domain.model.StartShoppingItem
2020
import io.snabble.sdk.dynamicview.domain.model.TextItem
2121
import io.snabble.sdk.dynamicview.domain.model.ToggleItem
22+
import io.snabble.sdk.dynamicview.domain.model.VersionItem
2223
import io.snabble.sdk.dynamicview.domain.model.Widget
2324
import io.snabble.sdk.dynamicview.viewmodel.DynamicAction
2425
import io.snabble.sdk.widgets.ButtonWidget
@@ -32,6 +33,7 @@ import io.snabble.sdk.widgets.snabble.purchase.ui.PurchaseWidget
3233
import io.snabble.sdk.widgets.snabble.stores.ui.SeeAllStoresWidget
3334
import io.snabble.sdk.widgets.snabble.stores.ui.StartShoppingWidget
3435
import io.snabble.sdk.widgets.snabble.toggle.ui.ToggleWidget
36+
import io.snabble.sdk.widgets.snabble.version.ui.VersionWidget
3537
import io.snabble.sdk.widgets.snabble.wlan.ui.ConnectWlanWidget
3638

3739
typealias OnDynamicAction = (action: DynamicAction) -> Unit
@@ -86,4 +88,6 @@ internal fun Widget(
8688
is ToggleItem -> ToggleWidget(model = widget, onAction = onAction)
8789

8890
is SectionItem -> SectionWidget(model = widget, onAction = onAction)
91+
92+
is VersionItem -> VersionWidget(model = widget, onAction = onAction)
8993
}

ui-toolkit/src/main/kotlin/io/snabble/sdk/widgets/SectionWidget.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import io.snabble.sdk.dynamicview.domain.model.Padding
2020
import io.snabble.sdk.dynamicview.domain.model.SectionItem
2121
import io.snabble.sdk.dynamicview.domain.model.TextItem
2222
import io.snabble.sdk.dynamicview.domain.model.ToggleItem
23+
import io.snabble.sdk.dynamicview.domain.model.VersionItem
2324
import io.snabble.sdk.dynamicview.domain.model.toPaddingValues
2425
import io.snabble.sdk.dynamicview.theme.properties.Elevation
2526
import io.snabble.sdk.dynamicview.theme.properties.LocalElevation
@@ -30,6 +31,7 @@ import io.snabble.sdk.dynamicview.theme.properties.padding
3031
import io.snabble.sdk.dynamicview.ui.OnDynamicAction
3132
import io.snabble.sdk.utils.isNotNullOrBlank
3233
import io.snabble.sdk.widgets.snabble.toggle.ui.ToggleWidget
34+
import io.snabble.sdk.widgets.snabble.version.ui.VersionWidget
3335
import io.snabble.sdk.dynamicview.theme.properties.Padding as OuterPadding
3436

3537
@Composable
@@ -70,6 +72,12 @@ fun SectionWidget(
7072
modifier = Modifier.heightIn(min = 36.dp)
7173
)
7274

75+
is VersionItem -> VersionWidget(
76+
model = widget,
77+
onAction = onAction,
78+
modifier = Modifier.heightIn(min = 36.dp)
79+
)
80+
7381
else -> Unit
7482
}
7583
Divider(modifier = modifier.fillMaxWidth(), thickness = Dp.Hairline)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package io.snabble.sdk.widgets.snabble.version.ui
2+
3+
import android.content.Context
4+
import android.content.pm.PackageManager
5+
import android.os.Build
6+
import androidx.compose.foundation.clickable
7+
import androidx.compose.foundation.interaction.MutableInteractionSource
8+
import androidx.compose.foundation.layout.Column
9+
import androidx.compose.foundation.layout.Spacer
10+
import androidx.compose.foundation.layout.fillMaxWidth
11+
import androidx.compose.foundation.layout.height
12+
import androidx.compose.foundation.layout.padding
13+
import androidx.compose.material.Text
14+
import androidx.compose.material3.MaterialTheme
15+
import androidx.compose.runtime.Composable
16+
import androidx.compose.ui.Modifier
17+
import androidx.compose.ui.platform.LocalContext
18+
import androidx.compose.ui.platform.LocalInspectionMode
19+
import androidx.compose.ui.tooling.preview.Preview
20+
import androidx.compose.ui.unit.dp
21+
import io.snabble.sdk.Snabble
22+
import io.snabble.sdk.dynamicview.domain.model.Padding
23+
import io.snabble.sdk.dynamicview.domain.model.VersionItem
24+
import io.snabble.sdk.dynamicview.domain.model.toPaddingValues
25+
import io.snabble.sdk.dynamicview.ui.OnDynamicAction
26+
import io.snabble.sdk.dynamicview.viewmodel.DynamicAction
27+
28+
@Composable
29+
fun VersionWidget(
30+
modifier: Modifier = Modifier,
31+
model: VersionItem,
32+
onAction: OnDynamicAction,
33+
) {
34+
val appVersion: String
35+
val sdkVersion: String
36+
37+
if (!LocalInspectionMode.current) {
38+
appVersion = provideAppVersion(LocalContext.current)
39+
sdkVersion = Snabble.version
40+
} else {
41+
appVersion = "1.0"
42+
sdkVersion = "0.10.0"
43+
}
44+
45+
Column(
46+
modifier = Modifier
47+
.fillMaxWidth()
48+
.clickable(
49+
interactionSource = MutableInteractionSource(),
50+
indication = null,
51+
) {
52+
onAction(DynamicAction(model))
53+
}
54+
.padding(model.padding.toPaddingValues())
55+
.then(modifier)
56+
) {
57+
Text(
58+
text = "Version",
59+
color = MaterialTheme.colorScheme.onSurface,
60+
style = MaterialTheme.typography.bodyLarge
61+
)
62+
Spacer(modifier = Modifier.height(4.dp))
63+
Text(
64+
text = "$appVersion, SDK $sdkVersion",
65+
color = MaterialTheme.colorScheme.onSurface,
66+
style = MaterialTheme.typography.bodyMedium
67+
)
68+
}
69+
}
70+
71+
private fun provideAppVersion(context: Context): String {
72+
val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
73+
context.packageManager.getPackageInfo(context.packageName, PackageManager.PackageInfoFlags.of(0L))
74+
} else {
75+
@Suppress("DEPRECATION")
76+
context.packageManager.getPackageInfo(context.packageName, 0)
77+
}
78+
return packageInfo.versionName
79+
}
80+
81+
@Preview
82+
@Composable
83+
fun VersionWidgetPreview() {
84+
VersionWidget(
85+
model = VersionItem(
86+
id = "a.version",
87+
padding = Padding(0)
88+
),
89+
onAction = {}
90+
)
91+
}

ui-toolkit/src/test/kotlin/io/snabble/sdk/dynamicview/data/dto/mapper/ConfigMapperTest.kt renamed to ui-toolkit/src/test/kotlin/io/snabble/sdk/dynamicview/data/dto/mapper/ConfigMapperImplTest.kt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import io.snabble.sdk.dynamicview.data.dto.SectionDto
2121
import io.snabble.sdk.dynamicview.data.dto.SeeAllStoresDto
2222
import io.snabble.sdk.dynamicview.data.dto.StartShoppingDto
2323
import io.snabble.sdk.dynamicview.data.dto.TextDto
24+
import io.snabble.sdk.dynamicview.data.dto.VersionDto
2425
import io.snabble.sdk.dynamicview.data.dto.WidgetDto
2526
import io.snabble.sdk.dynamicview.domain.model.ButtonItem
2627
import io.snabble.sdk.dynamicview.domain.model.ConnectWlanItem
@@ -33,12 +34,13 @@ import io.snabble.sdk.dynamicview.domain.model.SectionItem
3334
import io.snabble.sdk.dynamicview.domain.model.SeeAllStoresItem
3435
import io.snabble.sdk.dynamicview.domain.model.StartShoppingItem
3536
import io.snabble.sdk.dynamicview.domain.model.TextItem
37+
import io.snabble.sdk.dynamicview.domain.model.VersionItem
3638
import io.snabble.sdk.utils.getComposeColor
3739
import io.snabble.sdk.utils.getResourceString
3840
import io.snabble.sdk.utils.resolveColorId
3941
import io.snabble.sdk.utils.resolveImageId
4042

41-
internal class ConfigMapperTest : FreeSpec({
43+
internal class ConfigMapperImplTest : FreeSpec({
4244

4345
val context = mockk<Context>(relaxed = true)
4446

@@ -391,6 +393,27 @@ internal class ConfigMapperTest : FreeSpec({
391393
}
392394
}
393395

396+
"VersionDto to VersionItem" - {
397+
398+
val versionDto = VersionDto(
399+
id = "a.version",
400+
padding = PaddingDto(0, 0, 0, 0)
401+
)
402+
403+
val rootDto = setupSutDto(versionDto)
404+
every { context.resolveImageId(rootDto.configuration.image) } returns 1
405+
406+
val sut = createMapper().mapDtoToItems(rootDto)
407+
408+
val startShoppingItem = sut.widgets.first().shouldBeTypeOf<VersionItem>()
409+
410+
"id" {
411+
startShoppingItem.id shouldBe "a.version"
412+
}
413+
"padding" {
414+
startShoppingItem.padding shouldBe Padding(0, 0, 0, 0)
415+
}
416+
}
394417
}
395418
}
396419
})

0 commit comments

Comments
 (0)