Skip to content

Commit

Permalink
Merge branch 'main' into bug/fix_export_image_display_corruption_prof…
Browse files Browse the repository at this point in the history
…ile_card_when_small_phone
  • Loading branch information
Corvus400 authored Sep 2, 2024
2 parents 7314cf6 + cf6bcdc commit b2e607b
Show file tree
Hide file tree
Showing 25 changed files with 288 additions and 41 deletions.
4 changes: 2 additions & 2 deletions app-android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@

<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
android:theme="@style/Theme.AppCompat.DayNight.DarkActionBar" />
android:theme="@style/Theme.KaigiApp.Licenses" />

<activity
android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
android:theme="@style/Theme.AppCompat.DayNight.DarkActionBar" />
android:theme="@style/Theme.KaigiApp.Licenses" />

<provider
android:name="androidx.core.content.FileProvider"
Expand Down
4 changes: 4 additions & 0 deletions app-android/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
<style name="Theme.KaigiApp" parent="android:Theme.Material.NoActionBar">
<item name="android:statusBarColor">@android:color/transparent</item>
</style>

<style name="Theme.KaigiApp.Licenses" parent="Theme.AppCompat.DayNight.DarkActionBar">
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
</resources>
1 change: 0 additions & 1 deletion app-ios/Sources/AboutFeature/AboutView.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import ComposableArchitecture
import SwiftUI
import LicenseList
import Theme

@ViewAction(for: AboutReducer.self)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation
import SwiftUI
import Theme

