Skip to content

Commit

Permalink
Feat : 스크랩 화면 API 연동
Browse files Browse the repository at this point in the history
  • Loading branch information
DongChyeon committed Jun 18, 2024
1 parent 3416e5f commit 7f031d8
Show file tree
Hide file tree
Showing 17 changed files with 195 additions and 84 deletions.
4 changes: 3 additions & 1 deletion app/src/main/java/com/dev/briefing/BriefingNavHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ fun BriefingNavHost(
navigateToNewsDetail = appState.navController::navigateToNewsDetail
)
bookmarkScreen(
showSnackbar = appState::showSnackBar
showSnackbar = appState::showSnackBar,
navigateUp = appState.navController::navigateUp,
navigateToNewsDetail = appState.navController::navigateToNewsDetail
)
newsDetailScreen(
showSnackbar = appState::showSnackBar,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package store.newsbriefing.app.core.data.repository
import kotlinx.coroutines.flow.Flow
import store.newsbriefing.app.core.model.BriefingArticle
import store.newsbriefing.app.core.model.BriefingArticleCategory
import store.newsbriefing.app.core.model.BriefingCategoryArticles
import store.newsbriefing.app.core.model.BriefingCategoryArticle

interface BriefingRepository {
suspend fun getBriefingArticleSummaries(
briefingArticleCategory: BriefingArticleCategory
): Flow<BriefingCategoryArticles>
): Flow<BriefingCategoryArticle>

suspend fun getBriefingArticle(articleId: Long): Flow<BriefingArticle>
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import store.newsbriefing.app.core.data.repository.BriefingRepository
import store.newsbriefing.app.core.data.repository.model.asExternalModel
import store.newsbriefing.app.core.model.BriefingArticle
import store.newsbriefing.app.core.model.BriefingArticleCategory
import store.newsbriefing.app.core.model.BriefingCategoryArticles
import store.newsbriefing.app.core.model.BriefingCategoryArticle
import store.newsbriefing.app.core.network.datasource.BriefingNetworkDataSource
import javax.inject.Inject

Expand All @@ -15,7 +15,7 @@ internal class DefaultBriefingRepository @Inject constructor(
) : BriefingRepository {
override suspend fun getBriefingArticleSummaries(
briefingArticleCategory: BriefingArticleCategory,
): Flow<BriefingCategoryArticles> = flow {
): Flow<BriefingCategoryArticle> = flow {
val summaries = briefingNetworkDataSource.getBriefingArticleSummaries(
briefingArticleCategory,
null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import store.newsbriefing.app.core.model.BriefingArticle
import store.newsbriefing.app.core.model.BriefingArticleCategory
import store.newsbriefing.app.core.model.BriefingArticleRelated
import store.newsbriefing.app.core.model.BriefingArticleSummary
import store.newsbriefing.app.core.model.BriefingCategoryArticles
import store.newsbriefing.app.core.model.BriefingCategoryArticle
import store.newsbriefing.app.core.model.TimeOfDay
import store.newsbriefing.app.core.network.model.NetworkBriefingArticle
import store.newsbriefing.app.core.network.model.NetworkBriefingArticleRelated
Expand All @@ -14,11 +14,11 @@ import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

fun NetworkBriefingCategoryArticles.asExternalModel(): BriefingCategoryArticles {
fun NetworkBriefingCategoryArticles.asExternalModel(): BriefingCategoryArticle {
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.getDefault())
val parsedDate = dateFormat.parse(createdAt) ?: Date()

return BriefingCategoryArticles(
return BriefingCategoryArticle(
createdAt = parsedDate,
briefings = briefings.map { it.asExternalModel() }
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package store.newsbriefing.app.core.data.repository.model

import store.newsbriefing.app.core.common.util.toZoneDateTime
import store.newsbriefing.app.core.model.Scrap
import store.newsbriefing.app.core.model.TimeOfDay
import store.newsbriefing.app.core.network.model.NetworkScrap

fun NetworkScrap.asExternalModel() = Scrap(
briefingId = briefingId,
ranks = ranks,
title = title,
subtitle = subtitle,
date = date.toZoneDateTime(),
date = date,
gptModel = gptModel,
timeOfDay = timeOfDay
timeOfDay = TimeOfDay.fromValue(timeOfDay)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package store.newsbriefing.app.core.domain

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import store.newsbriefing.app.core.data.repository.MemberTokenRepository
import store.newsbriefing.app.core.data.repository.ScrapRepository
import store.newsbriefing.app.core.model.BriefingScrapArticle
import javax.inject.Inject

class LoadBriefingScrapArticleUseCase @Inject constructor(
private val scrapRepository: ScrapRepository,
private val memberTokenRepository: MemberTokenRepository
) {
suspend operator fun invoke(): Flow<List<BriefingScrapArticle>> {
val userId = memberTokenRepository.getMemberToken().first().memberId
val scraps = scrapRepository.getScrap(userId).first()

val groupedScraps = scraps.groupBy { it.date }

return flow { emit(groupedScraps.map { BriefingScrapArticle(it.key, it.value) }) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package store.newsbriefing.app.core.model

import java.util.Date

data class BriefingCategoryArticles(
data class BriefingCategoryArticle(
val createdAt: Date,
val briefings: List<BriefingArticleSummary>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package store.newsbriefing.app.core.model

data class BriefingScrapArticle(
val date: String,
val scraps: List<Scrap>
)
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package store.newsbriefing.app.core.model

import java.time.ZonedDateTime

data class Scrap(
val briefingId: Int,
val ranks: Int,
val title: String,
val subtitle: String,
val date: ZonedDateTime,
val date: String,
val gptModel: String,
val timeOfDay: String,
val timeOfDay: TimeOfDay,
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import store.newsbriefing.app.core.common.util.BriefingLogger
import store.newsbriefing.app.core.common.util.EventFlow
import store.newsbriefing.app.core.common.util.MutableEventFlow
import store.newsbriefing.app.core.common.util.asEventFlow
import store.newsbriefing.app.core.data.repository.MemberRepository
import store.newsbriefing.app.core.domain.SignInWithSocialProviderUseCase
import store.newsbriefing.app.core.model.SocialProvider
import javax.inject.Inject
Expand All @@ -22,7 +21,6 @@ sealed class SignInEvent {

@HiltViewModel
class SignInViewModel @Inject constructor(
private val memberRepository: MemberRepository,
private val signInWithSocialProviderUseCase: SignInWithSocialProviderUseCase
) : ViewModel() {
val eventFlow: EventFlow<SignInEvent>
Expand Down
3 changes: 3 additions & 0 deletions feature/bookmark/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ android {
}

dependencies {
implementation(projects.core.data)

api(projects.core.model)
api(projects.core.common)
api(projects.core.designsystem)
api(projects.core.domain)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ fun NavController.navigateToBookmark() {
}

fun NavGraphBuilder.bookmarkScreen(
showSnackbar: (String) -> Unit
showSnackbar: (String) -> Unit,
navigateUp: () -> Unit,
navigateToNewsDetail: (String) -> Unit
) {
composable(
route = bookmarkRoute
) {
BookmarkRoute(
showSnackbar = showSnackbar
showSnackbar = showSnackbar,
navigateUp = navigateUp,
navigateToNewsDetail = navigateToNewsDetail
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,87 +19,91 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
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.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.flow.collectLatest
import store.newsbriefing.app.core.designsystem.LoadingDialog
import store.newsbriefing.app.core.designsystem.theme.BriefingTheme
import store.newsbriefing.app.core.designsystem.theme.Pretendard
import store.newsbriefing.app.core.model.Scrap
import java.time.ZonedDateTime
import store.newsbriefing.app.core.model.TimeOfDay

@Composable
internal fun BookmarkRoute(
showSnackbar: (String) -> Unit
showSnackbar: (String) -> Unit,
navigateUp: () -> Unit,
navigateToNewsDetail: (String) -> Unit,
bookmarkViewModel: BookmarkViewModel = hiltViewModel()
) {
BookmarkScreen(
showSnackbar = showSnackbar
val uiState by bookmarkViewModel.uiState.collectAsStateWithLifecycle(
lifecycleOwner = androidx.compose.ui.platform.LocalLifecycleOwner.current
)
}

@Preview
@Composable
fun BookmarkScrrenPreview() {
BriefingTheme {
BookmarkScreen(
showSnackbar = {}
)
LaunchedEffect(Unit) {
bookmarkViewModel.eventFlow.collectLatest { event ->
when (event) {
is BookmarkEvent.ErrorOccurred -> {
showSnackbar(event.message)
}
}
}
}

BookmarkScreen(
uiState = uiState,
showSnackbar = showSnackbar,
navigateUp = navigateUp,
navigateToNewsDetail = navigateToNewsDetail
)
}

@Composable
internal fun BookmarkScreen(
showSnackbar: (String) -> Unit
uiState: BookmarkUiState,
showSnackbar: (String) -> Unit,
navigateUp: () -> Unit,
navigateToNewsDetail: (String) -> Unit
) {
Column(
modifier = Modifier
.fillMaxSize()
.background(BriefingTheme.colorScheme.BackgroundWhite)
.verticalScroll(rememberScrollState())
) {
TopBar {

when (uiState.articles) {
is BookmarkArticleUiState.Loading -> {
LoadingDialog()
}
is BookmarkArticleUiState.Error -> {
// Error
}
is BookmarkArticleUiState.Success -> {
val bookmarkArticles = uiState.articles.data

Column(
modifier = Modifier
.fillMaxSize()
.background(BriefingTheme.colorScheme.BackgroundWhite)
.verticalScroll(rememberScrollState())
) {
TopBar {
navigateUp()
}

repeat(3) {
BookmarkSection(
date = "2023.11.01(수) 오후",
items = listOf(
Scrap(
briefingId = 1,
ranks = 1,
title = "제목",
subtitle = "부제목",
date = ZonedDateTime.of(2023, 1, 1, 0, 0, 0, 0, ZonedDateTime.now().zone),
timeOfDay = "오전 10:00",
gptModel = "GPT-3",
),
Scrap(
briefingId = 2,
ranks = 2,
title = "제목",
subtitle = "부제목",
date = ZonedDateTime.of(2023, 1, 1, 0, 0, 0, 0, ZonedDateTime.now().zone),
timeOfDay = "오전 10:00",
gptModel = "GPT-3",
),
Scrap(
briefingId = 3,
ranks = 3,
title = "제목",
subtitle = "부제목",
date = ZonedDateTime.of(2023, 1, 1, 0, 0, 0, 0, ZonedDateTime.now().zone),
timeOfDay = "오전 10:00",
gptModel = "GPT-3",
bookmarkArticles.forEach {
BookmarkSection(
date = it.date,
items = it.scraps,
onItemClick = navigateToNewsDetail
)
)
)
}
}
}
}
}
Expand Down Expand Up @@ -128,7 +132,7 @@ private fun TopBar(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center),
text = "보관함",
text = stringResource(id = R.string.title_bookmark),
style = TextStyle(
fontFamily = Pretendard,
fontWeight = FontWeight.Medium,
Expand All @@ -144,7 +148,8 @@ private fun TopBar(
@Composable
private fun BookmarkSection(
date: String,
items: List<Scrap>
items: List<Scrap>,
onItemClick: (String) -> Unit,
) {
Column {
Text(
Expand All @@ -167,7 +172,7 @@ private fun BookmarkSection(

items.forEachIndexed { index, item ->
BookmarkItem(item = item) {

onItemClick("${item.briefingId}")
}

if (index != items.size - 1) {
Expand Down Expand Up @@ -234,7 +239,7 @@ private fun BookmarkItem(
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "${item.date} ${item.timeOfDay}",
text = "${item.date} ${stringResource(id = item.timeOfDay.getStringResId())}",
style = TextStyle(
fontFamily = Pretendard,
fontWeight = FontWeight.Normal,
Expand All @@ -252,7 +257,7 @@ private fun BookmarkItem(
)

Text(
text = "${item.gptModel}로 생성됨",
text = stringResource(id = R.string.generated_engine, item.gptModel),
style = TextStyle(
fontFamily = Pretendard,
fontWeight = FontWeight.Normal,
Expand All @@ -263,4 +268,11 @@ private fun BookmarkItem(
)
}
}
}

private fun TimeOfDay.getStringResId(): Int {
return when (this) {
TimeOfDay.MORNING -> R.string.time_of_day_morning
TimeOfDay.EVENING -> R.string.time_of_day_evening
}
}
Loading

0 comments on commit 7f031d8

Please sign in to comment.