mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-08 12:42:44 -05:00
add external ids (socials) to movies, tv, and people views
This commit is contained in:
@@ -25,4 +25,6 @@ interface DetailService {
|
||||
|
||||
suspend fun getWatchProviders(id: Int): Response<WatchProviderResponse>
|
||||
|
||||
suspend fun getExternalIds(id: Int): Response<ExternalIds>
|
||||
|
||||
}
|
||||
@@ -58,4 +58,7 @@ interface MoviesApi {
|
||||
@GET("movie/{id}/watch/providers")
|
||||
suspend fun getWatchProviders(@Path("id") id: Int): Response<WatchProviderResponse>
|
||||
|
||||
@GET("movie/{id}/external_ids")
|
||||
suspend fun getExternalIds(@Path("id") id: Int): Response<ExternalIds>
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.owenlejeune.tvtime.api.tmdb.api.v3
|
||||
import com.owenlejeune.tvtime.api.tmdb.TmdbClient
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.CastAndCrew
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailedItem
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ExternalIds
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePageResponse
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ImageCollection
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.KeywordsResponse
|
||||
@@ -82,4 +83,8 @@ class MoviesService: KoinComponent, DetailService, HomePageService {
|
||||
return movieService.getWatchProviders(id)
|
||||
}
|
||||
|
||||
override suspend fun getExternalIds(id: Int): Response<ExternalIds> {
|
||||
return movieService.getExternalIds(id)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.owenlejeune.tvtime.api.tmdb.api.v3
|
||||
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailPerson
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ExternalIds
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePagePeopleResponse
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonCreditsResponse
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonImageCollection
|
||||
@@ -32,4 +33,7 @@ interface PeopleApi {
|
||||
// @GET("persons/{id}/tagged_images")
|
||||
// suspend fun getTaggedImages(@Path("id") id: Int, @Query("page") page: Int = 1): Response<PersonImageCollection>
|
||||
|
||||
@GET("person/{id}/external_ids")
|
||||
suspend fun getExternalIds(@Path("id") id: Int): Response<ExternalIds>
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.owenlejeune.tvtime.api.tmdb.api.v3
|
||||
|
||||
import com.owenlejeune.tvtime.api.tmdb.TmdbClient
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailPerson
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ExternalIds
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePagePeopleResponse
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonCreditsResponse
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonImageCollection
|
||||
@@ -28,4 +29,8 @@ class PeopleService: KoinComponent {
|
||||
return service.getPopular(page)
|
||||
}
|
||||
|
||||
suspend fun getExternalIds(id: Int): Response<ExternalIds> {
|
||||
return service.getExternalIds(id)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -61,4 +61,7 @@ interface TvApi {
|
||||
@GET("tv/{id}/watch/providers")
|
||||
suspend fun getWatchProviders(@Path("id") seriesId: Int): Response<WatchProviderResponse>
|
||||
|
||||
@GET("tv/{id}/external_ids")
|
||||
suspend fun getExternalIds(@Path("id") id: Int): Response<ExternalIds>
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.owenlejeune.tvtime.api.tmdb.api.v3
|
||||
import com.owenlejeune.tvtime.api.tmdb.TmdbClient
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.CastAndCrew
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailedItem
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ExternalIds
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.HomePageResponse
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ImageCollection
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.KeywordsResponse
|
||||
@@ -87,4 +88,8 @@ class TvService: KoinComponent, DetailService, HomePageService {
|
||||
return service.getSeason(seriesId, seasonId)
|
||||
}
|
||||
|
||||
override suspend fun getExternalIds(id: Int): Response<ExternalIds> {
|
||||
return service.getExternalIds(id)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.owenlejeune.tvtime.api.tmdb.api.v3.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class ExternalIds(
|
||||
@SerializedName("facebook_id")
|
||||
val facebook: String?,
|
||||
@SerializedName("instagram_id")
|
||||
val instagram: String?,
|
||||
@SerializedName("tiktok_id")
|
||||
val tiktok: String?,
|
||||
@SerializedName("twitter_id")
|
||||
val twitter: String?,
|
||||
@SerializedName("youtube_id")
|
||||
val youtube: String?
|
||||
) {
|
||||
fun hasExternalIds(): Boolean = (facebook != null)
|
||||
.or(instagram != null)
|
||||
.or(tiktok != null)
|
||||
.or(twitter != null)
|
||||
.or(youtube != null)
|
||||
}
|
||||
@@ -1,18 +1,26 @@
|
||||
package com.owenlejeune.tvtime.ui.components
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
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.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@@ -24,6 +32,7 @@ import com.google.accompanist.pager.HorizontalPager
|
||||
import com.google.accompanist.pager.PagerState
|
||||
import com.google.accompanist.pager.rememberPagerState
|
||||
import com.owenlejeune.tvtime.R
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ExternalIds
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ImageCollection
|
||||
import com.owenlejeune.tvtime.ui.viewmodel.ConfigurationViewModel
|
||||
import com.owenlejeune.tvtime.utils.TmdbUtils
|
||||
@@ -220,4 +229,56 @@ fun RatingView(
|
||||
size = 50.dp
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ExternalIdsArea(
|
||||
externalIds: ExternalIds,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
if (externalIds.hasExternalIds()) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
externalIds.twitter?.let {
|
||||
ExternalIdLogo(url = "https://twitter.com/$it", logoPainter = painterResource(id = R.drawable.twitter_logo))
|
||||
}
|
||||
externalIds.facebook?.let {
|
||||
ExternalIdLogo(url = "https://facebook.com/$it", logoPainter = painterResource(id = R.drawable.facebook_logo))
|
||||
}
|
||||
externalIds.instagram?.let {
|
||||
ExternalIdLogo(url = "https://instagram.com/$it", logoPainter = painterResource(id = R.drawable.instagram_logo))
|
||||
}
|
||||
externalIds.tiktok?.let {
|
||||
ExternalIdLogo(url = "https://tiktok.com/@$it", logoPainter = painterResource(id = R.drawable.tiktok_logo))
|
||||
}
|
||||
externalIds.youtube?.let {
|
||||
ExternalIdLogo(url = "https://youtube.com/$it", logoPainter = painterResource(id = R.drawable.youtube_logo))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ExternalIdLogo(
|
||||
logoPainter: Painter,
|
||||
url: String,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
IconButton(
|
||||
onClick = {
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
context.startActivity(intent)
|
||||
},
|
||||
modifier = Modifier.size(28.dp)
|
||||
) {
|
||||
Icon(
|
||||
painter = logoPainter,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.secondary
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -619,40 +619,6 @@ fun HtmlText(text: String, modifier: Modifier = Modifier, color: Color = Color.U
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CircleBackgroundColorImage(
|
||||
size: Dp,
|
||||
backgroundColor: Color,
|
||||
painter: Painter,
|
||||
modifier: Modifier = Modifier,
|
||||
imageSize: DpSize? = null,
|
||||
imageAlignment: Alignment = Alignment.Center,
|
||||
contentDescription: String? = null,
|
||||
colorFilter: ColorFilter? = null
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.clip(CircleShape)
|
||||
.size(size)
|
||||
.background(color = backgroundColor)
|
||||
) {
|
||||
val mod = if (imageSize != null) {
|
||||
Modifier
|
||||
.align(imageAlignment)
|
||||
.size(size = imageSize)
|
||||
} else {
|
||||
Modifier.align(imageAlignment)
|
||||
}
|
||||
Image(
|
||||
contentDescription = contentDescription,
|
||||
modifier = mod,
|
||||
colorFilter = colorFilter,
|
||||
painter = painter,
|
||||
contentScale = ContentScale.FillBounds
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CircleBackgroundColorImage(
|
||||
size: Dp,
|
||||
@@ -1090,7 +1056,7 @@ fun SearchBar(
|
||||
placeHolder = stringResource(id = R.string.search_placeholder, placeholder),
|
||||
leadingIcon = {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.ic_search),
|
||||
imageVector = Icons.Filled.Search,
|
||||
contentDescription = stringResource(R.string.search_icon_content_descriptor),
|
||||
colorFilter = ColorFilter.tint(color = MaterialTheme.colorScheme.primary)
|
||||
)
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package com.owenlejeune.tvtime.ui.navigation
|
||||
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Face
|
||||
import androidx.compose.material.icons.outlined.Movie
|
||||
import androidx.compose.material.icons.outlined.Person
|
||||
import androidx.compose.material.icons.outlined.Tv
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
@@ -62,7 +68,7 @@ fun HomeScreenNavHost(
|
||||
|
||||
sealed class HomeScreenNavItem(
|
||||
stringRes: Int,
|
||||
val icon: Int,
|
||||
val icon: ImageVector,
|
||||
val route: String,
|
||||
private val orderGetter: (AppPreferences) -> Int,
|
||||
private val orderSetter: (AppPreferences, Int) -> Unit
|
||||
@@ -97,21 +103,21 @@ sealed class HomeScreenNavItem(
|
||||
|
||||
object Movies: HomeScreenNavItem(
|
||||
R.string.nav_movies_title,
|
||||
R.drawable.ic_movie,
|
||||
Icons.Outlined.Movie,
|
||||
"movies_route",
|
||||
{ it.moviesTabPosition },
|
||||
{ p, i -> p.moviesTabPosition = i }
|
||||
)
|
||||
object TV: HomeScreenNavItem(
|
||||
R.string.nav_tv_title,
|
||||
R.drawable.ic_tv,
|
||||
Icons.Outlined.Tv,
|
||||
"tv_route",
|
||||
{ it.tvTabPosition },
|
||||
{ p, i -> p.tvTabPosition = i }
|
||||
)
|
||||
object Account: HomeScreenNavItem(
|
||||
R.string.nav_account_title,
|
||||
R.drawable.ic_person,
|
||||
Icons.Outlined.Person,
|
||||
"account_route",
|
||||
{
|
||||
// if (SessionManager.currentSession.value?.isAuthorized == true) {
|
||||
@@ -124,7 +130,7 @@ sealed class HomeScreenNavItem(
|
||||
)
|
||||
object People: HomeScreenNavItem(
|
||||
R.string.nav_people_title,
|
||||
R.drawable.ic_face,
|
||||
Icons.Outlined.Face,
|
||||
"people_route",
|
||||
{ it.peopleTabPosition },
|
||||
{ p, i -> p.peopleTabPosition = i }
|
||||
|
||||
@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.NavigationRailDefaults
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -19,8 +20,10 @@ import androidx.compose.material3.LargeTopAppBar
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.NavigationBar
|
||||
import androidx.compose.material3.NavigationBarItem
|
||||
import androidx.compose.material3.NavigationBarItemDefaults
|
||||
import androidx.compose.material3.NavigationRail
|
||||
import androidx.compose.material3.NavigationRailItem
|
||||
import androidx.compose.material3.NavigationRailItemDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
@@ -35,7 +38,6 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.compositeOver
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavHostController
|
||||
@@ -161,7 +163,7 @@ private fun BottomNavBar(
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
.clip(RoundedCornerShape(24.dp)),
|
||||
icon = { Icon(painter = painterResource(id = item.icon), contentDescription = null) },
|
||||
icon = { Icon(imageVector = item.icon, contentDescription = null) },
|
||||
label = {
|
||||
val name = if (preferences.showBottomTabLabels) item.name else " "
|
||||
Text(text = name)
|
||||
@@ -171,7 +173,11 @@ private fun BottomNavBar(
|
||||
if (!isSelected) {
|
||||
navController.navigateInBottomBar(item.route)
|
||||
}
|
||||
}
|
||||
},
|
||||
colors = NavigationBarItemDefaults.colors(
|
||||
indicatorColor = MaterialTheme.colorScheme.secondary,
|
||||
selectedIconColor = MaterialTheme.colorScheme.onSecondary
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -252,14 +258,15 @@ private fun DualColumnMainContent(
|
||||
HomeScreenNavItem.SortedItems.forEachIndexed { index, item ->
|
||||
val isSelected = currentRoute == item.route
|
||||
NavigationRailItem(
|
||||
icon = { Icon(painter = painterResource(id = item.icon), contentDescription = null) },
|
||||
icon = { Icon(imageVector = item.icon, contentDescription = null) },
|
||||
label = { if (preferences.showBottomTabLabels) Text(item.name) },
|
||||
selected = isSelected,
|
||||
onClick = {
|
||||
if (!isSelected) {
|
||||
navController.navigateInBottomBar(item.route)
|
||||
}
|
||||
}
|
||||
},
|
||||
colors = NavigationRailItemDefaults.colors(indicatorColor = MaterialTheme.colorScheme.secondary)
|
||||
)
|
||||
if (index < HomeScreenNavItem.SortedItems.size - 1) {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
@@ -12,7 +12,11 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Book
|
||||
import androidx.compose.material.icons.filled.Bookmark
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Favorite
|
||||
import androidx.compose.material.icons.filled.Star
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -573,7 +577,7 @@ private fun ActionButtonRow(listItem: ListItem) {
|
||||
ActionButton(
|
||||
itemId = listItem.id,
|
||||
type = listItem.mediaType,
|
||||
iconRes = R.drawable.ic_favorite,
|
||||
imageVector = Icons.Filled.Favorite,
|
||||
contentDescription = stringResource(id = R.string.favourite_label),
|
||||
isSelected = isFavourited,
|
||||
filledIconColor = FavoriteSelected,
|
||||
@@ -583,7 +587,7 @@ private fun ActionButtonRow(listItem: ListItem) {
|
||||
ActionButton(
|
||||
itemId = listItem.id,
|
||||
type = listItem.mediaType,
|
||||
iconRes = R.drawable.ic_watchlist,
|
||||
imageVector = Icons.Filled.Bookmark,
|
||||
contentDescription = "",
|
||||
isSelected = isWatchlisted,
|
||||
filledIconColor = WatchlistSelected,
|
||||
@@ -594,7 +598,7 @@ private fun ActionButtonRow(listItem: ListItem) {
|
||||
ActionButton(
|
||||
itemId = listItem.id,
|
||||
type = listItem.mediaType,
|
||||
iconRes = R.drawable.ic_rating_star,
|
||||
imageVector = Icons.Filled.Star,
|
||||
contentDescription = "",
|
||||
isSelected = isRated,
|
||||
filledIconColor = RatingSelected,
|
||||
|
||||
@@ -20,6 +20,10 @@ import androidx.compose.material.icons.filled.Send
|
||||
import androidx.compose.material.icons.outlined.ExpandMore
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material.TabRow
|
||||
import androidx.compose.material.icons.filled.Bookmark
|
||||
import androidx.compose.material.icons.filled.Favorite
|
||||
import androidx.compose.material.icons.filled.List
|
||||
import androidx.compose.material.icons.filled.Star
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -27,6 +31,7 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@@ -188,6 +193,8 @@ private fun MediaViewContent(
|
||||
showImageGallery: MutableState<Boolean>,
|
||||
pagerState: PagerState
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.background(color = MaterialTheme.colorScheme.background),
|
||||
@@ -219,6 +226,22 @@ private fun MediaViewContent(
|
||||
MiscTvDetails(mediaItem = mediaItem, service as TvService)
|
||||
}
|
||||
|
||||
val externalIds = remember { mutableStateOf<ExternalIds?>(null) }
|
||||
LaunchedEffect(Unit) {
|
||||
scope.launch {
|
||||
val response = service.getExternalIds(itemId!!)
|
||||
if (response.isSuccessful) {
|
||||
externalIds.value = response.body()!!
|
||||
}
|
||||
}
|
||||
}
|
||||
externalIds.value?.let {
|
||||
ExternalIdsArea(
|
||||
externalIds = it,
|
||||
modifier = Modifier.padding(start = 20.dp)
|
||||
)
|
||||
}
|
||||
|
||||
ActionsView(itemId = itemId, type = type, service = service)
|
||||
|
||||
if (type == MediaViewType.MOVIE) {
|
||||
@@ -587,7 +610,7 @@ fun ActionButton(
|
||||
modifier: Modifier = Modifier,
|
||||
itemId: Int,
|
||||
type: MediaViewType,
|
||||
iconRes: Int,
|
||||
imageVector: ImageVector,
|
||||
contentDescription: String,
|
||||
isSelected: Boolean,
|
||||
filledIconColor: Color,
|
||||
@@ -628,7 +651,7 @@ fun ActionButton(
|
||||
modifier = Modifier
|
||||
.clip(CircleShape)
|
||||
.align(Alignment.Center),
|
||||
painter = painterResource(id = iconRes),
|
||||
imageVector = imageVector,
|
||||
contentDescription = contentDescription,
|
||||
tint = tintColor.value
|
||||
)
|
||||
@@ -685,7 +708,7 @@ private fun RateButton(
|
||||
modifier = Modifier
|
||||
.clip(CircleShape)
|
||||
.align(Alignment.Center),
|
||||
painter = painterResource(id = R.drawable.ic_rating_star),
|
||||
imageVector = Icons.Filled.Star,
|
||||
contentDescription = "",
|
||||
tint = tintColor.value
|
||||
)
|
||||
@@ -727,7 +750,7 @@ fun WatchlistButton(
|
||||
modifier = modifier,
|
||||
itemId = itemId,
|
||||
type = type,
|
||||
iconRes = R.drawable.ic_watchlist,
|
||||
imageVector = Icons.Filled.Bookmark,
|
||||
contentDescription = "",
|
||||
isSelected = hasWatchlistedItem,
|
||||
filledIconColor = WatchlistSelected,
|
||||
@@ -760,7 +783,7 @@ fun ListButton(
|
||||
),
|
||||
size = 40.dp,
|
||||
backgroundColor = MaterialTheme.colorScheme.actionButtonColor,
|
||||
painter = painterResource(id = R.drawable.ic_add_to_list),
|
||||
image = Icons.Filled.List,
|
||||
colorFilter = ColorFilter.tint(color = /*if (hasWatchlistedItem.value) WatchlistSelected else*/ MaterialTheme.colorScheme.background),
|
||||
contentDescription = ""
|
||||
)
|
||||
@@ -786,7 +809,7 @@ fun FavoriteButton(
|
||||
modifier = modifier,
|
||||
itemId = itemId,
|
||||
type = type,
|
||||
iconRes = R.drawable.ic_favorite,
|
||||
imageVector = Icons.Filled.Favorite,
|
||||
contentDescription = "",
|
||||
isSelected = isFavourited,
|
||||
filledIconColor = FavoriteSelected,
|
||||
|
||||
@@ -10,9 +10,11 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -24,10 +26,12 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import com.owenlejeune.tvtime.R
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.PeopleService
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.DetailPerson
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.ExternalIds
|
||||
import com.owenlejeune.tvtime.api.tmdb.api.v3.model.PersonCreditsResponse
|
||||
import com.owenlejeune.tvtime.ui.components.ContentCard
|
||||
import com.owenlejeune.tvtime.ui.components.DetailHeader
|
||||
import com.owenlejeune.tvtime.ui.components.ExpandableContentCard
|
||||
import com.owenlejeune.tvtime.ui.components.ExternalIdsArea
|
||||
import com.owenlejeune.tvtime.ui.components.TwoLineImageTextCard
|
||||
import com.owenlejeune.tvtime.ui.navigation.AppNavItem
|
||||
import com.owenlejeune.tvtime.utils.TmdbUtils
|
||||
@@ -83,6 +87,8 @@ fun PersonDetailScreen(
|
||||
)
|
||||
}
|
||||
) { innerPadding ->
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Box(modifier = Modifier.padding(innerPadding)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@@ -98,6 +104,22 @@ fun PersonDetailScreen(
|
||||
|
||||
BiographyCard(person = person.value)
|
||||
|
||||
val externalIds = remember { mutableStateOf<ExternalIds?>(null) }
|
||||
LaunchedEffect(Unit) {
|
||||
scope.launch {
|
||||
val response = PeopleService().getExternalIds(personId!!)
|
||||
if (response.isSuccessful) {
|
||||
externalIds.value = response.body()!!
|
||||
}
|
||||
}
|
||||
}
|
||||
externalIds.value?.let {
|
||||
ExternalIdsArea(
|
||||
externalIds = it,
|
||||
modifier = Modifier.padding(start = 4.dp)
|
||||
)
|
||||
}
|
||||
|
||||
val credits = remember { mutableStateOf<PersonCreditsResponse?>(null) }
|
||||
personId?.let {
|
||||
if (credits.value == null) {
|
||||
|
||||
@@ -4,15 +4,12 @@ import android.os.Build
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Brightness6
|
||||
|
||||
@@ -13,7 +13,6 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -75,7 +74,7 @@ class HomeTabRecyclerAdapter: RecyclerView.Adapter<HomeTabRecyclerAdapter.TabVie
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(24.dp),
|
||||
painter = painterResource(id = page.icon),
|
||||
imageVector = page.icon,
|
||||
contentDescription = page.name
|
||||
)
|
||||
Text(
|
||||
|
||||
@@ -16,7 +16,7 @@ object FileUtils {
|
||||
// char in that case. So we make it 4K to cover most, if not all, cases...
|
||||
val buffer = ByteArray(4096)
|
||||
val sb = java.lang.StringBuilder()
|
||||
var bytesRead = 0
|
||||
var bytesRead: Int
|
||||
while (bis.read(buffer).also { bytesRead = it } > 0) {
|
||||
val text = String(buffer, 0, bytesRead)
|
||||
sb.append(text)
|
||||
|
||||
9
app/src/main/res/drawable/facebook_logo.xml
Normal file
9
app/src/main/res/drawable/facebook_logo.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="50dp"
|
||||
android:height="50dp"
|
||||
android:viewportWidth="50"
|
||||
android:viewportHeight="50">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M25,3C12.85,3 3,12.85 3,25c0,11.03 8.125,20.137 18.712,21.728V30.831h-5.443v-5.783h5.443v-3.848c0,-6.371 3.104,-9.168 8.399,-9.168c2.536,0 3.877,0.188 4.512,0.274v5.048h-3.612c-2.248,0 -3.033,2.131 -3.033,4.533v3.161h6.588l-0.894,5.783h-5.694v15.944C38.716,45.318 47,36.137 47,25C47,12.85 37.15,3 25,3z"/>
|
||||
</vector>
|
||||
@@ -1,11 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M4,10.5c-0.83,0 -1.5,0.67 -1.5,1.5s0.67,1.5 1.5,1.5 1.5,-0.67 1.5,-1.5 -0.67,-1.5 -1.5,-1.5zM4,4.5c-0.83,0 -1.5,0.67 -1.5,1.5S3.17,7.5 4,7.5 5.5,6.83 5.5,6 4.83,4.5 4,4.5zM4,16.5c-0.83,0 -1.5,0.68 -1.5,1.5s0.68,1.5 1.5,1.5 1.5,-0.68 1.5,-1.5 -0.67,-1.5 -1.5,-1.5zM7,19h14v-2L7,17v2zM7,13h14v-2L7,11v2zM7,5v2h14L21,5L7,5z"/>
|
||||
</vector>
|
||||
@@ -1,11 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||
</vector>
|
||||
@@ -1,5 +0,0 @@
|
||||
<vector android:height="24dp" android:tint="@android:color/darker_gray"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M21,5v6.59l-3,-3.01 -4,4.01 -4,-4 -4,4 -3,-3.01L3,5c0,-1.1 0.9,-2 2,-2h14c1.1,0 2,0.9 2,2zM18,11.42l3,3.01L21,19c0,1.1 -0.9,2 -2,2L5,21c-1.1,0 -2,-0.9 -2,-2v-6.58l3,2.99 4,-4 4,4 4,-3.99z"/>
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M9,11.75c-0.69,0 -1.25,0.56 -1.25,1.25s0.56,1.25 1.25,1.25 1.25,-0.56 1.25,-1.25 -0.56,-1.25 -1.25,-1.25zM15,11.75c-0.69,0 -1.25,0.56 -1.25,1.25s0.56,1.25 1.25,1.25 1.25,-0.56 1.25,-1.25 -0.56,-1.25 -1.25,-1.25zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8 0,-0.29 0.02,-0.58 0.05,-0.86 2.36,-1.05 4.23,-2.98 5.21,-5.37C11.07,8.33 14.05,10 17.42,10c0.78,0 1.53,-0.09 2.25,-0.26 0.21,0.71 0.33,1.47 0.33,2.26 0,4.41 -3.59,8 -8,8z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M18,4l2,4h-3l-2,-4h-2l2,4h-3l-2,-4H8l2,4H7L5,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V4h-4z"/>
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h5v2h8v-2h5c1.1,0 1.99,-0.9 1.99,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,17L3,17L3,5h18v12z"/>
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M17,3H7c-1.1,0 -1.99,0.9 -1.99,2L5,21l7,-3 7,3V5c0,-1.1 -0.9,-2 -2,-2z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/instagram_logo.xml
Normal file
9
app/src/main/res/drawable/instagram_logo.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="50dp"
|
||||
android:height="50dp"
|
||||
android:viewportWidth="50"
|
||||
android:viewportHeight="50">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M16,3C8.83,3 3,8.83 3,16L3,34C3,41.17 8.83,47 16,47L34,47C41.17,47 47,41.17 47,34L47,16C47,8.83 41.17,3 34,3L16,3zM37,11C38.1,11 39,11.9 39,13C39,14.1 38.1,15 37,15C35.9,15 35,14.1 35,13C35,11.9 35.9,11 37,11zM25,14C31.07,14 36,18.93 36,25C36,31.07 31.07,36 25,36C18.93,36 14,31.07 14,25C14,18.93 18.93,14 25,14zM25,16C20.04,16 16,20.04 16,25C16,29.96 20.04,34 25,34C29.96,34 34,29.96 34,25C34,20.04 29.96,16 25,16z"/>
|
||||
</vector>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/placeholder"/>
|
||||
<item android:drawable="@drawable/ic_person" android:gravity="center"/>
|
||||
</layer-list>
|
||||
9
app/src/main/res/drawable/tiktok_logo.xml
Normal file
9
app/src/main/res/drawable/tiktok_logo.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="50dp"
|
||||
android:height="50dp"
|
||||
android:viewportWidth="50"
|
||||
android:viewportHeight="50">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M41,4H9C6.243,4 4,6.243 4,9v32c0,2.757 2.243,5 5,5h32c2.757,0 5,-2.243 5,-5V9C46,6.243 43.757,4 41,4zM37.006,22.323c-0.227,0.021 -0.457,0.035 -0.69,0.035c-2.623,0 -4.928,-1.349 -6.269,-3.388c0,5.349 0,11.435 0,11.537c0,4.709 -3.818,8.527 -8.527,8.527s-8.527,-3.818 -8.527,-8.527s3.818,-8.527 8.527,-8.527c0.178,0 0.352,0.016 0.527,0.027v4.202c-0.175,-0.021 -0.347,-0.053 -0.527,-0.053c-2.404,0 -4.352,1.948 -4.352,4.352s1.948,4.352 4.352,4.352s4.527,-1.894 4.527,-4.298c0,-0.095 0.042,-19.594 0.042,-19.594h4.016c0.378,3.591 3.277,6.425 6.901,6.685V22.323z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/twitter_logo.xml
Normal file
9
app/src/main/res/drawable/twitter_logo.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="50dp"
|
||||
android:height="50dp"
|
||||
android:viewportWidth="50"
|
||||
android:viewportHeight="50">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M50.063,10.438C48.215,11.258 46.234,11.809 44.152,12.059C46.277,10.785 47.91,8.77 48.676,6.371C46.691,7.547 44.484,8.402 42.145,8.863C40.27,6.863 37.598,5.617 34.641,5.617C28.961,5.617 24.355,10.219 24.355,15.898C24.355,16.703 24.449,17.488 24.625,18.242C16.078,17.813 8.504,13.719 3.43,7.496C2.543,9.02 2.039,10.785 2.039,12.668C2.039,16.234 3.852,19.383 6.613,21.23C4.926,21.176 3.34,20.711 1.953,19.941C1.953,19.984 1.953,20.027 1.953,20.07C1.953,25.055 5.5,29.207 10.199,30.156C9.34,30.391 8.43,30.516 7.492,30.516C6.828,30.516 6.184,30.453 5.555,30.328C6.867,34.41 10.664,37.391 15.16,37.473C11.645,40.23 7.211,41.871 2.391,41.871C1.559,41.871 0.742,41.824 -0.059,41.727C4.488,44.648 9.895,46.348 15.703,46.348C34.617,46.348 44.961,30.68 44.961,17.094C44.961,16.648 44.949,16.199 44.934,15.762C46.941,14.313 48.684,12.5 50.063,10.438Z"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/youtube_logo.xml
Normal file
9
app/src/main/res/drawable/youtube_logo.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="50dp"
|
||||
android:height="50dp"
|
||||
android:viewportWidth="50"
|
||||
android:viewportHeight="50">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M44.898,14.5C44.5,12.301 42.602,10.699 40.398,10.199C37.102,9.5 31,9 24.398,9C17.801,9 11.602,9.5 8.301,10.199C6.102,10.699 4.199,12.199 3.801,14.5C3.398,17 3,20.5 3,25C3,29.5 3.398,33 3.898,35.5C4.301,37.699 6.199,39.301 8.398,39.801C11.898,40.5 17.898,41 24.5,41C31.102,41 37.102,40.5 40.602,39.801C42.801,39.301 44.699,37.801 45.102,35.5C45.5,33 46,29.398 46.102,25C45.898,20.5 45.398,17 44.898,14.5ZM19,32L19,18L31.199,25Z"/>
|
||||
</vector>
|
||||
Reference in New Issue
Block a user