private actor CircularUserIconInMemoryCache {
static let shared = CircularUserIconInMemoryCache()
Expand Down Expand Up @@ -35,6 +36,10 @@ public struct CircularUserIcon: View {
}
}
.clipShape(Circle())
.overlay(
Circle()
.stroke(AssetColors.Outline.outline.swiftUIColor, lineWidth: 1)
)
.task {
if let data = await CircularUserIconInMemoryCache.shared.data(urlString: urlString) {
iconData = data
Expand Down
4 changes: 0 additions & 4 deletions app-ios/Sources/StaffFeature/StaffLabel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ struct StaffLabel: View {
HStack(alignment: .center, spacing: 12) {
CircularUserIcon(urlString: icon.absoluteString)
.frame(width: 52, height: 52)
.overlay(
Circle()
.stroke(AssetColors.Outline.outline.swiftUIColor, lineWidth: 1)
)

Text(name)
.textStyle(.bodyLarge)
Expand Down
11 changes: 2 additions & 9 deletions app-ios/Sources/TimetableFeature/TimetableGridCard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,8 @@ public struct TimetableGridCard: View {

ForEach(timetableItem.speakers, id: \.id) { speaker in
HStack(spacing: 8) {
Group {
AsyncImage(url: URL(string: speaker.iconUrl)) {
$0.resizable()
} placeholder: {
Color.gray
}
}
.frame(width: 32, height: 32)
.clipShape(Circle())
CircularUserIcon(urlString: speaker.iconUrl)
.frame(width: 32, height: 32)

Text(speaker.name)
.textStyle(.titleSmall)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ fun Project.setupAndroid() {
namespace?.let {
this.namespace = it
}
compileSdkVersion(34)
compileSdkVersion(35)

defaultConfig {
minSdk = 24
targetSdk = 34
targetSdk = 35
}

compileOptions {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.droidkaigi.confsched.droidkaigiui.component

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalContext
import coil3.request.ImageRequest
Expand All @@ -10,13 +11,17 @@ import io.github.droidkaigi.confsched.droidkaigiui.rememberAsyncImagePainter

@Composable
actual fun speakerPainter(url: String): Painter {
// TODO Use DrawableResource
// https://github.com/DroidKaigi/conference-app-2024/pull/864/files#r1736437080
// https://github.com/coil-kt/coil/issues/2077
return rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalContext.current)
val context = LocalContext.current

val imageRequest = remember(url, context) {
// TODO Use DrawableResource
// https://github.com/DroidKaigi/conference-app-2024/pull/864/files#r1736437080
// https://github.com/coil-kt/coil/issues/2077
ImageRequest.Builder(context)
.data(url)
.placeholder(R.drawable.icon_place_hoolder)
.build(),
)
.build()
}

return rememberAsyncImagePainter(model = imageRequest)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.droidkaigi.confsched.droidkaigiui

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.painter.Painter
import coil3.request.ImageRequest

Expand All @@ -13,7 +14,9 @@ fun rememberAsyncImagePainter(url: String): Painter {

@Composable
fun rememberAsyncImagePainter(model: ImageRequest): Painter {
val requestModel = remember(model) { model }

return coil3.compose.rememberAsyncImagePainter(
model = model,
model = requestModel,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package io.github.droidkaigi.confsched.droidkaigiui.component

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.fadeIn
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons.AutoMirrored.Filled
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MediumTopAppBar
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarColors
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AnimatedMediumTopAppBar(
title: String,
onBackClick: () -> Unit,
navIconContentDescription: String?,
modifier: Modifier = Modifier,
actions: @Composable RowScope.() -> Unit = {},
windowInsets: WindowInsets = TopAppBarDefaults.windowInsets,
colors: TopAppBarColors = TopAppBarDefaults.largeTopAppBarColors().copy(
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer,
),
scrollBehavior: TopAppBarScrollBehavior? = null,
) {
val density = LocalDensity.current.density
var navigationIconWidthDp by remember { mutableStateOf(0f) }
val isCenterTitle = remember(scrollBehavior?.state?.collapsedFraction) {
if (scrollBehavior == null) {
// Always left-align when scrollBehavior is not present
false
} else {
// Hide title position because it doesn't look smooth if it is displayed when collapsing
when (scrollBehavior.state.collapsedFraction) {
in 0.7f..1.0f -> true
in 0.0f..0.5f -> false
else -> null // Don't display while on the move.
}
}
}

MediumTopAppBar(
title = {
AnimatedVisibility(
visible = isCenterTitle != null,
enter = fadeIn(),
// No animation required as it is erased with alpha
exit = ExitTransition.None,
) {
Text(
text = title,
modifier = Modifier.then(
when (isCenterTitle) {
true -> {
Modifier
.padding(end = navigationIconWidthDp.dp)
.fillMaxWidth()
}
false -> Modifier
null -> Modifier.alpha(0f)
},
),
textAlign = TextAlign.Center,
)
}
},
modifier = modifier,
navigationIcon = {
IconButton(
modifier = Modifier
.onGloballyPositioned {
navigationIconWidthDp = it.size.width / density
},
onClick = onBackClick,
) {
Icon(
imageVector = Filled.ArrowBack,
contentDescription = navIconContentDescription,
)
}
},
actions = actions,
windowInsets = windowInsets,
colors = colors,
scrollBehavior = scrollBehavior,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@ package io.github.droidkaigi.confsched.testing.robot

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.hasTestTag
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performScrollToNode
import androidx.compose.ui.test.performTouchInput
import androidx.compose.ui.test.swipeUp
import io.github.droidkaigi.confsched.about.AboutScreen
import io.github.droidkaigi.confsched.about.AboutScreenLazyColumnTestTag
import io.github.droidkaigi.confsched.about.section.AboutCreditsContributorsItemTestTag
import io.github.droidkaigi.confsched.about.section.AboutCreditsSponsorsItemTestTag
import io.github.droidkaigi.confsched.about.section.AboutCreditsStaffItemTestTag
import io.github.droidkaigi.confsched.about.section.AboutCreditsTitleTestTag
import io.github.droidkaigi.confsched.about.section.AboutDetailTestTag
import io.github.droidkaigi.confsched.about.section.AboutFooterLinksTestTag
import io.github.droidkaigi.confsched.about.section.AboutOthersCodeOfConductItemTestTag
import io.github.droidkaigi.confsched.about.section.AboutOthersLicenseItemTestTag
import io.github.droidkaigi.confsched.about.section.AboutOthersPrivacyPolicyItemTestTag
import io.github.droidkaigi.confsched.about.section.AboutOthersSettingsItemTestTag
import io.github.droidkaigi.confsched.about.section.AboutOthersTitleTestTag
import io.github.droidkaigi.confsched.designsystem.theme.KaigiTheme
import javax.inject.Inject
Expand All @@ -24,6 +36,25 @@ class AboutScreenRobot @Inject constructor(
waitUntilIdle()
}

fun scrollToCreditsSection() {
composeTestRule
.onNode(hasTestTag(AboutScreenLazyColumnTestTag))
.performScrollToNode(hasTestTag(AboutCreditsStaffItemTestTag))

// FIXME Without this, you won't be able to scroll to the exact middle of the credits section.
composeTestRule.onRoot().performTouchInput {
swipeUp(startY = centerY, endY = centerY - 200)
}
waitUntilIdle()
}

fun scrollToOthersSection() {
composeTestRule
.onNode(hasTestTag(AboutScreenLazyColumnTestTag))
.performScrollToNode(hasTestTag(AboutOthersTitleTestTag))
waitUntilIdle()
}

fun checkDetailSectionDisplayed() {
composeTestRule
.onNode(hasTestTag(AboutDetailTestTag))
Expand All @@ -36,12 +67,52 @@ class AboutScreenRobot @Inject constructor(
.assertIsDisplayed()
}

fun checkCreditsSectionContentsDisplayed() {
composeTestRule
.onNode(hasTestTag(AboutCreditsContributorsItemTestTag))
.assertExists()
.assertIsDisplayed()

composeTestRule
.onNode(hasTestTag(AboutCreditsStaffItemTestTag))
.assertExists()
.assertIsDisplayed()

composeTestRule
.onNode(hasTestTag(AboutCreditsSponsorsItemTestTag))
.assertExists()
.assertIsDisplayed()
}

fun checkOthersSectionTitleDisplayed() {
composeTestRule
.onNode(hasTestTag(AboutOthersTitleTestTag))
.assertIsDisplayed()
}

fun checkOthersSectionContentsDisplayed() {
composeTestRule
.onNode(hasTestTag(AboutOthersCodeOfConductItemTestTag))
.assertExists()
.assertIsDisplayed()

composeTestRule
.onNode(hasTestTag(AboutOthersLicenseItemTestTag))
.assertExists()
.assertIsDisplayed()

composeTestRule
.onNode(hasTestTag(AboutOthersPrivacyPolicyItemTestTag))
.assertExists()
.assertIsDisplayed()

composeTestRule
.onNode(hasTestTag(AboutOthersSettingsItemTestTag))
.assertExists()
.assertIsDisplayed()
}

// TODO https://github.com/DroidKaigi/conference-app-2024/issues/670
fun checkFooterLinksSectionDisplayed() {
composeTestRule
.onNode(hasTestTag(AboutFooterLinksTestTag))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ class SponsorsScreenRobot @Inject constructor(
)
}

fun scrollBottom() {
composeTestRule
.onNode(hasTestTag(SponsorsListLazyVerticalGridTestTag))
.performScrollToNode(
hasTestTag(SponsorsListSponsorItemTestTagPrefix.plus(Sponsor.fakes().last().name)),
)
}

fun checkDisplayPlatinumSponsors() {
checkSponsorItemsDisplayedByRangeAndSponsorType(
sponsorType = SponsorType.Platinum,
Expand All @@ -92,7 +100,8 @@ class SponsorsScreenRobot @Inject constructor(
sponsorType: SponsorType,
fromTo: IntRange,
) {
val sponsorList = Sponsor.fakes().filter { it.plan.toSponsorType() == sponsorType }.subList(fromTo.first, fromTo.last)
val sponsorList = Sponsor.fakes().filter { it.plan.toSponsorType() == sponsorType }
.subList(fromTo.first, fromTo.last)
sponsorList.forEach { sponsor ->
composeTestRule
.onNode(hasTestTag(SponsorsListSponsorItemTestTagPrefix.plus(sponsor.name)))
Expand Down
Loading

0 comments on commit b2e607b

Please sign in to comment.