Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
41295e0
chore: 사용하지 않는 파일 제거
parkjiminnnn Dec 1, 2025
bca7076
refactor: 공통 헤더 컴포넌트 이름 변경 및 Scaffold 적용
parkjiminnnn Dec 1, 2025
a61fa9a
style: 코드 포맷팅
parkjiminnnn Dec 1, 2025
507b68f
fix: NewsScreen Modifier 누락 수정 및 NewsTabRowPreview 테마 적용
parkjiminnnn Dec 1, 2025
e454246
refactor: StateFlow로 변경
parkjiminnnn Dec 2, 2025
2127ad4
feat: 일정 화면 ComposeUI 기초 구현
parkjiminnnn Dec 2, 2025
fb6e92e
refactor: NewsTabRow 컨텐츠 색상 설정 방식 변경
parkjiminnnn Dec 3, 2025
c95f70a
refactor: 네이밍 변경
parkjiminnnn Dec 3, 2025
2f77110
feat: 일정 화면 탭 UI 구현
parkjiminnnn Dec 3, 2025
af8fa95
feat: 일정 아이템 카드 구현
parkjiminnnn Dec 9, 2025
831e0dc
refactor: 불필요한 함수 제거
parkjiminnnn Dec 9, 2025
9b9e426
feat: 일정 타임라인에 사용될 Lottie Circle 데이터 클래스 추가
parkjiminnnn Dec 9, 2025
39956b8
feat: 일정 아이템 카드 UI 구현
parkjiminnnn Dec 10, 2025
5bd8069
feat: 카드 배경색 적용
parkjiminnnn Dec 10, 2025
acd296f
fix: 소식 화면 레이아웃 패딩 수정
parkjiminnnn Dec 10, 2025
09f399f
feat: 일정 화면 Compose 마이그레이션
parkjiminnnn Dec 10, 2025
aa7d65b
refactor: VieModel 자동 DI 변경
parkjiminnnn Dec 10, 2025
dbd60af
refactor: 일정 화면 UI 상태 관리 및 데이터 로딩 로직 개선
parkjiminnnn Dec 18, 2025
486cad8
fix: 일정 화면 새로고침 시 기존 데이터 유지 로직 수정
parkjiminnnn Dec 18, 2025
0eba44e
fix: ScheduleViewModel 데이터 로딩 로직 개선
parkjiminnnn Dec 18, 2025
4fda065
refactor: 일정 화면 UI 상태 구조 개선 및 로직 최적화
parkjiminnnn Dec 19, 2025
a5469ef
fix: Schedule 화면 성능 및 UX 개선
parkjiminnnn Dec 19, 2025
54cf5b1
feat: 일정 화면 현재 진행 중인 이벤트 위치로 자동 스크롤 기능 추가
parkjiminnnn Dec 19, 2025
670a838
refactor: ScheduleFragment의 메뉴 재클릭 로직 수정
parkjiminnnn Dec 19, 2025
12795eb
fix: 일정 화면 새로고침(Refreshing) 상태 추가 및 UI 로직 개선
parkjiminnnn Dec 19, 2025
b21e5ec
refactor: 일정 화면 ViewPager 및 탭 페이지 프래그먼트 제거
parkjiminnnn Dec 19, 2025
0076c56
feat: `ScheduleTabPage` 에러 발생 시 스택 트레이스 로그 추가
parkjiminnnn Dec 19, 2025
54562e4
fix: 진행 중인 일정 위치 계산 로직 수정
parkjiminnnn Dec 19, 2025
72136fa
feat: JUnit 5 마이그레이션 및 테스트 환경 설정
parkjiminnnn Dec 21, 2025
722f08f
refactor: ScheduleEventUiModel에서 북마크 상태 필드 제거
parkjiminnnn Dec 21, 2025
44db8ea
test: ScheduleViewModelTest 및 관련 코드 리팩토링
parkjiminnnn Dec 21, 2025
8baaf1e
refactor: ScheduleEventCard 리팩토링 및 색상 로직 분리
parkjiminnnn Dec 22, 2025
8c77188
refactor: Lottie 프로퍼티 호이스팅 적용
parkjiminnnn Dec 22, 2025
3f84cc5
refactor: Composable 어노테이션 제거
parkjiminnnn Dec 22, 2025
401b44b
refactor: ScheduleEventItem 코드 구조 개선 및 가독성 향상
parkjiminnnn Dec 22, 2025
35e2a38
refactor: `PullToRefreshContainer` 사용 방식 개선 및 리팩토링
parkjiminnnn Dec 22, 2025
4f864cb
refactor: 일정 화면 탭 클릭 시 스크롤 애니메이션 적용
parkjiminnnn Dec 22, 2025
c76703e
fix: 일정 탭 빈 화면 스크롤 가능하도록 수정
parkjiminnnn Dec 22, 2025
7079e2c
refactor: 선택적 파라미터를 사용하도록 변경
parkjiminnnn Dec 23, 2025
af60091
refactor: 함수명 변경
parkjiminnnn Dec 23, 2025
e0ffb6f
refactor: 일정 화면 이벤트 프리로딩하도록 변경
parkjiminnnn Dec 23, 2025
45f2a76
fix: NewsScreen 내 Pager 구성 요소 레이아웃 수정
parkjiminnnn Dec 23, 2025
e9af718
Merge remote-tracking branch 'origin/develop' into feat/7
parkjiminnnn Dec 27, 2025
ff5e151
refactor: 일정 화면 컴포넌트 리팩토링 및 커스텀 Typography 적용
parkjiminnnn Dec 27, 2025
e5f1ba3
refactor: Lottie 애니메이션 로직 위치 수정
parkjiminnnn Dec 28, 2025
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
9 changes: 9 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,13 @@ dependencies {
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
debugImplementation(libs.logging.interceptor)
testImplementation(libs.junit.jupiter.api)
testRuntimeOnly(libs.junit.jupiter.engine)
testImplementation(libs.junit.jupiter.params)
testImplementation(libs.junit.platform.launcher)
testRuntimeOnly(libs.junit.vintage.engine)
}

