Setup LottieFileItem

This commit is contained in:
2021-09-04 17:58:34 +02:00
parent 88e6a3596c
commit d60df4e5ff
20 changed files with 574 additions and 61 deletions
+2
View File
@@ -117,6 +117,8 @@ dependencies {
implementation(Libs.ksp_api) implementation(Libs.ksp_api)
implementation(Libs.lottie_compose)
implementation(Libs.orbit_mvi_core) implementation(Libs.orbit_mvi_core)
implementation(Libs.orbit_mvi_viewmodel) implementation(Libs.orbit_mvi_viewmodel)
testImplementation(Libs.orbit_mvi_test) testImplementation(Libs.orbit_mvi_test)
+2
View File
@@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="com.ericampire.android.androidstudycase"> package="com.ericampire.android.androidstudycase">
<uses-permission android:name="android.permission.INTERNET" />
<queries> <queries>
<intent> <intent>
@@ -10,10 +10,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import com.ericampire.android.androidstudycase.presentation.screen.main.ui.MainScreen import com.ericampire.android.androidstudycase.presentation.screen.main.ui.MainScreen
import com.ericampire.android.androidstudycase.presentation.theme.AndroidStudyCaseTheme import com.ericampire.android.androidstudycase.presentation.theme.AndroidStudyCaseTheme
import com.google.accompanist.pager.ExperimentalPagerApi
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint @AndroidEntryPoint
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
@ExperimentalPagerApi
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContent { setContent {
@@ -9,6 +9,7 @@ import com.ericampire.android.androidstudycase.presentation.screen.home.business
import com.ericampire.android.androidstudycase.presentation.screen.home.ui.HomeScreen import com.ericampire.android.androidstudycase.presentation.screen.home.ui.HomeScreen
import com.ericampire.android.androidstudycase.presentation.screen.preview.ui.PreviewScreen import com.ericampire.android.androidstudycase.presentation.screen.preview.ui.PreviewScreen
import com.ericampire.android.androidstudycase.util.Destination import com.ericampire.android.androidstudycase.util.Destination
import com.google.accompanist.pager.ExperimentalPagerApi
fun NavGraphBuilder.addHomeScreen(navController: NavController) { fun NavGraphBuilder.addHomeScreen(navController: NavController) {
composable(Destination.Home.route) { composable(Destination.Home.route) {
@@ -19,6 +20,7 @@ fun NavGraphBuilder.addHomeScreen(navController: NavController) {
} }
} }
@ExperimentalPagerApi
fun NavGraphBuilder.addExploreScreen(navController: NavController) { fun NavGraphBuilder.addExploreScreen(navController: NavController) {
composable(Destination.Explore.route) { composable(Destination.Explore.route) {
ExploreScreen( ExploreScreen(
@@ -0,0 +1,25 @@
package com.ericampire.android.androidstudycase.presentation.custom
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
import com.google.accompanist.glide.rememberGlidePainter
import com.ericampire.android.androidstudycase.R
@Composable
fun CustomImageView(
modifier: Modifier = Modifier,
data: String,
) {
Image(
modifier = modifier,
painter = rememberGlidePainter(
request = data,
fadeIn = true
),
contentScale = ContentScale.Crop,
contentDescription = null,
)
}
@@ -0,0 +1,40 @@
package com.ericampire.android.androidstudycase.presentation.custom
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material.MaterialTheme
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.ericampire.android.androidstudycase.R
@Composable
fun TopActionBar(modifier: Modifier = Modifier) {
TopAppBar(
elevation = 0.dp,
modifier = modifier,
backgroundColor = Color.Transparent,
title = {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
content = {
Image(
modifier = Modifier.height(23.dp),
painter = painterResource(id = R.drawable.ic_lottiefiles_logo),
contentDescription = stringResource(id = R.string.txt_lottie_logo)
)
}
)
},
)
}
@@ -4,4 +4,5 @@ sealed interface ExploreEffect {
data class ShowErrorMessage(val message: String) : ExploreEffect data class ShowErrorMessage(val message: String) : ExploreEffect
object Loading : ExploreEffect object Loading : ExploreEffect
object Success : ExploreEffect object Success : ExploreEffect
object Idle : ExploreEffect
} }
@@ -1,13 +1,136 @@
package com.ericampire.android.androidstudycase.presentation.screen.explore.ui package com.ericampire.android.androidstudycase.presentation.screen.explore.ui
import androidx.compose.runtime.Composable import androidx.compose.animation.Crossfade
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.ericampire.android.androidstudycase.R
import com.ericampire.android.androidstudycase.presentation.custom.TopActionBar
import com.ericampire.android.androidstudycase.presentation.screen.explore.business.ExploreAction
import com.ericampire.android.androidstudycase.presentation.screen.explore.business.ExploreEffect
import com.ericampire.android.androidstudycase.presentation.screen.explore.business.ExploreViewModel import com.ericampire.android.androidstudycase.presentation.screen.explore.business.ExploreViewModel
import com.ericampire.android.androidstudycase.presentation.theme.AppColor
import com.google.accompanist.insets.navigationBarsPadding
import com.google.accompanist.insets.statusBarsPadding
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.pagerTabIndicatorOffset
import com.google.accompanist.pager.rememberPagerState
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import timber.log.Timber
@ExperimentalPagerApi
@Composable @Composable
fun ExploreScreen( fun ExploreScreen(
navController: NavController, navController: NavController,
viewModel: ExploreViewModel viewModel: ExploreViewModel
) { ) {
val effects by viewModel.container.sideEffectFlow.collectAsState(ExploreEffect.Idle)
val state by viewModel.container.stateFlow.collectAsState()
val tabItems = stringArrayResource(id = R.array.explore_item)
val pagerState = rememberPagerState(pageCount = tabItems.size)
val coroutineScope = rememberCoroutineScope()
LaunchedEffect(viewModel) {
viewModel.submitAction(ExploreAction.FindRecentFile)
}
LaunchedEffect(viewModel) {
snapshotFlow { pagerState.currentPage }.collect { page ->
when (page) {
0 -> viewModel.submitAction(ExploreAction.FindRecentFile)
1 -> viewModel.submitAction(ExploreAction.FindFeaturedFile)
else -> viewModel.submitAction(ExploreAction.FindPopularFile)
}
}
}
Scaffold(
topBar = {
Column(
modifier = Modifier.fillMaxWidth().background(color = AppColor.Black001),
content = {
TopActionBar()
TabRow(
modifier = Modifier.fillMaxWidth(),
selectedTabIndex = pagerState.currentPage,
backgroundColor = Color.Transparent,
indicator = { tabPositions ->
TabRowDefaults.Indicator(
modifier = Modifier
.pagerTabIndicatorOffset(pagerState, tabPositions)
.padding(horizontal = 32.dp)
.clip(RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)),
height = 3.dp,
color = MaterialTheme.colors.primary
)
},
tabs = {
tabItems.forEachIndexed { index, title ->
Tab(
selected = index == pagerState.currentPage,
selectedContentColor = MaterialTheme.colors.primary,
unselectedContentColor = Color.White,
onClick = {
coroutineScope.launch {
pagerState.animateScrollToPage(index)
}
},
content = {
Text(
modifier = Modifier.padding(vertical = 12.dp),
text = title,
style = MaterialTheme.typography.h6.copy(
fontWeight = FontWeight.Normal
),
textAlign = TextAlign.Center,
)
}
)
}
}
)
}
)
},
content = { contentPadding ->
Crossfade(modifier = Modifier.padding(contentPadding), targetState = effects) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
content = {
when(it) {
ExploreEffect.Idle -> {
Timber.e("Idel")
}
ExploreEffect.Loading -> {
}
is ExploreEffect.ShowErrorMessage -> {
}
ExploreEffect.Success -> {
val data = state.files
Timber.e(data.toString())
}
}
}
)
}
}
)
} }
@@ -0,0 +1,201 @@
package com.ericampire.android.androidstudycase.presentation.screen.explore.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
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.unit.dp
import com.airbnb.lottie.compose.*
import com.ericampire.android.androidstudycase.domain.entity.Lottiefile
import com.ericampire.android.androidstudycase.presentation.custom.CustomImageView
import com.ericampire.android.androidstudycase.presentation.theme.AndroidStudyCaseTheme
import com.ericampire.android.androidstudycase.presentation.theme.AppColor
import com.ericampire.android.androidstudycase.util.LottieFileProvider
@ExperimentalMaterialApi
@Composable
fun LottieFileItemView(
modifier: Modifier = Modifier,
lottiefile: Lottiefile,
onClick: (Lottiefile) -> Unit
) {
Card(
modifier = modifier,
elevation = 0.dp,
onClick = { onClick(lottiefile) },
shape = MaterialTheme.shapes.large.copy(all = CornerSize(0.dp)),
content = {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
content = {
Row(
modifier = Modifier
.background(AppColor.Black001)
.padding(12.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically,
content = {
CustomImageView(
modifier = Modifier
.size(44.dp)
.clip(CircleShape),
data = lottiefile.createdBy?.avatarUrl ?: "null",
)
Column(
verticalArrangement = Arrangement.spacedBy(4.dp),
content = {
Text(
text = lottiefile.name,
style = MaterialTheme.typography.h6,
textAlign = TextAlign.Center,
)
Text(
text = lottiefile.createdBy?.name ?: "",
style = MaterialTheme.typography.caption,
textAlign = TextAlign.Center,
)
}
)
}
)
LottieFileContentView(lottiefile = lottiefile)
ActionButton(
onLikeClick = { /*TODO*/ },
onCommentClick = { /*TODO*/ },
onAddCollectionClick = { /*TODO*/ },
onShareClick = { }
)
}
)
}
)
}
@Composable
fun LottieFileContentView(
modifier: Modifier = Modifier,
lottiefile: Lottiefile
) {
val composition by rememberLottieComposition(
spec = LottieCompositionSpec.Url(lottiefile.lottieUrl)
)
val progress by animateLottieCompositionAsState(
composition = composition,
iterations = LottieConstants.IterateForever,
)
Box(
modifier = modifier.background(Color.White),
content = {
LottieAnimation(
modifier = Modifier
.fillMaxWidth()
.height(400.dp),
composition = composition,
progress = progress,
)
}
)
}
@Composable
private fun ActionButton(
modifier: Modifier = Modifier,
onLikeClick: () -> Unit,
onCommentClick: () -> Unit,
onAddCollectionClick: () -> Unit,
onShareClick: () -> Unit,
) {
Row(
modifier = modifier
.background(AppColor.Black001)
.padding(12.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
content = {
Row(
horizontalArrangement = Arrangement.spacedBy(20.dp),
verticalAlignment = Alignment.CenterVertically,
content = {
IconButton(
modifier = Modifier.size(20.dp),
onClick = onLikeClick,
content = {
Icon(
imageVector = Icons.Rounded.Favorite,
contentDescription = null
)
}
)
IconButton(
modifier = Modifier.size(20.dp),
onClick = onCommentClick,
content = {
Icon(
imageVector = Icons.Rounded.ChatBubble,
contentDescription = null
)
}
)
IconButton(
modifier = Modifier.size(20.dp),
onClick = onAddCollectionClick,
content = {
Icon(
imageVector = Icons.Rounded.CreateNewFolder,
contentDescription = null
)
}
)
}
)
IconButton(
modifier = Modifier.size(20.dp),
onClick = onShareClick,
content = {
Icon(
imageVector = Icons.Rounded.Share,
contentDescription = null
)
}
)
}
)
}
@ExperimentalMaterialApi
@Preview()
@Composable
fun LottiefileItemViewPreview(@PreviewParameter(LottieFileProvider::class) data: Lottiefile) {
AndroidStudyCaseTheme(darkTheme = true) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center,
content = {
LottieFileItemView(
lottiefile = data,
onClick = {}
)
}
)
}
}
@@ -8,9 +8,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material.* import androidx.compose.material.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Explore import androidx.compose.material.icons.rounded.*
import androidx.compose.material.icons.rounded.Home
import androidx.compose.material.icons.rounded.Scanner
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
@@ -24,7 +22,11 @@ import com.ericampire.android.androidstudycase.app.addExploreScreen
import com.ericampire.android.androidstudycase.app.addHomeScreen import com.ericampire.android.androidstudycase.app.addHomeScreen
import com.ericampire.android.androidstudycase.app.addPreviewScreen import com.ericampire.android.androidstudycase.app.addPreviewScreen
import com.ericampire.android.androidstudycase.util.Destination import com.ericampire.android.androidstudycase.util.Destination
import com.google.accompanist.insets.navigationBarsPadding
import com.google.accompanist.insets.statusBarsPadding
import com.google.accompanist.pager.ExperimentalPagerApi
@ExperimentalPagerApi
@Composable @Composable
fun MainScreen() { fun MainScreen() {
val navController = rememberNavController() val navController = rememberNavController()
@@ -36,6 +38,7 @@ fun MainScreen() {
) )
Scaffold( Scaffold(
modifier = Modifier.statusBarsPadding().navigationBarsPadding(),
bottomBar = { bottomBar = {
BottomNavigation( BottomNavigation(
backgroundColor = MaterialTheme.colors.background, backgroundColor = MaterialTheme.colors.background,
@@ -85,8 +88,8 @@ fun MainScreen() {
fun getIconByIndex(index: Int): ImageVector { fun getIconByIndex(index: Int): ImageVector {
return when (index) { return when (index) {
0 -> Icons.Rounded.Home 0 -> Icons.Rounded.Home
1 -> Icons.Rounded.Scanner 1 -> Icons.Rounded.QrCodeScanner
2 -> Icons.Rounded.Explore 2 -> Icons.Rounded.Escalator
else -> Icons.Rounded.Home else -> Icons.Rounded.Home
} }
} }
@@ -5,8 +5,9 @@ import androidx.compose.ui.graphics.Color
object AppColor { object AppColor {
val Purple200 = Color(0xFFBB86FC) val PrimaryColor = Color(0xFF2BEAED)
val Purple500 = Color(0xFF6200EE) val PrimaryColorDark = Color(0xFF006B78)
val Purple700 = Color(0xFF3700B3) val Purple700 = Color(0xFF3700B3)
val Teal200 = Color(0xFF03DAC5) val Teal200 = Color(0xFF03DAC5)
val Black001 = Color(0xFF222222)
} }
@@ -9,7 +9,7 @@ import androidx.compose.ui.graphics.Color
import com.google.accompanist.insets.ProvideWindowInsets import com.google.accompanist.insets.ProvideWindowInsets
private val DarkColorPalette = darkColors( private val DarkColorPalette = darkColors(
primary = AppColor.Purple200, primary = AppColor.PrimaryColor,
primaryVariant = AppColor.Purple700, primaryVariant = AppColor.Purple700,
secondary = AppColor.Teal200, secondary = AppColor.Teal200,
background = Color.Black, background = Color.Black,
@@ -21,7 +21,7 @@ private val DarkColorPalette = darkColors(
) )
private val LightColorPalette = lightColors( private val LightColorPalette = lightColors(
primary = AppColor.Purple500, primary = AppColor.PrimaryColorDark,
primaryVariant = AppColor.Purple700, primaryVariant = AppColor.Purple700,
secondary = AppColor.Teal200, secondary = AppColor.Teal200,
background = Color.White, background = Color.White,
@@ -0,0 +1,97 @@
package com.ericampire.android.androidstudycase.util
import com.ericampire.android.androidstudycase.domain.entity.Animator
import com.ericampire.android.androidstudycase.domain.entity.Blog
import com.ericampire.android.androidstudycase.domain.entity.Lottiefile
object PreviewData {
object Blog {
val data = listOf(
Blog(
postedAt = "2021-07-08T00:00:00.000Z",
imageUrl = "https://d3jl769oy69y7b.cloudfront.net/2021/07/Blog-Visual---The-Key-to-An-Immersive-UX_-Animation.png",
title = "The Key to An Immersive UX: Animation"
),
Blog(
title = "LottieFiles Animations are accessible across 25,000+ everyday tools with the embed feature",
postedAt = "2021-06-18T00:00:00.000Z",
imageUrl = "https://d3jl769oy69y7b.cloudfront.net/2021/06/Embed-Blog-OG.png"
),
Blog(
postedAt = "2021-07-08T00:00:00.000Z",
imageUrl = "https://d3jl769oy69y7b.cloudfront.net/2021/07/Blog-Visual---The-Key-to-An-Immersive-UX_-Animation.png",
title = "The Key to An Immersive UX: Animation"
),
Blog(
title = "LottieFiles Animations are accessible across 25,000+ everyday tools with the embed feature",
postedAt = "2021-06-18T00:00:00.000Z",
imageUrl = "https://d3jl769oy69y7b.cloudfront.net/2021/06/Embed-Blog-OG.png"
),
)
}
object Lottiefile {
val data = listOf(
Lottiefile(
id = 1370,
bgColor = "#ffffff",
lottieUrl = "https://assets4.lottiefiles.com/datafiles/U1I3rWEyksM9cCH/data.json",
gifUrl = "https://assets3.lottiefiles.com/render/julivspr.gif",
videoUrl = "https://assets3.lottiefiles.com/render/julivspr.mp4",
imageUrl = "https://assets8.lottiefiles.com/render/julivspr.png",
createdAt = "2018-02-02T15:53:12.000Z",
name = "confetti",
createdBy = PreviewData.Animator.data.first()
),
Lottiefile(
id = 427,
bgColor = "#ffffff",
lottieUrl = "https://assets8.lottiefiles.com/datafiles/zc3XRzudyWE36ZBJr7PIkkqq0PFIrIBgp4ojqShI/newAnimation.json",
gifUrl = "https://assets10.lottiefiles.com/render/juml9ngj.gif",
videoUrl = "https://assets10.lottiefiles.com/render/juml9ngj.mp4",
imageUrl = "https://assets4.lottiefiles.com/render/juml9ngj.png",
createdAt = "2017-07-28T14:25:49.000Z",
name = "Happy Birthday!",
createdBy = PreviewData.Animator.data[1]
),
Lottiefile(
id = 782,
bgColor = "#ffffff",
lottieUrl = "https://assets5.lottiefiles.com/datafiles/8UjWgBkqvEF5jNoFcXV4sdJ6PXpS6DwF7cK4tzpi/Check Mark Success/Check Mark Success Data.json",
gifUrl = "https://assets2.lottiefiles.com/render/jum1r6it.gif",
videoUrl = "https://assets2.lottiefiles.com/render/jum1r6it.mp4",
imageUrl = "https://assets1.lottiefiles.com/render/jum1r6it.png",
createdAt = "2017-10-04T18:16:21.000Z",
name = "Check Mark - Success",
createdBy = PreviewData.Animator.data[2]
),
)
}
object Animator {
val data = listOf(
Animator(
name = "Kevin Correa",
avatarUrl = "https://assets4.lottiefiles.com/avatars/300_60abcb0579641.jpg"
),
Animator(
name = "Alexander Plaksin",
avatarUrl = "https://assets5.lottiefiles.com/avatars/300_487756-994436705.jpg"
),
Animator(
name = "Vanessa Urrunaga",
avatarUrl = "https://assets2.lottiefiles.com/avatars/300_60df0a5dbd4f5.jpg"
),
Animator(
name = "Kevin Correa",
avatarUrl = "https://assets4.lottiefiles.com/avatars/300_60abcb0579641.jpg"
),
Animator(
name = "Alexander Plaksin",
avatarUrl = "https://assets5.lottiefiles.com/avatars/300_487756-994436705.jpg"
),
Animator(
name = "Vanessa Urrunaga",
avatarUrl = "https://assets2.lottiefiles.com/avatars/300_60df0a5dbd4f5.jpg"
),
)
}
}
@@ -0,0 +1,24 @@
package com.ericampire.android.androidstudycase.util
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.ericampire.android.androidstudycase.domain.entity.Animator
import com.ericampire.android.androidstudycase.domain.entity.Blog
import com.ericampire.android.androidstudycase.domain.entity.Lottiefile
class BlogProvider : PreviewParameterProvider<Blog> {
override val values: Sequence<Blog>
get() = PreviewData.Blog.data.asSequence()
}
class AnimatorProvider : PreviewParameterProvider<Animator> {
override val values: Sequence<Animator>
get() = PreviewData.Animator.data.asSequence()
}
class LottieFileProvider : PreviewParameterProvider<Lottiefile> {
override val values: Sequence<Lottiefile>
get() = PreviewData.Lottiefile.data.asSequence()
}
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="216dp"
android:height="44dp"
android:viewportWidth="216"
android:viewportHeight="44">
<path
android:pathData="M3.252,0A3.252,3.252 0,0 0,0 3.252v37.496A3.252,3.252 0,0 0,3.252 44h36.887a3.252,3.252 0,0 0,3.252 -3.252V3.252A3.252,3.252 0,0 0,40.139 0H3.252zM34.9,11.165c0.176,-1.208 -0.646,-2.33 -1.837,-2.509 -4.495,-0.674 -8.754,3.376 -13.297,12.148 -3.567,6.888 -6.775,10.35 -8.96,10.186 -1.2,-0.09 -2.245,0.824 -2.334,2.04 -0.088,1.217 0.813,2.277 2.013,2.367 4.423,0.331 8.625,-3.822 13.14,-12.539 3.535,-6.827 6.693,-10.147 8.801,-9.83 1.19,0.177 2.298,-0.656 2.474,-1.864z"
android:fillType="evenOdd">
<aapt:attr name="android:fillColor">
<gradient
android:startY="25.573"
android:startX="-13.485"
android:endY="52.389"
android:endX="28.352"
android:type="linear">
<item android:offset="0" android:color="#FF2BEAED"/>
<item android:offset="1" android:color="#FF0FCCCE"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M53.691,34.7L53.691,9.3h5.045v20.927h11.077v4.471L53.69,34.698zM81.031,35.021c-5.503,0 -9.172,-3.827 -9.172,-9.05 0,-5.223 3.669,-9.015 9.172,-9.015 5.362,0 9.137,3.65 9.137,9.015 0,5.33 -3.775,9.05 -9.137,9.05zM81.031,30.801c2.47,0 4.445,-1.968 4.445,-4.83s-1.905,-4.83 -4.445,-4.83c-2.681,0 -4.48,2.076 -4.48,4.83 0,2.719 1.834,4.83 4.48,4.83zM98.246,35.021c-2.963,0 -4.903,-1.896 -4.903,-5.83v-8.085h-2.047v-3.9h2.047L93.343,11.52l4.62,-0.5v6.188h4.657v3.899h-4.656v7.405c0,1.538 0.388,2.254 1.481,2.254 0.565,0 1.412,-0.215 2.188,-0.609l1.164,3.756c-1.094,0.609 -2.223,1.11 -4.55,1.11zM111.263,35.021c-2.963,0 -4.903,-1.896 -4.903,-5.83v-8.085h-2.046v-3.9h2.046L106.36,11.52l4.621,-0.5v6.188h4.656v3.899h-4.656v7.405c0,1.538 0.388,2.254 1.482,2.254 0.564,0 1.411,-0.215 2.187,-0.609l1.164,3.756c-1.094,0.609 -2.223,1.11 -4.551,1.11zM121.529,14.846c-1.694,0 -2.928,-1.288 -2.928,-2.898 0,-1.574 1.234,-2.862 2.928,-2.862 1.658,0 2.928,1.288 2.928,2.862 0,1.61 -1.27,2.898 -2.928,2.898zM119.165,34.699L119.165,17.207h4.621v17.492h-4.621zM143.577,25.792c0,0.572 -0.071,1.395 -0.106,1.681h-12.1c0.564,2.111 2.222,3.363 4.551,3.363 1.94,0 3.28,-0.823 4.198,-1.967l2.998,2.826c-1.446,1.895 -3.669,3.326 -7.514,3.326 -5.291,0 -9.031,-3.613 -9.031,-9.086 0,-5.33 3.634,-8.979 8.749,-8.979 4.868,0 8.255,3.72 8.255,8.836zM135.287,21.034c-1.87,0 -3.352,1.074 -3.881,3.077h7.585c-0.459,-1.86 -1.694,-3.077 -3.704,-3.077z"
android:fillColor="#18C8CA"
android:fillType="evenOdd"/>
<path
android:pathData="M175.75,34.7L175.75,8.37h4.621L180.371,34.7h-4.621zM169.717,14.846c-1.693,0 -2.928,-1.288 -2.928,-2.898 0,-1.574 1.235,-2.861 2.928,-2.861 1.658,0 2.928,1.287 2.928,2.861 0,1.61 -1.27,2.898 -2.928,2.898zM146.893,34.7L146.893,9.3h16.615v4.472h-11.711v6.797h9.771v4.507h-9.771L151.797,34.7h-4.904zM167.354,17.207v17.492h4.621L171.975,17.207h-4.621zM200.055,27.474a17.27,17.27 0,0 0,0.106 -1.682c0,-5.115 -3.386,-8.836 -8.255,-8.836 -5.115,0 -8.748,3.65 -8.748,8.98 0,5.473 3.739,9.086 9.031,9.086 3.845,0 6.067,-1.431 7.513,-3.327l-2.998,-2.826c-0.917,1.144 -2.258,1.967 -4.198,1.967 -2.328,0 -3.986,-1.252 -4.551,-3.362h12.1zM191.871,21.034c-1.87,0 -3.351,1.074 -3.88,3.077h7.584c-0.459,-1.86 -1.693,-3.076 -3.704,-3.076zM202.348,32.446c1.87,1.645 4.233,2.576 6.985,2.576 4.515,0 6.667,-2.361 6.667,-5.438 0,-3.47 -2.187,-4.293 -5.926,-5.688 -1.693,-0.644 -2.54,-1.145 -2.54,-1.86 0,-0.93 0.917,-1.288 1.623,-1.288 1.27,0 2.822,0.573 4.127,1.86l2.258,-3.47c-1.976,-1.538 -3.916,-2.182 -6.279,-2.182 -3.563,0 -6.245,2.04 -6.245,5.187 0,3.399 2.47,4.758 5.327,5.724 2.223,0.751 3.105,1.145 3.105,1.896 0,0.858 -0.741,1.43 -2.082,1.43 -1.905,0 -3.386,-0.679 -4.797,-2.002l-2.223,3.255z"
android:fillColor="#006B78"
android:fillType="evenOdd"/>
</vector>
-16
View File
@@ -1,16 +0,0 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.AndroidStudyCase" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>
+5 -3
View File
@@ -2,14 +2,16 @@
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="Theme.AndroidStudyCase" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> <style name="Theme.AndroidStudyCase" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. --> <!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item> <item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item> <item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item> <item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. --> <!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item> <item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item> <item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item> <item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. --> <!-- Status bar color. -->
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. --> <!-- Customize your theme here. -->
</style> </style>
+4 -32
View File
@@ -1,37 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string-array name="notification_tabs">
<item>Commandes</item>
<item>Tout</item>
</string-array>
<string-array name="notification_channel_names"> <string-array name="explore_item">
<item>Nouveau fournisseur</item> <item>Recent</item>
<item>Promotions</item> <item>Featured</item>
<item>Commandes</item> <item>Popular</item>
<item>Nouvelle mise à jour</item>
<item>Globale</item>
</string-array>
<string-array name="notification_channel_ids">
<item>stores</item>
<item>products</item>
<item>orders</item>
<item>global</item>
<item>default</item>
</string-array>
<string-array name="notification_channel_descriptions">
<item>Être notifié lorsqu\'un nouveau fournisseur est disponible sur Be Served.</item>
<item>Être notifié lorsqu\'il y a de nouvelles promotions.</item>
<item>Être notifié lorsque l\'état de votre commande change.</item>
<item>Être notifié lorsqu\'une nouvelle version de l\'application est disponible.</item>
<item>Autres notifications.</item>
</string-array>
<string-array name="history_items">
<item>En cours</item>
<item>Refusée</item>
<item>Historique</item>
</string-array> </string-array>
</resources> </resources>
+1
View File
@@ -8,4 +8,5 @@
<string name="txt_featured">Featured</string> <string name="txt_featured">Featured</string>
<string name="txt_recent">Recent</string> <string name="txt_recent">Recent</string>
<string name="txt_popular">Popular</string> <string name="txt_popular">Popular</string>
<string name="txt_lottie_logo">Lottie Logo</string>
</resources> </resources>
+1
View File
@@ -59,3 +59,4 @@ version.io.insert-koin..koin-android=3.1.2
version.io.insert-koin..koin-androidx-viewmodel=3.1.2 version.io.insert-koin..koin-androidx-viewmodel=3.1.2
version.io.insert-koin..koin-androidx-compose=3.1.2 version.io.insert-koin..koin-androidx-compose=3.1.2
version.io.insert-koin..koin-androidx-workmanager=3.1.2 version.io.insert-koin..koin-androidx-workmanager=3.1.2
version.com.airbnb.android..lottie-compose=4.1.0