Skip to content

Commit

Permalink
Merge pull request #38 from Nexters/feat/#37
Browse files Browse the repository at this point in the history
[feat] 작품 목록, 상세 화면 디테일 작업 #37
  • Loading branch information
easyhooon authored Feb 15, 2025
2 parents eca605f + ae02479 commit 82b4c0c
Show file tree
Hide file tree
Showing 15 changed files with 235 additions and 84 deletions.
9 changes: 6 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="${appName}"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Ziine"
android:usesCleartextTraffic="true"
tools:targetApi="31">

<provider
Expand All @@ -30,14 +30,17 @@
</provider>

<!-- Trigger Google Play services to install the backported photo picker module. -->
<service android:name="com.google.android.gms.metadata.ModuleDependencies"
<service
android:name="com.google.android.gms.metadata.ModuleDependencies"
android:enabled="false"
android:exported="false"
tools:ignore="MissingClass">
<intent-filter>
<action android:name="com.google.android.gms.metadata.MODULE_DEPENDENCIES" />
</intent-filter>
<meta-data android:name="photopicker_activity:0:required" android:value="" />
<meta-data
android:name="photopicker_activity:0:required"
android:value="" />
</service>

</application>
Expand Down
11 changes: 3 additions & 8 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ kotlinx-collections-immutable = "0.3.8"
agp = "8.7.3"
activity-compose = "1.10.0"
androidx-activity-ktx = "1.10.0"
androidx-compose-foundation = "1.8.0-alpha08"
androidx-lifecycle = "2.8.7"
androidx-navigation = "2.8.6"
androidx-core-splashscreen = "1.0.1"
Expand All @@ -30,7 +29,6 @@ androidx-hilt-navigation-compose = "1.2.0"
androidx-compose-material3 = "1.3.1"

# google
google-secrets = "2.0.1"
google-service = "4.4.2"
hilt = "2.55"
ksp = "2.1.0-1.0.29"
Expand All @@ -43,7 +41,6 @@ coil = "2.7.0"
compose-stable-marker = "1.0.4"
compose-extensions = "1.6.8"
landscapist = "2.3.6"
javax-inject = "1"
firebase-bom = "33.8.0"
firebase-crashlytics = "3.0.2"
lottie = "6.1.0"
Expand Down Expand Up @@ -97,10 +94,9 @@ okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
retrofit-kotlinx-serialization-converter = { group = "com.squareup.retrofit2", name = "converter-kotlinx-serialization", version.ref = "retrofit" }
okhttp-logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
coil-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" }
landscapist-bom = { group = "com.github.skydoves", name = "landscapist-bom", version.ref = "landscapist" }
landscapist-coil = { group = "com.github.skydoves", name = "landscapist-coil" }
landscapist-placeholder = { group = "com.github.skydoves", name = "landscapist-placeholder" }
landscapist-animation = { group = "com.github.skydoves", name = "landscapist-animation" }
landscapist-coil = { group = "com.github.skydoves", name = "landscapist-coil", version.ref = "landscapist" }
landscapist-placeholder = { group = "com.github.skydoves", name = "landscapist-placeholder", version.ref = "landscapist" }
landscapist-animation = { group = "com.github.skydoves", name = "landscapist-animation", version.ref = "landscapist" }
timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "timber" }
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebase-bom" }
firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics-ktx" }
Expand Down Expand Up @@ -128,7 +124,6 @@ compose = [
]