tasks.withType<Test>().configureEach {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import com.daedan.festabook.di.viewmodel.MetroViewModelFactory
import com.daedan.festabook.logging.DefaultFirebaseLogger
import com.daedan.festabook.presentation.main.MainActivity
import com.daedan.festabook.presentation.placeDetail.PlaceDetailActivity
import com.daedan.festabook.presentation.schedule.ScheduleViewModel
import com.daedan.festabook.presentation.splash.SplashActivity
import com.google.android.play.core.appupdate.AppUpdateManager
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
Expand Down Expand Up @@ -41,8 +40,6 @@ interface FestaBookAppGraph {
val defaultFirebaseLogger: DefaultFirebaseLogger

val metroViewModelFactory: MetroViewModelFactory

val scheduleViewModelFactory: ScheduleViewModel.Factory
}

val Context.appGraph get() = (applicationContext as FestaBookApp).festaBookGraph
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import com.daedan.festabook.presentation.theme.FestabookTypography
import com.daedan.festabook.presentation.theme.festabookSpacing

@Composable
fun Header(
fun FestabookTopAppBar(
title: String,
modifier: Modifier = Modifier,
style: TextStyle = FestabookTypography.displayLarge,
Expand All @@ -32,6 +32,6 @@ fun Header(

@Composable
@Preview(showBackground = true)
private fun HeaderPreview() {
Header(title = "FestaBook")
private fun FestabookTopAppBarPreview() {
FestabookTopAppBar(title = "FestaBook")
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.daedan.festabook.R
import com.daedan.festabook.presentation.theme.FestabookColor

const val PULL_OFFSET_LIMIT = 180F
private const val PULL_OFFSET_LIMIT = 180F

@OptIn(ExperimentalMaterial3Api::class)
@Composable
Expand All @@ -31,7 +32,7 @@ fun PullToRefreshContainer(
onRefresh: () -> Unit,
modifier: Modifier = Modifier,
pullOffsetLimit: Float = PULL_OFFSET_LIMIT,
content: @Composable (PullToRefreshState) -> Unit,
content: @Composable (Modifier) -> Unit,
) {
val pullToRefreshState = rememberPullToRefreshState()
val threshold = (pullOffsetLimit / 2).dp
Expand All @@ -52,7 +53,11 @@ fun PullToRefreshContainer(
},
modifier = modifier.fillMaxSize(),
) {
content(pullToRefreshState)
content(
Modifier.graphicsLayer {
translationY = pullToRefreshState.distanceFraction * pullOffsetLimit
},
)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.daedan.festabook.presentation.news.component

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
Expand All @@ -12,7 +13,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.daedan.festabook.R
import com.daedan.festabook.presentation.common.component.Header
import com.daedan.festabook.presentation.common.component.FestabookTopAppBar
import com.daedan.festabook.presentation.news.NewsTab
import com.daedan.festabook.presentation.news.NewsViewModel
import com.daedan.festabook.presentation.news.lost.LostUiState
Expand All @@ -38,29 +39,36 @@ fun NewsScreen(
pageState.animateScrollToPage(NewsTab.NOTICE.ordinal)
}
}

Column(modifier = modifier.background(color = MaterialTheme.colorScheme.background)) {
Header(title = stringResource(R.string.news_title))
NewsTabRow(pageState, scope)
NewsTabPage(
pageState = pageState,
noticeUiState = noticeUiState,
faqUiState = faqUiState,
lostUiState = lostUiState,
isNoticeRefreshing = isNoticeRefreshing,
isLostItemRefreshing = isLostItemRefreshing,
onNoticeRefresh = {
val oldNotices =
(noticeUiState as? NoticeUiState.Success)?.notices ?: emptyList()
newsViewModel.loadAllNotices(NoticeUiState.Refreshing(oldNotices))
},
onLostItemRefresh = {
val oldLostItems = (lostUiState as? LostUiState.Success)?.lostItems ?: emptyList()
newsViewModel.loadAllLostItems(LostUiState.Refreshing(oldLostItems))
},
onNoticeClick = { newsViewModel.toggleNotice(it) },
onFaqClick = { newsViewModel.toggleFAQ(it) },
onLostGuideClick = { newsViewModel.toggleLostGuide() },
)
Scaffold(
topBar = { FestabookTopAppBar(title = stringResource(R.string.news_title)) },
modifier = modifier,
) { innerPadding ->
Column(
modifier = Modifier.padding(top = innerPadding.calculateTopPadding()),
) {
NewsTabRow(pageState, scope)
NewsTabPage(
pageState = pageState,
noticeUiState = noticeUiState,
faqUiState = faqUiState,
lostUiState = lostUiState,
isNoticeRefreshing = isNoticeRefreshing,
isLostItemRefreshing = isLostItemRefreshing,
onNoticeRefresh = {
val oldNotices =
(noticeUiState as? NoticeUiState.Success)?.notices ?: emptyList()
newsViewModel.loadAllNotices(NoticeUiState.Refreshing(oldNotices))
},
onLostItemRefresh = {
val oldLostItems =
(lostUiState as? LostUiState.Success)?.lostItems ?: emptyList()
newsViewModel.loadAllLostItems(LostUiState.Refreshing(oldLostItems))
},
onNoticeClick = { newsViewModel.toggleNotice(it) },
onFaqClick = { newsViewModel.toggleFAQ(it) },
onLostGuideClick = { newsViewModel.toggleLostGuide() },
modifier = Modifier.fillMaxSize(),
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.daedan.festabook.presentation.news.NewsTab
import com.daedan.festabook.presentation.theme.FestabookColor
import com.daedan.festabook.presentation.theme.FestabookTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

Expand All @@ -27,7 +28,6 @@ fun NewsTabRow(
TabRow(
selectedTabIndex = pageState.currentPage,
containerColor = MaterialTheme.colorScheme.background,
Comment on lines 28 to 30
Copy link
Contributor

Choose a reason for hiding this comment

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

여기에서도 FestabookColor 를 사용할 수 있지 않을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

dev브랜치 병합시키고 반영하겠습니다.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

여기에서도 FestabookColor 를 사용할 수 있지 않을까요?

TabRow가 Material 컴포넌트라서 이렇게 했는데 제가 놓친 부분이 있을까요?

contentColor = FestabookColor.black,
indicator = { tabPositions ->
TabRowDefaults.PrimaryIndicator(
color = FestabookColor.black,
Expand All @@ -41,6 +41,7 @@ fun NewsTabRow(
Tab(
selected = pageState.currentPage == index,
unselectedContentColor = FestabookColor.gray500,
selectedContentColor = FestabookColor.black,
onClick = { scope.launch { pageState.animateScrollToPage(index) } },
text = { Text(text = stringResource(title.tabNameRes)) },
)
Expand All @@ -51,8 +52,10 @@ fun NewsTabRow(
@Composable
@Preview
private fun NewsTabRowPreview() {
NewsTabRow(
pageState = rememberPagerState { 3 },
scope = rememberCoroutineScope(),
)
FestabookTheme {
NewsTabRow(
pageState = rememberPagerState { 3 },
scope = rememberCoroutineScope(),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,12 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.daedan.festabook.R
import com.daedan.festabook.presentation.common.component.EmptyStateScreen
import com.daedan.festabook.presentation.common.component.LoadingStateScreen
import com.daedan.festabook.presentation.common.component.PULL_OFFSET_LIMIT
import com.daedan.festabook.presentation.common.component.PullToRefreshContainer
import com.daedan.festabook.presentation.news.component.NewsItem
import com.daedan.festabook.presentation.news.lost.LostUiState
Expand Down Expand Up @@ -55,9 +53,11 @@ fun LostItemScreen(
PullToRefreshContainer(
isRefreshing = isRefreshing,
onRefresh = onRefresh,
) { pullToRefreshState ->
) { graphicsLayer ->
when (lostUiState) {
LostUiState.InitialLoading -> LoadingStateScreen()
LostUiState.InitialLoading -> {
LoadingStateScreen()
}

is LostUiState.Error -> {
LaunchedEffect(lostUiState) {
Expand All @@ -73,10 +73,7 @@ fun LostItemScreen(
modifier =
modifier
.fillMaxSize()
.graphicsLayer {
translationY =
pullToRefreshState.distanceFraction * PULL_OFFSET_LIMIT
},
.then(graphicsLayer),
)
}

Expand All @@ -88,10 +85,7 @@ fun LostItemScreen(
modifier =
modifier
.fillMaxSize()
.graphicsLayer {
translationY =
pullToRefreshState.distanceFraction * PULL_OFFSET_LIMIT
},
.then(graphicsLayer),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,13 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.daedan.festabook.R
import com.daedan.festabook.presentation.common.component.EmptyStateScreen
import com.daedan.festabook.presentation.common.component.LoadingStateScreen
import com.daedan.festabook.presentation.common.component.PULL_OFFSET_LIMIT
import com.daedan.festabook.presentation.common.component.PullToRefreshContainer
import com.daedan.festabook.presentation.news.component.NewsItem
import com.daedan.festabook.presentation.news.notice.NoticeUiState
Expand All @@ -39,9 +36,11 @@ fun NoticeScreen(
PullToRefreshContainer(
isRefreshing = isRefreshing,
onRefresh = onRefresh,
) { pullToRefreshState ->
) { graphicsLayer ->
when (uiState) {
NoticeUiState.InitialLoading -> LoadingStateScreen()
NoticeUiState.InitialLoading -> {
LoadingStateScreen()
}

is NoticeUiState.Error -> {
LaunchedEffect(uiState) {
Expand All @@ -53,10 +52,7 @@ fun NoticeScreen(
NoticeContent(
notices = uiState.oldNotices,
onNoticeClick = onNoticeClick,
modifier =
modifier.graphicsLayer {
translationY = pullToRefreshState.distanceFraction * PULL_OFFSET_LIMIT
},
modifier = modifier.then(graphicsLayer),
)
}

Expand All @@ -65,10 +61,7 @@ fun NoticeScreen(
notices = uiState.notices,
expandPosition = uiState.expandPosition,
onNoticeClick = onNoticeClick,
modifier =
modifier.graphicsLayer {
translationY = pullToRefreshState.distanceFraction * PULL_OFFSET_LIMIT
},
modifier = modifier.then(graphicsLayer),
)
}
}
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ package com.daedan.festabook.presentation.schedule
import com.daedan.festabook.presentation.schedule.model.ScheduleEventUiModel

sealed interface ScheduleEventsUiState {
data object Loading : ScheduleEventsUiState
data object InitialLoading : ScheduleEventsUiState

data class Refreshing(
val oldEvents: List<ScheduleEventUiModel>,
) : ScheduleEventsUiState

data class Success(
val events: List<ScheduleEventUiModel>,
Expand Down
Loading