Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.flint.core.designsystem.component.bottomsheet

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.SheetState
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.flint.core.designsystem.component.listItem.OttShortCutListItem
Expand All @@ -20,7 +25,6 @@ import com.flint.domain.type.OttType
fun OttListBottomSheet(
ottList: OttListModel,
onDismiss: () -> Unit,
onMoveClick: (String) -> Unit,
modifier: Modifier = Modifier,
sheetState: SheetState = rememberModalBottomSheetState(),
) {
Expand All @@ -29,17 +33,26 @@ fun OttListBottomSheet(
onDismiss = onDismiss,
) {
LazyColumn(
modifier = modifier.padding(top = 24.dp, bottom = 32.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = modifier.padding(bottom = 30.dp),
) {
item {
Text(
text = "이 작품을 볼 수 있는 OTT",
style = FlintTheme.typography.head3Sb18,
color = FlintTheme.colors.white,
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
)

Spacer(Modifier.height(12.dp))
}

items(ottList.otts.size) {
OttShortCutListItem(
ottModel = ottList.otts[it],
onMoveClick = {
onMoveClick(ottList.otts[it].contentUrl)
onDismiss()
},
)
Spacer(Modifier.height(8.dp))
}
}
}
Expand All @@ -57,7 +70,6 @@ private fun PreviewOttListBottomSheet() {
OttListBottomSheet(
ottList = ottList,
onDismiss = {},
onMoveClick = {},
modifier = Modifier,
sheetState = sheetState,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import com.flint.domain.type.OttType
@Composable
fun OttShortCutListItem(
ottModel: OttModel,
onMoveClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(
Expand All @@ -57,23 +56,6 @@ fun OttShortCutListItem(
)

Spacer(Modifier.weight(1f))

Box(
modifier =
Modifier
.clip(RoundedCornerShape(8.dp))
.background(FlintTheme.colors.primary400)
.clickable {
onMoveClick()
}.padding(vertical = 7.dp, horizontal = 12.dp),
contentAlignment = Alignment.Center,
) {
Text(
text = "바로 보러가기",
style = FlintTypography.body2M14,
color = FlintTheme.colors.white,
)
}
}
}

Expand All @@ -88,8 +70,7 @@ private fun PreviewOttShortCutListItem() {
name = "Netflix",
logoUrl = "",
contentUrl = "",
),
onMoveClick = {},
)
)
}
}
Expand Down
47 changes: 47 additions & 0 deletions app/src/main/java/com/flint/core/designsystem/theme/Color.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,15 @@ data class Colors(
val yellow: Color,
val blue: Color,
val kakao: Color,
val transparent: Color,
val buttonStroke: Brush,
val myGradient: Brush,
val blueGradient: Brush,
val primary400Gradient: Brush,
val grayGradient: Brush,
val gray800Gradient: Brush,
val userBadgeGradient: Brush,
val userBadgeStroke: Brush,
)

val FlintColors =
Expand Down Expand Up @@ -160,6 +167,7 @@ val FlintColors =
yellow = Color(0xFFF9B902),
blue = Color(0xFF38A5FF),
kakao = Color(0xFFFEE500),
transparent = Color.Transparent,
buttonStroke =
Brush.verticalGradient(
colors = listOf(Color(0xFFAEAEAE), Color(0xFF666666)),
Expand All @@ -168,6 +176,45 @@ val FlintColors =
Brush.verticalGradient(
colors = listOf(Color(0xFF424BBD).copy(1f), Color(0xFF121212).copy(alpha = 0.04f)),
),
blueGradient =
Brush.verticalGradient(
colors = listOf(Color(0xFF062845).copy(alpha = 0f), Color(0xFF062845).copy(1f)),
),
primary400Gradient =
Brush.verticalGradient(
colors = listOf(Color(0xFF1ABFF2).copy(0f), Color(0xFF1ABFF2).copy(0.35f)),
),
grayGradient =
Brush.verticalGradient(
colors = listOf(Color(0xFF21242C).copy(alpha = 0f), Color(0xFF21242C).copy(alpha = 1f)),
),
gray800Gradient =
Brush.verticalGradient(
colors = listOf(Color(0xFF21242C).copy(alpha = 0f), Color(0xFF21242C).copy(alpha = 0.35f)),
),
userBadgeGradient = object : ShaderBrush() {
override fun createShader(size: Size): Shader {
return LinearGradientShader(
from = Offset(size.width * 0.095f, size.height * 0.109f),
to = Offset(size.width * 0.921f, size.height * 0.844f),
colors = listOf(Color.White.copy(alpha = 0f), Color.White.copy(alpha = 0.1f)),
)
}
},
userBadgeStroke = object : ShaderBrush() {
override fun createShader(size: Size): Shader {
return LinearGradientShader(
from = Offset(size.width * 0.429f, 0f),
to = Offset(size.width * 0.738f, size.height),
colors = listOf(
Color.White.copy(alpha = 0.7f),
Color.White.copy(alpha = 0f),
Color.White.copy(alpha = 0.7f),
),
colorStops = listOf(0f, 0.52f, 1f),
)
}
},
)