landscapist = [
"landscapist-bom",
"landscapist-coil",
"landscapist-placeholder",
"landscapist-animation",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fun ZiineApp(modifier: Modifier = Modifier) {
},
floatingActionButton = {
AnimatedVisibility(
visible = tabController.shouldShowTopBar(),
visible = tabController.shouldShowFloatingActionButton(),
enter = fadeIn(),
exit = fadeOut(),
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.AnimatedVisibilityScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionLayout
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
Expand All @@ -24,9 +25,11 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.nexters.ziine.android.presentation.LocalSharedTransitionScope
import com.nexters.ziine.android.presentation.R
import com.nexters.ziine.android.presentation.artworks.model.UiArtist
import com.nexters.ziine.android.presentation.artworks.model.UiArtwork
import com.nexters.ziine.android.presentation.component.NetworkImage
Expand All @@ -51,50 +54,73 @@ internal fun ArtworkItem(
with(sharedTransitionScope) {
Box(
modifier = modifier
.sharedElement(
rememberSharedContentState(key = artwork.artworkImageUrl),
animatedVisibilityScope = animatedVisibilityScope,
)
.fillMaxWidth()
.padding(horizontal = 16.dp)
.heightIn(max = 900.dp)
.clip(RoundedCornerShape(16.dp))
.border(
width = 1.5.dp,
color = Gray0.copy(alpha = 0.1f),
shape = RoundedCornerShape(16.dp),
)
.clickable(onClick = onArtworkItemSelect),
.padding(horizontal = 16.dp),
) {
NetworkImage(
imageUrl = artwork.artworkImageUrl,
contentDescription = "${artwork.title} by ${artwork.artist.name}",
modifier = Modifier
.fillMaxWidth(),
contentScale = ContentScale.FillWidth,
)

Row(
Box(
modifier = Modifier
.sharedElement(
rememberSharedContentState(key = artwork.artworkImageUrl),
animatedVisibilityScope = animatedVisibilityScope,
)
.fillMaxWidth()
.padding(top = 20.dp, start = 20.dp)
.align(Alignment.TopStart),
verticalAlignment = Alignment.CenterVertically,
.heightIn(max = 900.dp)
.clip(RoundedCornerShape(16.dp))
.border(
width = 1.5.dp,
color = Gray0.copy(alpha = 0.1f),
shape = RoundedCornerShape(16.dp),
)
.clickable(onClick = onArtworkItemSelect),
) {
NetworkImage(
imageUrl = artwork.artist.profileImageUrl,
contentDescription = "Profile Image of ${artwork.artist.name}",
imageUrl = artwork.artworkImageUrl,
contentDescription = "${artwork.title} by ${artwork.artist.name}",
modifier = Modifier
.size(28.dp)
.clip(CircleShape),
.fillMaxWidth(),
contentScale = ContentScale.FillWidth,
)
Spacer(modifier = Modifier.width(6.dp))
Text(
text = artwork.artist.name,
style = Paragraph2,
color = Gray0,
modifier = Modifier.weight(1f),

Image(
painter = painterResource(id = R.drawable.top_gradient),
contentDescription = "Top Gradient Image",
modifier = Modifier
.fillMaxWidth()
.align(Alignment.TopCenter),
contentScale = ContentScale.FillWidth,
)

Image(
painter = painterResource(id = R.drawable.bottom_gradient),
contentDescription = "Top Gradient Image",
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter),
contentScale = ContentScale.FillWidth,
)

Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 20.dp, start = 20.dp)
.align(Alignment.TopStart),
verticalAlignment = Alignment.CenterVertically,
) {
NetworkImage(
imageUrl = artwork.artist.profileImageUrl,
contentDescription = "Profile Image of ${artwork.artist.name}",
modifier = Modifier
.size(28.dp)
.clip(CircleShape),
)
Spacer(modifier = Modifier.width(6.dp))
Text(
text = artwork.artist.name,
style = Paragraph2,
color = Gray0,
modifier = Modifier.weight(1f),
)
}
}

Row(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,10 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.animateLottieCompositionAsState
import com.airbnb.lottie.compose.rememberLottieComposition
import com.nexters.ziine.android.presentation.R
import com.nexters.ziine.android.presentation.preview.ComponentPreview
import com.nexters.ziine.android.presentation.ui.theme.ZiineTheme
Expand All @@ -25,22 +20,16 @@ fun LoadingIndicator(
isLoading: Boolean,
modifier: Modifier = Modifier,
) {
val lottieComposition by rememberLottieComposition(LottieCompositionSpec.RawRes(resId = R.raw.loading))
val progress by animateLottieCompositionAsState(
composition = lottieComposition,
iterations = LottieConstants.IterateForever,
)

AnimatedVisibility(
visible = isLoading,
enter = fadeIn(),
exit = fadeOut(),
) {
Box(modifier = modifier.size(88.dp)) {
LottieAnimation(
composition = lottieComposition,
progress = { progress },
modifier = modifier.align(Alignment.Center)
LottieImage(
resId = R.raw.loading,
modifier = modifier.align(Alignment.Center),
iterations = LottieConstants.IterateForever,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.nexters.ziine.android.presentation.component

import androidx.annotation.RawRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.animateLottieCompositionAsState
import com.airbnb.lottie.compose.rememberLottieComposition

@Composable
fun LottieImage(
@RawRes resId: Int,
modifier: Modifier = Modifier,
iterations: Int = LottieConstants.IterateForever,
) {
val lottieComposition by rememberLottieComposition(LottieCompositionSpec.RawRes(resId = resId))
val progress by animateLottieCompositionAsState(
composition = lottieComposition,
iterations = iterations,
)

LottieAnimation(
composition = lottieComposition,
progress = { progress },
modifier = modifier,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import coil.request.ImageRequest
import com.nexters.ziine.android.presentation.R
import com.nexters.ziine.android.presentation.preview.ComponentPreview
import com.nexters.ziine.android.presentation.ui.theme.ZiineTheme
import timber.log.Timber

@Composable
fun NetworkImage(
Expand Down Expand Up @@ -64,6 +65,9 @@ fun NetworkImage(
modifier = modifier,
error = failureImage,
contentScale = contentScale,
onError = { exception ->
Timber.e("${exception.result.throwable}")
},
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import com.nexters.ziine.android.presentation.R
Expand Down Expand Up @@ -72,7 +73,7 @@ fun ZiineErrorDialog(
)
Spacer(modifier = Modifier.height(64.dp))
Image(
painter = painterResource(id = R.drawable.placeholder),
imageVector = ImageVector.vectorResource(id = R.drawable.error_image),
contentDescription = "Error Image",
modifier = Modifier
.fillMaxWidth()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,5 @@ class TabController(
}

@Composable
fun shouldShowFloatingActionButton() =
MainTab.contains {
currentDestination?.hasRoute(it::class) == true
}
fun shouldShowFloatingActionButton() = currentDestination?.hasRoute(MainTab.ARTWORKS.route::class) == true
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,17 @@ import androidx.activity.compose.LocalActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import com.nexters.ziine.android.presentation.MainActivity
import com.nexters.ziine.android.presentation.common.extensions.startActivityWithAnimation
import com.nexters.ziine.android.presentation.ui.theme.Primary500
import com.nexters.ziine.android.presentation.ui.theme.ZiineTheme
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import tech.thdev.compose.exteions.system.ui.controller.rememberExSystemUiController

@SuppressLint("CustomSplashScreen")
@AndroidEntryPoint
class SplashActivity : ComponentActivity() {
companion object {
private const val SPLASH_DURATION_MILLIS = 1300L
}

override fun onCreate(savedInstanceState: Bundle?) {
installSplashScreen()
super.onCreate(savedInstanceState)
Expand All @@ -42,16 +36,15 @@ class SplashActivity : ComponentActivity() {
onDispose {}
}

LaunchedEffect(key1 = Unit) {
delay(SPLASH_DURATION_MILLIS)
activity?.startActivityWithAnimation<MainActivity>(
withFinish = true,
intentBuilder = { this },
)
}

ZiineTheme {
SplashScreen()
SplashScreen(
onAnimationFinish = {
activity?.startActivityWithAnimation<MainActivity>(
withFinish = true,
intentBuilder = { this },
)
}
)
}
}
}
Expand Down
Loading

0 comments on commit 82b4c0c

Please sign in to comment.