Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
fad939e
[Add] 시간표 수정, 삭제 다이얼로그 추가
nodobi Nov 5, 2024
9043f80
Merge branch 'develop' into feature/timetable_dialogs
nodobi Nov 5, 2024
84f59dc
Merge pull request #456 from BCSDLab/release
ThirFir Nov 5, 2024
64cde41
[Add] 추가 가능한 학기 리스트 받는 유즈케이스 추가
nodobi Nov 6, 2024
e4e83c5
[Add] ui 레이어에서 사용할 SemesterModel 추가
nodobi Nov 6, 2024
dedfcac
Merge branch 'develop' into feature/timetable_dialogs
nodobi Nov 6, 2024
9a1cfad
[Add] 학기 설정 버튼 컴포넌트 추가
nodobi Nov 6, 2024
8096949
[del] hour formatter 삭제
Jokwanhee Nov 7, 2024
35937ae
[fix] 변수명 변경
Jokwanhee Nov 7, 2024
fa44832
[fix] range 구하는 로직 수정
Jokwanhee Nov 7, 2024
6ed214f
[add] 마지막 활성화 radius round 추가
Jokwanhee Nov 7, 2024
774b497
[add] 클릭 활성화 radius 추가 및 시간표 확장
Jokwanhee Nov 7, 2024
f7a3d61
[fix] 테스트 코드 수정
Jokwanhee Nov 7, 2024
2a32c28
[fix] 강의 시간 분할 로직 변경
Jokwanhee Nov 7, 2024
2b57c29
[del] 주석 제거
Jokwanhee Nov 7, 2024
61aca0a
[fix] bottom end round 설정 로직 함수화
Jokwanhee Nov 7, 2024
06cdd0d
[fix] 함수명 변경 적용
Jokwanhee Nov 7, 2024
365b039
[fix] 강의 활성화 블록 시간 확장 기능 추가
Jokwanhee Nov 7, 2024
3709697
[add] 테스트 코드 추가
Jokwanhee Nov 7, 2024
d3fbb24
[add] 동일 과목 활성화 구현
Jokwanhee Nov 8, 2024
9392a64
[fix] 시간표 색상 변경
Jokwanhee Nov 8, 2024
ae40eee
[add] sideEffect 추가 및 바텀 시트 모드 콜백 추가
Jokwanhee Nov 8, 2024
9242040
add: BusSearchScreen
ThirFir Nov 6, 2024
a439239
add: Compose ContraintLayout dependency
ThirFir Nov 6, 2024
837833d
add: ConstraintLayout 적용한 버스 조회 뷰
ThirFir Nov 6, 2024
38e3498
add: 프리뷰 추가
ThirFir Nov 6, 2024
8aef5c0
add: 조회하기 버튼 뷰
ThirFir Nov 6, 2024
51af37a
add: 버튼 onClick 임시
ThirFir Nov 6, 2024
70c9369
add: 임시 검색 로직
ThirFir Nov 6, 2024
83d2672
add: Button enabled 상태
ThirFir Nov 6, 2024
e594b67
add: place 선택 바텀시트
ThirFir Nov 7, 2024
f2fa9a4
chore: 패키지 정리
ThirFir Nov 7, 2024
85370a1
chore: TODO 주석
ThirFir Nov 7, 2024
39f5845
chore: 오타
ThirFir Nov 7, 2024
f7836da
add: BusSearchResultScreen 밑바탕
ThirFir Nov 7, 2024
286de42
add: Picker 컴포넌트
ThirFir Nov 7, 2024
be023b7
refactor: 무한스크롤 아닐 때 동작 처리
ThirFir Nov 7, 2024
a336d5e
chore: Compose bom 버전 업
ThirFir Nov 7, 2024
bfab6f1
add: 상단 Row
ThirFir Nov 7, 2024
09c9dd1
refactor: LazyColumn으로 변경
ThirFir Nov 7, 2024
3d6e006
add: PickerState에 Index 추가
ThirFir Nov 7, 2024
69916d1
add: 출발 시간 선택 다이얼로그
ThirFir Nov 7, 2024
0de03cc
add: 시간 뷰모델 로직
ThirFir Nov 7, 2024
ae5edcc
add: 시간 선택 뷰 로직
ThirFir Nov 7, 2024
a9f6059
add: 메인 액티비티 버스 진입 뷰
ThirFir Nov 8, 2024
07b1b67
add: 메인에서 버스 feature로의 진입
ThirFir Nov 8, 2024
c76d284
fix: Swap 아이콘 변경
ThirFir Nov 8, 2024
1bf8c6f
Merge remote-tracking branch 'origin/develop' into feature/bus-search
ThirFir Nov 8, 2024
afaa686
add: 버스 검색 결과 아이템 뷰
ThirFir Nov 8, 2024
193fc28
chore: 임시 데이터 포맷 수정
ThirFir Nov 8, 2024
0ce706e
add: 프리뷰
ThirFir Nov 8, 2024
d02ecc0
[Add] 시간표 학기 화면 추가
nodobi Nov 10, 2024
eec58f4
Merge branch 'develop' into feature/timetable_dialogs
nodobi Nov 10, 2024
14cac12
[Add] 학기 관련 유즈케이스 추가
nodobi Nov 10, 2024
c360843
add: 스테이지 로그 이벤트
skdud0629 Nov 10, 2024
ed7fb04
add: 스테이지 로그 이벤트
skdud0629 Nov 10, 2024
b24e5e1
[add] koin 모ㄹ compose bom 종속성 추가
Jokwanhee Nov 12, 2024
3813e2e
[add] resources 추가
Jokwanhee Nov 12, 2024
bd44273
[Add] feature/timetable 모듈에 compose-lifecycle 의존성 추가
nodobi Nov 12, 2024
f1084bf
add: picker unselected textstyle
ThirFir Nov 12, 2024
d96dd13
chore: minSdk를 24에서 26으로 상향
kongwoojin Nov 12, 2024
f75129a
Merge pull request #468 from BCSDLab/release
hsgo2430 Nov 12, 2024
a55d7ed
Merge pull request #464 from BCSDLab/add/stage_log_event
skdud0629 Nov 12, 2024
b602ddb
chore: Napier 코드 삭제
kongwoojin Nov 12, 2024
9e4924b
chore: Napier 라이브러리 삭제
kongwoojin Nov 12, 2024
12a7658
fix: 로깅
ThirFir Nov 12, 2024
1baaa6c
fix: MainActivity release/debug
ThirFir Nov 12, 2024
e14c593
[Add] 시간표 학기 화면 추가
nodobi Nov 12, 2024
46baeec
[Add] 시간표 학기 Ui 구현
nodobi Nov 12, 2024
1557d0e
Merge pull request #471 from BCSDLab/feature/remove-napier
kongwoojin Nov 13, 2024
4e5d3f9
[add] CustomSnackBarHost 구현
Jokwanhee Nov 13, 2024
b52d961
Merge pull request #469 from BCSDLab/feature/bump-minsdk-to-26
kongwoojin Nov 13, 2024
d391344
Merge pull request #463 from BCSDLab/feature/bus-search
ThirFir Nov 13, 2024
8b63b22
Merge pull request #472 from BCSDLab/feature/timetable_dialogs
nodobi Nov 13, 2024
fb4f1a8
[fix] 커스텀 스낵바 속성 추가
Jokwanhee Nov 13, 2024
24decd4
[add] Retrofit 널 반환 허용
Jokwanhee Nov 13, 2024
253de28
[fix] DTO 수정 및 연산 추가
Jokwanhee Nov 13, 2024
9bc85d7
[add] 요일 컴포넌트 추가
Jokwanhee Nov 13, 2024
ccbc10e
[fix] 학부 필터링 모달 수정
Jokwanhee Nov 13, 2024
42d2172
[add] TimeEditBox 수정
Jokwanhee Nov 13, 2024
dcffc78
[add] 상태 데이터 클래스 추가
Jokwanhee Nov 13, 2024
d844061
[fix] 다이어로그 수정
Jokwanhee Nov 13, 2024
0e8bcb8
[add] BitmapUtils 추가
Jokwanhee Nov 13, 2024
7494fec
[add] 코드 수정 및 추가
Jokwanhee Nov 13, 2024
ab35761
[add] 시간표 바텀시트 수정 및 추가
Jokwanhee Nov 13, 2024
3ef94b8
[add] string 리소스 추가
Jokwanhee Nov 13, 2024
563768f
[fix] 뷰모델 로직 수정 및 추가
Jokwanhee Nov 13, 2024
4695d8a
[add] KoinPicker 구현
Jokwanhee Nov 13, 2024
6cd2ed6
[fix] 시간표 액티비티 코드 수정 및 추가
Jokwanhee Nov 13, 2024
c9ead66
[fix] TimetableLecture 테스트 코드 수정
Jokwanhee Nov 13, 2024
80d7d6e
[fix] 익명 여부 false 수정
Jokwanhee Nov 13, 2024
cd8facc
Merge remote-tracking branch 'origin/develop' into feature/timetable_…
Jokwanhee Nov 13, 2024
73f4f54
[fix] KoinPicker 변경 및 gradient 추가
Jokwanhee Nov 13, 2024
437e911
[fix] KoinPicker 수정
Jokwanhee Nov 13, 2024
73a44a9
[add] TimetableSemesterActivity 연결
Jokwanhee Nov 13, 2024
f55322a
[add] dialog 흰색 배경 추가
Jokwanhee Nov 13, 2024
179295d
Merge pull request #473 from BCSDLab/feature/timetable_api_v3
Jokwanhee Nov 14, 2024
3ee2dc1
[del] onSwitch 제거
Jokwanhee Nov 16, 2024
3366103
[fix] update v4.0.6
Jokwanhee Nov 16, 2024
d746cf4
Merge pull request #476 from BCSDLab/hotfix/notification_logging
Jokwanhee Nov 16, 2024
c28cbf3
add: 식단 더보기 AB테스트
ThirFir Nov 18, 2024
02c7742
del: 로그
ThirFir Nov 18, 2024
8adb1dd
Merge pull request #477 from BCSDLab/feature/dining-main-abtest
ThirFir Nov 18, 2024
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
Expand Up @@ -20,7 +20,7 @@ internal fun configureAndroidProject(
it.defaultConfig.targetSdk = 34
}
defaultConfig {
minSdk = 24
minSdk = 26
testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ buildscript {
}

extra.apply {
set("versionName", "4.0.5")
set("versionCode", 40005)
set("versionName", "4.0.6")
set("versionCode", 40006)
// 코인 버전 관리

set("versionBusinessName", "1.0.1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathEffect
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawOutline
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

/**
* 리플 효과 없는 Clickable
Expand All @@ -24,4 +35,44 @@ fun Modifier.noRippleClickable(
role = role,
onClick = onClick
)
}

/**
* 점선(-) 테두리
*/
fun Modifier.dashedBorder(
color: Color,
shape: Shape,
strokeWidth: Dp = 1.dp,
dashLength: Dp = 3.dp,
gapLength: Dp = 3.dp,
cap: StrokeCap = StrokeCap.Round
) = dashedBorder(brush = SolidColor(color), shape, strokeWidth, dashLength, gapLength, cap)

private fun Modifier.dashedBorder(
brush: Brush,
shape: Shape,
strokeWidth: Dp,
dashLength: Dp,
gapLength: Dp,
cap: StrokeCap = StrokeCap.Round
) = this.drawWithContent {

val outline = shape.createOutline(size, layoutDirection, density = this)

val dashedStroke = Stroke(
cap = cap,
width = strokeWidth.toPx(),
pathEffect = PathEffect.dashPathEffect(
intervals = floatArrayOf(dashLength.toPx(), gapLength.toPx())
)
)

drawContent()

drawOutline(
outline = outline,
style = dashedStroke,
brush = brush
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum class FilledButtonColors {
Primary,
Warning,
Danger,
Success
}

@Composable
Expand Down Expand Up @@ -99,6 +100,13 @@ internal fun filledButtonColorByType(type: FilledButtonColors): ButtonColors = w
disabledContainerColor = KoinTheme.colors.neutral300,
disabledContentColor = KoinTheme.colors.neutral600
)

FilledButtonColors.Success -> ButtonColors(
containerColor = KoinTheme.colors.success700,
contentColor = KoinTheme.colors.neutral0,
disabledContainerColor = KoinTheme.colors.neutral300,
disabledContentColor = KoinTheme.colors.neutral600
)
}

@Preview
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package `in`.koreatech.koin.core.designsystem.component.picker

import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Brush.Companion.verticalGradient
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import `in`.koreatech.koin.core.designsystem.theme.KoinTheme
import kotlinx.coroutines.flow.map

/**
* 아이템 피커
* @param items 아이템 리스트
* @param pickerState PickerState
* @param visibleItemsCount 보여질 아이템 수
* @param modifier Modifier
* @param infiniteScroll 무한 스크롤 여부
* @param brushVerticalGradient vertical Brush 그라디언트 설정
* @param startIndex 시작 인덱스
* @param contentPadding 아이템 내부 Padding
* @param selectedTextStyle 선택 아이템 텍스트 스타일
* @param unselectedTextStyle 선택되지 않은 아이템 텍스트 스타일
* @param selectedItemColor 선택 아이템 색상
* @param unselectedItemColor 선택되지 않은 아이템 색상
*/
@Composable
fun KoinPicker(
items: List<String>,
pickerState: PickerState,
visibleItemsCount: Int,
modifier: Modifier = Modifier,
infiniteScroll: Boolean = true,
brushVerticalGradient: Brush = verticalGradient(),
startIndex: Int = 0,
contentPadding: PaddingValues = PaddingValues(vertical = 2.dp),
selectedTextStyle: TextStyle = KoinTheme.typography.medium16,
unselectedTextStyle: TextStyle = KoinTheme.typography.medium16,
selectedItemColor: Color = KoinTheme.colors.primary500,
unselectedItemColor: Color = KoinTheme.colors.neutral500,
) {

val newItems = if (infiniteScroll) items
else List(visibleItemsCount / 2) { "" } + items + List(visibleItemsCount / 2) { "" }

val visibleItemsMiddle = visibleItemsCount / 2
val listScrollCount = if (infiniteScroll) Int.MAX_VALUE else newItems.size
val listScrollMiddle = listScrollCount / 2
val listStartIndex =
(listScrollMiddle - listScrollMiddle % newItems.size - visibleItemsMiddle + startIndex).coerceAtLeast(startIndex)

val listState = rememberLazyListState(initialFirstVisibleItemIndex = listStartIndex)
val flingBehavior = rememberSnapFlingBehavior(lazyListState = listState)

var selectedItemIndex by remember { mutableIntStateOf(startIndex) }

var itemHeight by remember { mutableStateOf(0.dp) }
val density = LocalDensity.current

val fadingEdgeGradient = remember { brushVerticalGradient }

LazyColumn(
state = listState,
flingBehavior = flingBehavior,
modifier = modifier
.height(itemHeight * visibleItemsCount)
.fadingEdge(fadingEdgeGradient),
) {
items(listScrollCount) { index ->
Text(
text = newItems.getItem(index),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = if (selectedItemIndex == index) selectedTextStyle else unselectedTextStyle,
color = if (selectedItemIndex == index) selectedItemColor else unselectedItemColor,
modifier = Modifier
.fillMaxSize()
.onSizeChanged {
itemHeight = with(density) {
it.height.toDp()
}
}
.padding(contentPadding)
)
}
}

LaunchedEffect(listState) {
snapshotFlow {
listState.firstVisibleItemIndex
}.map { index ->
index + visibleItemsMiddle
}.collect { middle ->
selectedItemIndex = middle
pickerState.selectedItem = newItems.getItem(middle)
pickerState.selectedItemIndex = middle % newItems.size - if (infiniteScroll.not()) visibleItemsMiddle else 0
}
}
}

@Composable
fun rememberPickerState() = remember { PickerState() }

class PickerState internal constructor() {
var selectedItem by mutableStateOf("")
var selectedItemIndex by mutableIntStateOf(0)
}

private fun Modifier.fadingEdge(brush: Brush) = this
.graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen)
.drawWithContent {
drawContent()
drawRect(brush = brush, blendMode = BlendMode.DstIn)
}


private fun List<String>.getItem(index: Int) = this[index % this.size]
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package `in`.koreatech.koin.core.designsystem.component.snackbar

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import `in`.koreatech.koin.core.designsystem.noRippleClickable
import `in`.koreatech.koin.core.designsystem.theme.KoinTheme

// Surface 사용하지 않을 경우, SnackBar 커스텀
@Composable
fun CustomSnackBarHost(
hotState: SnackbarHostState,
radius: Dp = 0.dp,
messageTextStyle: TextStyle = KoinTheme.typography.regular12.copy(
color = Color.White
),
actionLabelTextStyle: TextStyle = KoinTheme.typography.regular12.copy(
color = Color.White
),
background: Color = Color.Black,
alignment: Alignment = Alignment.BottomCenter,
paddingValues: PaddingValues = PaddingValues(bottom = 20.dp, start = 10.dp, end = 10.dp),
innerPaddingValues: PaddingValues = PaddingValues(horizontal = 10.dp, vertical = 16.dp)
) {
SnackbarHost(
hostState = hotState,
) { snackbarData ->
SnackBarContent(
messageText = snackbarData.visuals.message,
actionLabelText = snackbarData.visuals.actionLabel ?: "",
radius = radius,
background = background,
messageTextStyle = messageTextStyle,
actionLabelTextStyle = actionLabelTextStyle,
alignment = alignment,
paddingValues = paddingValues,
innerPaddingValues = innerPaddingValues,
onAction = { snackbarData.dismiss() }
)
}

}

@Composable
private fun SnackBarContent(
messageText: String,
actionLabelText: String,
modifier: Modifier = Modifier,
radius: Dp = 0.dp,
background: Color = Color.Black,
messageTextStyle: TextStyle = KoinTheme.typography.regular12.copy(
color = Color.White
),
actionLabelTextStyle: TextStyle = KoinTheme.typography.regular12.copy(
color = Color.White
),
alignment: Alignment = Alignment.BottomCenter,
paddingValues: PaddingValues = PaddingValues(bottom = 20.dp, start = 10.dp, end = 10.dp),
innerPaddingValues: PaddingValues = PaddingValues(horizontal = 10.dp, vertical = 16.dp),
onAction: () -> Unit = {}
) {
Box(
modifier = modifier
.fillMaxSize()
.padding(paddingValues),
contentAlignment = alignment
) {
Box(
modifier = modifier
.fillMaxWidth()
.clip(RoundedCornerShape(radius))
.background(background)
.padding(innerPaddingValues)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = Modifier.width(4.dp))
Text(
text = messageText,
style = messageTextStyle,
modifier = Modifier.weight(1f),
)
Spacer(modifier = Modifier.weight(0.05f))
if (actionLabelText.isNotEmpty()) {
Text(
text = actionLabelText,
style = actionLabelTextStyle,
modifier = Modifier.weight(0.1f).noRippleClickable { onAction() }
)
}

}
}
}
}

fun SnackbarHostState.dismissIfShown() {
if (currentSnackbarData != null) {
currentSnackbarData?.dismiss()
}
}

suspend fun SnackbarHostState.showSnackBarWithDismiss(
message: String,
actionLabel: String = "",
duration: SnackbarDuration = SnackbarDuration.Short
) {
dismissIfShown()
showSnackbar(
message = message,
actionLabel = actionLabel,
duration = duration
)
}

@Preview(showBackground = true, showSystemUi = true)
@Composable
private fun SnackBarContentPreview() {
SnackBarContent(
messageText = "스낵바 메시지",
actionLabelText = "닫기",
)
}
Loading
Loading