Skip to content

Commit

Permalink
Merge pull request #982 from raseln/raseln/implement_contributors_cou…
Browse files Browse the repository at this point in the history
…nt_ui

[ContributorsScreen] Display the total number of persons in ContributorsScreen
  • Loading branch information
takahirom authored Sep 7, 2024
2 parents 8cec73f + 14300ef commit bab8c00
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 1 deletion.
49 changes: 49 additions & 0 deletions app-ios/Sources/ContributorFeature/ContributorsCountItem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import SwiftUI
import Theme

struct ContributorsCountItem: View {
let totalContributor: Int
let duration: Double = 1.0
@State private var tracker = 0

var body: some View {
VStack(alignment: .leading) {

Text(String(localized: "Total", bundle: .module))
.textStyle(.titleMedium)
.foregroundStyle(AssetColors.Surface.onSurfaceVariant.swiftUIColor)
.frame(maxWidth: .infinity, alignment: .leading)

HStack {
Text("\(tracker)")
.textStyle(.headlineLarge)
.foregroundStyle(AssetColors.Surface.onSurface.swiftUIColor)
.onAppear() {
animate()
}

Text(String(localized: "Person", bundle: .module))
.textStyle(.headlineSmall)
.foregroundStyle(AssetColors.Surface.onSurface.swiftUIColor)
}

Spacer()
.frame(height: 16)
Divider()
}
}

func animate() {
let interval = duration / Double(totalContributor)
Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { time in
tracker += 1
if tracker == totalContributor {
time.invalidate()
}
}
}
}

#Preview {
ContributorsCountItem(totalContributor: 112)
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ struct KmpPresenterContributorView: View {
if let existsState = state as? Exists {
ScrollView {
LazyVStack(spacing: 0) {

ContributorsCountItem(totalContributor: existsState.contributors.count)
.frame(maxWidth: .infinity)
.padding(.horizontal, 16)
.padding(.vertical, 10)

ForEach(existsState.contributors, id: \.id) { value in
let contributor = Model.Contributor(
id: Int(value.id),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,39 @@
}
}
}
},
"Person" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "persons"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "人"
}
}
}
},
"Total" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Total"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "合計"
}
}
}
}
},
"version" : "1.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ struct SwiftUIContributorView: View {
if let contributors = store.contributors {
ScrollView {
LazyVStack(spacing: 0) {

ContributorsCountItem(totalContributor: contributors.count)
.frame(maxWidth: .infinity)
.padding(.horizontal, 16)
.padding(.vertical, 10)

ForEach(contributors, id: \.id) { contributor in
ContributorListItemView(contributor: contributor) { url in
store.send(.view(.contributorButtonTapped(url)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.isDisplayed
import androidx.compose.ui.test.performScrollToIndex
import io.github.droidkaigi.confsched.contributors.ContributorsItemTestTagPrefix
import io.github.droidkaigi.confsched.contributors.ContributorsScreen
import io.github.droidkaigi.confsched.contributors.ContributorsTestTag
import io.github.droidkaigi.confsched.contributors.ContributorsTotalCountTestTag
import io.github.droidkaigi.confsched.contributors.component.ContributorsItemImageTestTagPrefix
import io.github.droidkaigi.confsched.contributors.component.ContributorsUserNameTextTestTagPrefix
import io.github.droidkaigi.confsched.droidkaigiui.Inject
Expand Down Expand Up @@ -80,6 +82,14 @@ class ContributorsScreenRobot @Inject constructor(
.assertCountAtLeast(2)
}

fun checkContributorTotalCountDisplayed() {
// Check contributors total count is being displayed
composeTestRule
.onNode(hasTestTag(ContributorsTotalCountTestTag))
.assertExists()
.isDisplayed()
}

fun checkDoesNotFirstContributorItemDisplayed() {
val contributor = Contributor.fakes().first()
composeTestRule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class ContributorsScreenTest(private val testCase: DescribedBehavior<Contributor
checkShowFirstAndSecondContributors()
}
}
itShould("show contributors total count") {
captureScreenWithChecks {
checkContributorTotalCountDisplayed()
}
}

describe("when scroll to index 10") {
doIt {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="contributor_title">コントリビューター</string>
<string name="contributor_total">合計</string>
<string name="contributor_person">人</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="contributor_title">Contributor</string>
<string name="contributor_total">Total</string>
<string name="contributor_person">persons</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import conference_app_2024.feature.contributors.generated.resources.contributor_title
import io.github.droidkaigi.confsched.compose.rememberEventFlow
import io.github.droidkaigi.confsched.contributors.component.ContributorsCountItem
import io.github.droidkaigi.confsched.contributors.component.ContributorsItem
import io.github.droidkaigi.confsched.droidkaigiui.SnackbarMessageEffect
import io.github.droidkaigi.confsched.droidkaigiui.UserMessageStateHolder
Expand All @@ -36,6 +37,7 @@ const val contributorsScreenRoute = "contributors"
const val ContributorsScreenTestTag = "ContributorsScreenTestTag"
const val ContributorsTestTag = "ContributorsTestTag"
const val ContributorsItemTestTagPrefix = "ContributorsItemTestTag:"
const val ContributorsTotalCountTestTag = "ContributorsTotalCountTestTag"

fun NavGraphBuilder.contributorsScreens(
onNavigationIconClick: () -> Unit,
Expand Down Expand Up @@ -161,6 +163,14 @@ private fun Contributors(
modifier = modifier.testTag(ContributorsTestTag),
contentPadding = contentPadding,
) {
item {
ContributorsCountItem(
totalContributor = contributors.size,
modifier = Modifier
.fillMaxWidth()
.testTag(ContributorsTotalCountTestTag),
)
}
items(contributors) {
ContributorsItem(
contributor = it,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package io.github.droidkaigi.confsched.contributors.component

import androidx.compose.animation.core.EaseOutQuart
import androidx.compose.animation.core.animateIntAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import conference_app_2024.feature.contributors.generated.resources.contributor_person
import conference_app_2024.feature.contributors.generated.resources.contributor_total
import io.github.droidkaigi.confsched.contributors.ContributorsRes
import org.jetbrains.compose.resources.stringResource

@Composable
internal fun ContributorsCountItem(
totalContributor: Int,
modifier: Modifier = Modifier,
) {
var targetValue by remember { mutableStateOf(0) }
val animatedTotalContributor by animateIntAsState(
targetValue = targetValue,
animationSpec = tween(
delayMillis = 300,
durationMillis = 1000,
easing = EaseOutQuart,
),
)
LaunchedEffect(totalContributor) {
targetValue = totalContributor
}
Column(
modifier = modifier
.padding(horizontal = 16.dp, vertical = 10.dp),
) {
Text(
text = stringResource(ContributorsRes.string.contributor_total),
style = MaterialTheme.typography.titleMedium,
)
Row(
horizontalArrangement = Arrangement.spacedBy(6.dp),
verticalAlignment = Alignment.Bottom,
) {
Text(
text = "$animatedTotalContributor",
style = MaterialTheme.typography.headlineLarge,
)
Text(
text = stringResource(ContributorsRes.string.contributor_person),
style = MaterialTheme.typography.headlineSmall,
)
}
Spacer(modifier = Modifier.height(16.dp))
HorizontalDivider()
}
}

0 comments on commit bab8c00

Please sign in to comment.