@Preview(device = Devices.DESKTOP)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ enum class CollectionListRouteType(
) {
CREATED(title = "전체 컬렉션"),
SAVED(title = "저장 컬렉션"),
RECENT(title = "눈여겨보고 있는 컬렉션"),
FAMOUS(title = "인기 컬렉션")
}
6 changes: 5 additions & 1 deletion app/src/main/java/com/flint/data/api/HomeApi.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package com.flint.data.api

import com.flint.data.dto.base.BaseResponse
import com.flint.data.dto.home.response.PopularCollectionResponseDto
import com.flint.data.dto.home.response.RecommendCollectionResponseDto
import retrofit2.http.GET

interface HomeApi {

@GET("/api/v1/home/recommended-collections")
suspend fun getRecommendedCollections() : BaseResponse<RecommendCollectionResponseDto>
suspend fun getRecommendedCollections(): BaseResponse<RecommendCollectionResponseDto>

@GET("/api/v1/home/popular-collections")
suspend fun getPopularCollections(): BaseResponse<PopularCollectionResponseDto>
}
2 changes: 1 addition & 1 deletion app/src/main/java/com/flint/data/api/UserApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ interface UserApi {
): BaseResponse<BookmarkedCollectionListResponseDto>

// 사용자별 북마크한 콘텐츠 목록 조회
@GET("/api/v1/contents/{userId}/bookmarked-contents")
@GET("/api/v1/users/{userId}/bookmarked-contents")
suspend fun getBookmarkedContentListByUserId(
@Path("userId") userId: String
): BaseResponse<BookmarkedContentListResponseDto>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class TokenInterceptor

val requestBuilder = originalRequest.newBuilder()

