refactor: rework cover's loading animation performance

Close #159
This commit is contained in:
Cuong-Tran 2024-07-22 10:30:04 +07:00 committed by Tran M. Cuong
parent c7bab00379
commit a67d63a4d8
7 changed files with 77 additions and 714 deletions

View file

@ -1,30 +1,33 @@
package eu.kanade.presentation.manga.components
import androidx.annotation.ColorInt
import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.size
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
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.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.semantics.Role
import coil3.compose.AsyncImage
import eu.kanade.presentation.util.rememberResourceBitmapPainter
import androidx.compose.ui.unit.dp
import coil3.compose.SubcomposeAsyncImage
import eu.kanade.tachiyomi.R
import kotlinx.coroutines.delay
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.asMangaCover
import tachiyomi.domain.manga.model.MangaCover as DomainMangaCover
@ -57,39 +60,74 @@ enum class MangaCover(val ratio: Float) {
// KMK <--
) {
// KMK -->
val coverErrorPainter = when (size) {
Size.Big -> rememberResourceBitmapPainter(id = R.drawable.cover_error_big, tint)
Size.Medium -> rememberResourceBitmapPainter(id = R.drawable.cover_error_medium, tint)
else -> rememberResourceBitmapPainter(id = R.drawable.cover_error, tint)
}
val animatedImageVector = when (size) {
Size.Big -> AnimatedImageVector.animatedVectorResource(R.drawable.anim_loading_big)
Size.Medium -> AnimatedImageVector.animatedVectorResource(R.drawable.anim_loading_medium)
else -> AnimatedImageVector.animatedVectorResource(R.drawable.anim_loading)
}
var atEnd by remember { mutableStateOf(false) }
suspend fun runAnimation() {
while (true) {
delay(LoadingAnimatedDuration)
atEnd = !atEnd
}
}
LaunchedEffect(animatedImageVector) {
runAnimation()
}
var succeed by remember { mutableStateOf(false) }
// KMK <--
AsyncImage(
val modifierColored = modifier
.aspectRatio(ratio)
.clip(shape)
// KMK -->
.alpha(if (succeed) alpha else 1f)
.background(bgColor ?: CoverPlaceholderColor)
// KMK <--
.then(
if (onClick != null) {
Modifier.clickable(
role = Role.Button,
onClick = onClick,
)
} else {
Modifier
},
)
SubcomposeAsyncImage(
model = data,
// KMK -->
// placeholder = ColorPainter(CoverPlaceholderColor),
placeholder = rememberAnimatedVectorPainter(animatedImageVector = animatedImageVector, atEnd = atEnd),
error = coverErrorPainter,
fallback = coverErrorPainter,
loading = {
Box(
modifier = modifierColored
) {
CircularProgressIndicator(
color = tint?.let { Color(it) } ?: CoverPlaceholderOnBgColor,
modifier = Modifier
.size(
when (size) {
Size.Big -> 16.dp
Size.Medium -> 24.dp
else -> 32.dp
}
)
.align(Alignment.Center),
strokeWidth = when (size) {
Size.Normal -> 3.dp
else -> 2.dp
},
)
}
},
error = {
Box(
modifier = modifierColored
) {
Image(
imageVector = ImageVector.vectorResource(R.drawable.cover_error_vector),
contentDescription = contentDescription,
modifier = Modifier
.size(
when (size) {
Size.Big -> 16.dp
Size.Medium -> 24.dp
else -> 32.dp
}
)
.align(Alignment.Center),
colorFilter = ColorFilter.tint(
tint?.let { Color(it) } ?: CoverPlaceholderOnBgColor
),
)
}
},
onSuccess = {
succeed = true
if (onCoverLoaded != null) {
@ -101,26 +139,11 @@ enum class MangaCover(val ratio: Float) {
},
// KMK <--
contentDescription = contentDescription,
modifier = modifier
.aspectRatio(ratio)
.clip(shape)
// KMK -->
.alpha(if (succeed) alpha else 1f)
.background(bgColor ?: Color.Transparent)
// KMK <--
.then(
if (onClick != null) {
Modifier.clickable(
role = Role.Button,
onClick = onClick,
)
} else {
Modifier
},
),
modifier = modifierColored,
contentScale = ContentScale.Crop,
)
}
}
const val LoadingAnimatedDuration = 600L
private val CoverPlaceholderColor = Color(0x1F888888)
private val CoverPlaceholderOnBgColor = Color(0x8F888888)

View file

@ -1,209 +0,0 @@
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:width="24dp"
android:height="24dp"
android:viewportWidth="4320"
android:viewportHeight="4320">
<group android:name="_SQ">
<path
android:fillAlpha="0.1"
android:fillColor="@color/cover_placeholder_loading"
android:pathData="M0,0h4320v4320H0z" />
</group>
<group android:name="_R_G"
android:translateX="1620"
android:translateY="1620">
<group android:name="_R_G_L_2_G">
<path
android:name="_R_G_L_2_G_D_0_P_0"
android:fillAlpha="1"
android:fillColor="@color/cover_placeholder_loading"
android:fillType="nonZero"
android:pathData=" M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c " />
</group>
<group android:name="_R_G_L_1_G">
<path
android:name="_R_G_L_1_G_D_0_P_0"
android:fillAlpha="1"
android:fillColor="@color/cover_placeholder_loading"
android:fillType="nonZero"
android:pathData=" M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c " />
</group>
<group android:name="_R_G_L_0_G">
<path
android:name="_R_G_L_0_G_D_0_P_0"
android:fillAlpha="1"
android:fillColor="@color/cover_placeholder_loading"
android:fillType="nonZero"
android:pathData=" M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c " />
</group>
</group>
<group android:name="time_group" />
</vector>
</aapt:attr>
<target android:name="_R_G_L_2_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="83"
android:propertyName="pathData"
android:startOffset="0"
android:valueFrom="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueTo="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="100"
android:propertyName="pathData"
android:startOffset="83"
android:valueFrom="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueTo="M272.31 322.51 C222.84,322.51 182.36,362.99 182.36,412.46 C182.36,461.93 222.84,502.41 272.31,502.41 C321.78,502.41 362.26,461.93 362.26,412.46 C362.26,362.99 321.78,322.51 272.31,322.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="133"
android:propertyName="pathData"
android:startOffset="183"
android:valueFrom="M272.31 322.51 C222.84,322.51 182.36,362.99 182.36,412.46 C182.36,461.93 222.84,502.41 272.31,502.41 C321.78,502.41 362.26,461.93 362.26,412.46 C362.26,362.99 321.78,322.51 272.31,322.51c "
android:valueTo="M270.46 486.51 C220.99,486.51 180.52,526.99 180.52,576.46 C180.52,625.93 220.99,666.41 270.46,666.41 C319.93,666.41 360.41,625.93 360.41,576.46 C360.41,526.99 319.93,486.51 270.46,486.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="67"
android:propertyName="pathData"
android:startOffset="317"
android:valueFrom="M270.46 486.51 C220.99,486.51 180.52,526.99 180.52,576.46 C180.52,625.93 220.99,666.41 270.46,666.41 C319.93,666.41 360.41,625.93 360.41,576.46 C360.41,526.99 319.93,486.51 270.46,486.51c "
android:valueTo="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_1_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="150"
android:propertyName="pathData"
android:startOffset="0"
android:valueFrom="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueTo="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="100"
android:propertyName="pathData"
android:startOffset="150"
android:valueFrom="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueTo="M542.16 322.51 C492.68,322.51 452.21,362.99 452.21,412.46 C452.21,461.93 492.68,502.41 542.16,502.41 C591.63,502.41 632.1,461.93 632.1,412.46 C632.1,362.99 591.63,322.51 542.16,322.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="133"
android:propertyName="pathData"
android:startOffset="250"
android:valueFrom="M542.16 322.51 C492.68,322.51 452.21,362.99 452.21,412.46 C452.21,461.93 492.68,502.41 542.16,502.41 C591.63,502.41 632.1,461.93 632.1,412.46 C632.1,362.99 591.63,322.51 542.16,322.51c "
android:valueTo="M540.31 486.51 C490.84,486.51 450.36,526.99 450.36,576.46 C450.36,625.93 490.84,666.41 540.31,666.41 C589.78,666.41 630.26,625.93 630.26,576.46 C630.26,526.99 589.78,486.51 540.31,486.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="67"
android:propertyName="pathData"
android:startOffset="383"
android:valueFrom="M540.31 486.51 C490.84,486.51 450.36,526.99 450.36,576.46 C450.36,625.93 490.84,666.41 540.31,666.41 C589.78,666.41 630.26,625.93 630.26,576.46 C630.26,526.99 589.78,486.51 540.31,486.51c "
android:valueTo="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_0_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="217"
android:propertyName="pathData"
android:startOffset="0"
android:valueFrom="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueTo="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="100"
android:propertyName="pathData"
android:startOffset="217"
android:valueFrom="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueTo="M812 322.51 C762.53,322.51 722.05,362.99 722.05,412.46 C722.05,461.93 762.53,502.41 812,502.41 C861.47,502.41 901.95,461.93 901.95,412.46 C901.95,362.99 861.47,322.51 812,322.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="133"
android:propertyName="pathData"
android:startOffset="317"
android:valueFrom="M812 322.51 C762.53,322.51 722.05,362.99 722.05,412.46 C722.05,461.93 762.53,502.41 812,502.41 C861.47,502.41 901.95,461.93 901.95,412.46 C901.95,362.99 861.47,322.51 812,322.51c "
android:valueTo="M810.16 486.51 C760.68,486.51 720.21,526.99 720.21,576.46 C720.21,625.93 760.68,666.41 810.16,666.41 C859.63,666.41 900.1,625.93 900.1,576.46 C900.1,526.99 859.63,486.51 810.16,486.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="67"
android:propertyName="pathData"
android:startOffset="450"
android:valueFrom="M810.16 486.51 C760.68,486.51 720.21,526.99 720.21,576.46 C720.21,625.93 760.68,666.41 810.16,666.41 C859.63,666.41 900.1,625.93 900.1,576.46 C900.1,526.99 859.63,486.51 810.16,486.51c "
android:valueTo="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="time_group">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="518"
android:propertyName="translateX"
android:startOffset="0"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
</animated-vector>

View file

@ -1,209 +0,0 @@
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:width="24dp"
android:height="24dp"
android:viewportWidth="1440"
android:viewportHeight="1440">
<group android:name="_SQ">
<path
android:fillAlpha="0.1"
android:fillColor="@color/cover_placeholder_loading"
android:pathData="M0,0h4320v4320H0z" />
</group>
<group android:name="_R_G"
android:translateX="180"
android:translateY="180">
<group android:name="_R_G_L_2_G">
<path
android:name="_R_G_L_2_G_D_0_P_0"
android:fillAlpha="1"
android:fillColor="@color/cover_placeholder_loading"
android:fillType="nonZero"
android:pathData=" M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c " />
</group>
<group android:name="_R_G_L_1_G">
<path
android:name="_R_G_L_1_G_D_0_P_0"
android:fillAlpha="1"
android:fillColor="@color/cover_placeholder_loading"
android:fillType="nonZero"
android:pathData=" M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c " />
</group>
<group android:name="_R_G_L_0_G">
<path
android:name="_R_G_L_0_G_D_0_P_0"
android:fillAlpha="1"
android:fillColor="@color/cover_placeholder_loading"
android:fillType="nonZero"
android:pathData=" M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c " />
</group>
</group>
<group android:name="time_group" />
</vector>
</aapt:attr>
<target android:name="_R_G_L_2_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="83"
android:propertyName="pathData"
android:startOffset="0"
android:valueFrom="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueTo="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="100"
android:propertyName="pathData"
android:startOffset="83"
android:valueFrom="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueTo="M272.31 322.51 C222.84,322.51 182.36,362.99 182.36,412.46 C182.36,461.93 222.84,502.41 272.31,502.41 C321.78,502.41 362.26,461.93 362.26,412.46 C362.26,362.99 321.78,322.51 272.31,322.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="133"
android:propertyName="pathData"
android:startOffset="183"
android:valueFrom="M272.31 322.51 C222.84,322.51 182.36,362.99 182.36,412.46 C182.36,461.93 222.84,502.41 272.31,502.41 C321.78,502.41 362.26,461.93 362.26,412.46 C362.26,362.99 321.78,322.51 272.31,322.51c "
android:valueTo="M270.46 486.51 C220.99,486.51 180.52,526.99 180.52,576.46 C180.52,625.93 220.99,666.41 270.46,666.41 C319.93,666.41 360.41,625.93 360.41,576.46 C360.41,526.99 319.93,486.51 270.46,486.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="67"
android:propertyName="pathData"
android:startOffset="317"
android:valueFrom="M270.46 486.51 C220.99,486.51 180.52,526.99 180.52,576.46 C180.52,625.93 220.99,666.41 270.46,666.41 C319.93,666.41 360.41,625.93 360.41,576.46 C360.41,526.99 319.93,486.51 270.46,486.51c "
android:valueTo="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_1_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="150"
android:propertyName="pathData"
android:startOffset="0"
android:valueFrom="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueTo="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="100"
android:propertyName="pathData"
android:startOffset="150"
android:valueFrom="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueTo="M542.16 322.51 C492.68,322.51 452.21,362.99 452.21,412.46 C452.21,461.93 492.68,502.41 542.16,502.41 C591.63,502.41 632.1,461.93 632.1,412.46 C632.1,362.99 591.63,322.51 542.16,322.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="133"
android:propertyName="pathData"
android:startOffset="250"
android:valueFrom="M542.16 322.51 C492.68,322.51 452.21,362.99 452.21,412.46 C452.21,461.93 492.68,502.41 542.16,502.41 C591.63,502.41 632.1,461.93 632.1,412.46 C632.1,362.99 591.63,322.51 542.16,322.51c "
android:valueTo="M540.31 486.51 C490.84,486.51 450.36,526.99 450.36,576.46 C450.36,625.93 490.84,666.41 540.31,666.41 C589.78,666.41 630.26,625.93 630.26,576.46 C630.26,526.99 589.78,486.51 540.31,486.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="67"
android:propertyName="pathData"
android:startOffset="383"
android:valueFrom="M540.31 486.51 C490.84,486.51 450.36,526.99 450.36,576.46 C450.36,625.93 490.84,666.41 540.31,666.41 C589.78,666.41 630.26,625.93 630.26,576.46 C630.26,526.99 589.78,486.51 540.31,486.51c "
android:valueTo="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_0_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="217"
android:propertyName="pathData"
android:startOffset="0"
android:valueFrom="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueTo="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="100"
android:propertyName="pathData"
android:startOffset="217"
android:valueFrom="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueTo="M812 322.51 C762.53,322.51 722.05,362.99 722.05,412.46 C722.05,461.93 762.53,502.41 812,502.41 C861.47,502.41 901.95,461.93 901.95,412.46 C901.95,362.99 861.47,322.51 812,322.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="133"
android:propertyName="pathData"
android:startOffset="317"
android:valueFrom="M812 322.51 C762.53,322.51 722.05,362.99 722.05,412.46 C722.05,461.93 762.53,502.41 812,502.41 C861.47,502.41 901.95,461.93 901.95,412.46 C901.95,362.99 861.47,322.51 812,322.51c "
android:valueTo="M810.16 486.51 C760.68,486.51 720.21,526.99 720.21,576.46 C720.21,625.93 760.68,666.41 810.16,666.41 C859.63,666.41 900.1,625.93 900.1,576.46 C900.1,526.99 859.63,486.51 810.16,486.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="67"
android:propertyName="pathData"
android:startOffset="450"
android:valueFrom="M810.16 486.51 C760.68,486.51 720.21,526.99 720.21,576.46 C720.21,625.93 760.68,666.41 810.16,666.41 C859.63,666.41 900.1,625.93 900.1,576.46 C900.1,526.99 859.63,486.51 810.16,486.51c "
android:valueTo="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="time_group">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="518"
android:propertyName="translateX"
android:startOffset="0"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
</animated-vector>

View file

@ -1,209 +0,0 @@
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:width="24dp"
android:height="24dp"
android:viewportWidth="2160"
android:viewportHeight="2160">
<group android:name="_SQ">
<path
android:fillAlpha="0.1"
android:fillColor="@color/cover_placeholder_loading"
android:pathData="M0,0h4320v4320H0z" />
</group>
<group android:name="_R_G"
android:translateX="540"
android:translateY="540">
<group android:name="_R_G_L_2_G">
<path
android:name="_R_G_L_2_G_D_0_P_0"
android:fillAlpha="1"
android:fillColor="@color/cover_placeholder_loading"
android:fillType="nonZero"
android:pathData=" M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c " />
</group>
<group android:name="_R_G_L_1_G">
<path
android:name="_R_G_L_1_G_D_0_P_0"
android:fillAlpha="1"
android:fillColor="@color/cover_placeholder_loading"
android:fillType="nonZero"
android:pathData=" M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c " />
</group>
<group android:name="_R_G_L_0_G">
<path
android:name="_R_G_L_0_G_D_0_P_0"
android:fillAlpha="1"
android:fillColor="@color/cover_placeholder_loading"
android:fillType="nonZero"
android:pathData=" M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c " />
</group>
</group>
<group android:name="time_group" />
</vector>
</aapt:attr>
<target android:name="_R_G_L_2_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="83"
android:propertyName="pathData"
android:startOffset="0"
android:valueFrom="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueTo="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="100"
android:propertyName="pathData"
android:startOffset="83"
android:valueFrom="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueTo="M272.31 322.51 C222.84,322.51 182.36,362.99 182.36,412.46 C182.36,461.93 222.84,502.41 272.31,502.41 C321.78,502.41 362.26,461.93 362.26,412.46 C362.26,362.99 321.78,322.51 272.31,322.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="133"
android:propertyName="pathData"
android:startOffset="183"
android:valueFrom="M272.31 322.51 C222.84,322.51 182.36,362.99 182.36,412.46 C182.36,461.93 222.84,502.41 272.31,502.41 C321.78,502.41 362.26,461.93 362.26,412.46 C362.26,362.99 321.78,322.51 272.31,322.51c "
android:valueTo="M270.46 486.51 C220.99,486.51 180.52,526.99 180.52,576.46 C180.52,625.93 220.99,666.41 270.46,666.41 C319.93,666.41 360.41,625.93 360.41,576.46 C360.41,526.99 319.93,486.51 270.46,486.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="67"
android:propertyName="pathData"
android:startOffset="317"
android:valueFrom="M270.46 486.51 C220.99,486.51 180.52,526.99 180.52,576.46 C180.52,625.93 220.99,666.41 270.46,666.41 C319.93,666.41 360.41,625.93 360.41,576.46 C360.41,526.99 319.93,486.51 270.46,486.51c "
android:valueTo="M270.46 450.51 C220.99,450.51 180.52,490.99 180.52,540.46 C180.52,589.93 220.99,630.41 270.46,630.41 C319.93,630.41 360.41,589.93 360.41,540.46 C360.41,490.99 319.93,450.51 270.46,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_1_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="150"
android:propertyName="pathData"
android:startOffset="0"
android:valueFrom="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueTo="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="100"
android:propertyName="pathData"
android:startOffset="150"
android:valueFrom="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueTo="M542.16 322.51 C492.68,322.51 452.21,362.99 452.21,412.46 C452.21,461.93 492.68,502.41 542.16,502.41 C591.63,502.41 632.1,461.93 632.1,412.46 C632.1,362.99 591.63,322.51 542.16,322.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="133"
android:propertyName="pathData"
android:startOffset="250"
android:valueFrom="M542.16 322.51 C492.68,322.51 452.21,362.99 452.21,412.46 C452.21,461.93 492.68,502.41 542.16,502.41 C591.63,502.41 632.1,461.93 632.1,412.46 C632.1,362.99 591.63,322.51 542.16,322.51c "
android:valueTo="M540.31 486.51 C490.84,486.51 450.36,526.99 450.36,576.46 C450.36,625.93 490.84,666.41 540.31,666.41 C589.78,666.41 630.26,625.93 630.26,576.46 C630.26,526.99 589.78,486.51 540.31,486.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="67"
android:propertyName="pathData"
android:startOffset="383"
android:valueFrom="M540.31 486.51 C490.84,486.51 450.36,526.99 450.36,576.46 C450.36,625.93 490.84,666.41 540.31,666.41 C589.78,666.41 630.26,625.93 630.26,576.46 C630.26,526.99 589.78,486.51 540.31,486.51c "
android:valueTo="M540.31 450.51 C490.84,450.51 450.36,490.99 450.36,540.46 C450.36,589.93 490.84,630.41 540.31,630.41 C589.78,630.41 630.26,589.93 630.26,540.46 C630.26,490.99 589.78,450.51 540.31,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="_R_G_L_0_G_D_0_P_0">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="217"
android:propertyName="pathData"
android:startOffset="0"
android:valueFrom="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueTo="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="100"
android:propertyName="pathData"
android:startOffset="217"
android:valueFrom="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueTo="M812 322.51 C762.53,322.51 722.05,362.99 722.05,412.46 C722.05,461.93 762.53,502.41 812,502.41 C861.47,502.41 901.95,461.93 901.95,412.46 C901.95,362.99 861.47,322.51 812,322.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="133"
android:propertyName="pathData"
android:startOffset="317"
android:valueFrom="M812 322.51 C762.53,322.51 722.05,362.99 722.05,412.46 C722.05,461.93 762.53,502.41 812,502.41 C861.47,502.41 901.95,461.93 901.95,412.46 C901.95,362.99 861.47,322.51 812,322.51c "
android:valueTo="M810.16 486.51 C760.68,486.51 720.21,526.99 720.21,576.46 C720.21,625.93 760.68,666.41 810.16,666.41 C859.63,666.41 900.1,625.93 900.1,576.46 C900.1,526.99 859.63,486.51 810.16,486.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
<objectAnimator
android:duration="67"
android:propertyName="pathData"
android:startOffset="450"
android:valueFrom="M810.16 486.51 C760.68,486.51 720.21,526.99 720.21,576.46 C720.21,625.93 760.68,666.41 810.16,666.41 C859.63,666.41 900.1,625.93 900.1,576.46 C900.1,526.99 859.63,486.51 810.16,486.51c "
android:valueTo="M810.16 450.51 C760.68,450.51 720.21,490.99 720.21,540.46 C720.21,589.93 760.68,630.41 810.16,630.41 C859.63,630.41 900.1,589.93 900.1,540.46 C900.1,490.99 859.63,450.51 810.16,450.51c "
android:valueType="pathType">
<aapt:attr name="android:interpolator">
<pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
</aapt:attr>
</objectAnimator>
</set>
</aapt:attr>
</target>
<target android:name="time_group">
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
android:duration="518"
android:propertyName="translateX"
android:startOffset="0"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" />
</set>
</aapt:attr>
</target>
</animated-vector>

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<item>
<color android:color="@color/cover_placeholder" />
</item>
<item
android:top="6dp"
android:bottom="6dp"
android:left="6dp"
android:right="6dp"
android:drawable="@drawable/cover_error_vector"
/>
</layer-list>

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<item>
<color android:color="@color/cover_placeholder" />
</item>
<item
android:top="24dp"
android:bottom="24dp"
android:left="24dp"
android:right="24dp"
android:drawable="@drawable/cover_error_vector"
/>
</layer-list>

View file

@ -2,8 +2,7 @@
<resources>
<color name="splash">#FBEDED</color>
<color name="cover_placeholder">#2F888888</color>
<color name="cover_placeholder_loading">#888888</color>
<color name="cover_placeholder">#4F888888</color>
<color name="error">#BA1B1B</color>
<color name="errorContainer">#FFDAD4</color>