val isSearchRequest = originalRequest.url.encodedPath.endsWith("/contents/search")
if (accessToken.isNotEmpty() && !isSearchRequest) {
val isPublicEndpoint = originalRequest.url.encodedPath == "/api/v1/search/contents"
if (accessToken.isNotEmpty() && !isPublicEndpoint) {
requestBuilder.header("Authorization", "Bearer $accessToken")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import kotlinx.serialization.Serializable

@Serializable
data class BookmarkedContentListResponseDto(
@SerialName("totalCount")
val totalCount: Int = 0,
Comment on lines +8 to +9

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

DTO에 추가된 필드가 도메인 모델로 매핑되지 않음.

BookmarkedContentListResponseDtototalCount, BookmarkedContentResponseDtobookmarkCountisBookmarked 필드가 추가되었지만, ContentMapper.kttoModel() 확장 함수에서 이 필드들을 매핑하지 않고 있습니다 (app/src/main/java/com/flint/domain/mapper/content/ContentMapper.kt:13-28 참조).

API가 이제 이 데이터를 제공한다면 도메인 모델과 UI 상태에 반영되어야 합니다. 현재는 API 응답 데이터가 버려지고 있어 데이터 무결성 문제가 발생합니다.

🔧 제안: 매퍼 업데이트

ContentMapper.kt를 업데이트하여 새 필드를 매핑하세요:

fun BookmarkedContentListResponseDto.toModel() : BookmarkedContentListModel {
    return BookmarkedContentListModel(
        totalCount = totalCount,
        contents = contents.map { it.toModel() }.toImmutableList()
    )
}

fun BookmarkedContentResponseDto.toModel() : BookmarkedContentItemModel {
    return BookmarkedContentItemModel(
        id = id,
        title = title,
        year = year,
        imageUrl = imageUrl,
        bookmarkCount = bookmarkCount,
        isBookmarked = isBookmarked,
        getOttSimpleList = getOttSimpleList.mapNotNull { ottSimple ->
            runCatching { OttType.valueOf(ottSimple.ottName) }.getOrNull()
        }
    )
}

그리고 BookmarkedContentListModelBookmarkedContentItemModel에도 해당 필드를 추가하세요.

Also applies to: 24-27

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@app/src/main/java/com/flint/data/dto/content/response/BookmarkedContentListResponseDto.kt`
around lines 8 - 9, The new fields totalCount in
BookmarkedContentListResponseDto and bookmarkCount and isBookmarked in
BookmarkedContentResponseDto are added to the DTOs but not being mapped to the
domain models. Update the toModel() extension functions in ContentMapper.kt for
both BookmarkedContentListResponseDto (lines 13-28) and
BookmarkedContentResponseDto to include mappings for totalCount, bookmarkCount,
and isBookmarked respectively. Additionally, add these corresponding fields to
the domain model classes BookmarkedContentListModel and
BookmarkedContentItemModel so the API response data is properly preserved
through the mapping layer instead of being discarded.

@SerialName("contents")
val contents: List<BookmarkedContentResponseDto>
)
Expand All @@ -19,6 +21,10 @@ data class BookmarkedContentResponseDto(
val year: Int,
@SerialName("imageUrl")
val imageUrl: String,
@SerialName("bookmarkCount")
val bookmarkCount: Int = 0,
@SerialName("isBookmarked")
val isBookmarked: Boolean = false,
@SerialName("getOttSimpleList")
val getOttSimpleList: List<OttSimpleResponseDto>
)
Expand All @@ -29,4 +35,4 @@ data class OttSimpleResponseDto(
val ottName: String,
@SerialName("logoUrl")
val logoUrl: String
)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.flint.data.dto.home.response

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class PopularCollectionResponseDto(
@SerialName("collections")
val collections: List<PopularCollectionItemResponseDto>
)

@Serializable
data class PopularCollectionItemResponseDto(
@SerialName("id")
val id: String,
@SerialName("thumbnailUrl")
val thumbnailUrl: String?,
@SerialName("title")
val title: String,
@SerialName("nickname")
val nickname: String,
@SerialName("profileImageUrl")
val profileUrl: String?
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.flint.domain.mapper.collection
import com.flint.data.dto.collection.response.CollectionsResponseDto
import com.flint.data.dto.collection.response.RecentCollectionItemResponseDto
import com.flint.data.dto.collection.response.RecentCollectionListResponseDto
import com.flint.data.dto.home.response.PopularCollectionItemResponseDto
import com.flint.data.dto.home.response.PopularCollectionResponseDto
import com.flint.data.dto.home.response.RecommendCollectionItemResponseDto
import com.flint.data.dto.home.response.RecommendCollectionResponseDto
import com.flint.data.dto.user.response.BookmarkedCollectionItemResponseDto
Expand All @@ -22,6 +24,22 @@ fun CollectionsResponseDto.toModel(): CollectionsModel {
}


fun PopularCollectionResponseDto.toModel(): CollectionListModel {
return CollectionListModel(
collections = collections.map { it.toModel() }.toImmutableList()
)
}

private fun PopularCollectionItemResponseDto.toModel(): CollectionItemModel {
return CollectionItemModel(
id = id,
thumbnailUrl = thumbnailUrl,
title = title,
nickname = nickname,
profileUrl = profileUrl
)
}

fun RecommendCollectionResponseDto.toModel(): CollectionListModel {
return CollectionListModel(
collections = collections.map { it.toModel() }.toImmutableList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,30 @@ data class CollectionListModel(
userId = "0",
nickname = "nickname",
profileUrl = null
),
CollectionItemModel(
id = "1",
thumbnailUrl = "",
title = "드라마 제목",
description = "드라마 제목 드라마 제목 드라마 제목 드라마 제목 드라마 제목",
imageList = emptyList(),
bookmarkCount = 0,
isBookmarked = false,
userId = "0",
nickname = "nickname",
profileUrl = null
),
CollectionItemModel(
id = "2",
thumbnailUrl = "",
title = "드라마 제목",
description = "드라마 제목 드라마 제목 드라마 제목 드라마 제목 드라마 제목",
imageList = emptyList(),
bookmarkCount = 0,
isBookmarked = false,
userId = "0",
nickname = "nickname",
profileUrl = null
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ class HomeRepository @Inject constructor(
) {
suspend fun getRecommendedCollectionList(): Result<CollectionListModel> =
suspendRunCatching { apiService.getRecommendedCollections().data.toModel() }

suspend fun getPopularCollectionList(): Result<CollectionListModel> =
suspendRunCatching { apiService.getPopularCollections().data.toModel() }
}
Loading
Loading