Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7f065a8
mod/#61 로그인 및 회원가입 로직 수정
sonms Jan 21, 2026
294a373
mod/#61 qa 2차 반영 및 자녀 회원가입 로직 수정
sonms Jan 21, 2026
af816e0
feat/#61 자녀 소원 화면 로직 및 UI 수정
sonms Jan 21, 2026
988eba0
feat/#61 회원가입 QA 및 버그 수정
sonms Jan 21, 2026
e887d8c
fix/#61 SSE 연결 및 모델 수정
sonms Jan 21, 2026
45b554a
feat: 자녀 화면 SSE 이벤트 구독 및 실시간 데이터 갱신 기능 추가
sonms Jan 21, 2026
1614210
mod/#61 SseManager 구독 로직 리팩토링 및 안정성 강화
Jan 22, 2026
456161f
feat/#61 SSE 실시간 데이터 반영
Jan 22, 2026
9c46662
mod/#61 QA 반영 - 키보드 외 클릭 시 키보드 내리기
Jan 22, 2026
059dc22
mod/#61 QA 반영 - 텍스트 가운데 정렬
Jan 22, 2026
de8c5d5
feat/#61 탭 클릭 시 새로고침 기능 추가
Jan 22, 2026
3ca5eea
mod/#61 버그 수정 및 QA 2차 반영
sonms Jan 22, 2026
903bce2
Merge branch 'develop' of https://github.com/Team-Kiero/Kiero-Android…
sonms Jan 22, 2026
2c2e85d
Merge branch 'develop' of https://github.com/Team-Kiero/Kiero-Android…
sonms Jan 22, 2026
a74e8cc
Merge branch 'develop' of https://github.com/Team-Kiero/Kiero-Android…
sonms Jan 22, 2026
60e0902
Merge branch 'develop' of https://github.com/Team-Kiero/Kiero-Android…
sonms Jan 22, 2026
b8a6314
mod/#61: KieroLoadingIndicator 내 로딩 애니메이션 반복 횟수 및 완료 콜백(onSuccess) 추가…
seungjae708 Jan 22, 2026
d06eefb
Merge branch 'mod/#61-qa-reflect-four' of https://github.com/Team-Kie…
sonms Jan 22, 2026
36710b0
feat/#61: Presigned URL을 이용한 S3 이미지 업로드 기능 추가
sonms Jan 22, 2026
451696c
refactor/#61: S3 서비스 추가 및 관련 코드 수정
sonms Jan 22, 2026
6b2f7fe
feat/#61: QA 반영 및 로그아웃 로직 수정
sonms Jan 22, 2026
e829633
feat/#61: 부모 알림 화면 `Pull to Refresh` 기능 추가 및 UI/로직 개선
sonms Jan 22, 2026
ce94965
feat/#61: 자녀 회원가입 시 데모 데이터 생성 및 미션/소원 화면 개선
sonms Jan 22, 2026
731daf6
fix: `BaseResponse`를 `Response`로 변경
sonms Jan 22, 2026
a40b2e3
refactor/#61: 카메라 기능 및 전반적인 UI/로직 수정
sonms Jan 22, 2026
5abad0d
refactor/#61: 미션 이름 수정 시 커서 위치 유지 및 코드 개선
sonms Jan 23, 2026
65ecbb5
feat/#61: 스플래시 화면 로직 수정 및 UI 개선
sonms Jan 23, 2026
3104008
refactor/#61: Coil 이미지 로더 설정 최적화 및 탐색 로직 개선
sonms Jan 23, 2026
f83ff33
refactor/#61: 알림장 분석 실패 시 예외 처리 개선
sonms Jan 23, 2026
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
23 changes: 22 additions & 1 deletion app/src/main/java/com/kiero/KieroApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import coil.ImageLoader
import coil.ImageLoaderFactory
import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder
import coil.disk.DiskCache
import coil.memory.MemoryCache
import coil.util.DebugLogger
import com.kakao.sdk.common.KakaoSdk
import dagger.hilt.android.HiltAndroidApp
import timber.log.Timber
Expand All @@ -30,6 +33,7 @@ class KieroApplication : Application(), ImageLoaderFactory {
private fun setDayMode() {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}

private fun initKakaoSdk() {
try {
KakaoSdk.init(this, BuildConfig.KAKAO_NATIVE_APP_KEY)
Expand All @@ -49,8 +53,25 @@ class KieroApplication : Application(), ImageLoaderFactory {
add(GifDecoder.Factory())
}
}
.memoryCache {
MemoryCache.Builder(this)
.maxSizePercent(0.25)
.build()
}
.diskCache {
DiskCache.Builder()
.directory(cacheDir.resolve("image_cache"))
.maxSizeBytes(50L * 1024 * 1024)
.build()
}
.crossfade(false)
.bitmapConfig(Bitmap.Config.HARDWARE)
.respectCacheHeaders(false)
.apply {
if (BuildConfig.DEBUG) {
logger(DebugLogger())
}
}
.build()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import coil.drawable.MovieDrawable
import coil.request.ImageRequest
import coil.request.onAnimationEnd
import coil.request.repeatCount
import coil.size.Precision

@Composable
fun KieroGifImage(
Expand All @@ -24,6 +25,7 @@ fun KieroGifImage(
val imageRequest = remember(drawableId) {
ImageRequest.Builder(context)
.data(drawableId)
.precision(Precision.INEXACT)
.bitmapConfig(Bitmap.Config.ARGB_8888)
.allowHardware(false)
.repeatCount(repeatCount)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ fun KieroButtonMedium(
enabled = isEnabled,
modifier = modifier.fillMaxWidth(),
shape = RoundedCornerShape(8.dp),
color = if (isEnabled) containerColor else KieroTheme.colors.gray300,
contentColor = if (isEnabled) contentColor else KieroTheme.colors.gray600
color = if (isEnabled) containerColor else KieroTheme.colors.gray900,
contentColor = if (isEnabled) contentColor else KieroTheme.colors.white
) {
Row(
modifier = Modifier.padding(vertical = 13.dp, horizontal = 16.dp),
Expand Down Expand Up @@ -76,7 +76,7 @@ private fun KieroButtonMediumPreview() {
horizontalAlignment = Alignment.CenterHorizontally
) {
KieroButtonMedium(
text = "시작하기", onClick = { })
text = "시작하기", onClick = { }, isEnabled = false)
KieroButtonMedium(
text = "일정 추가하기",
leadingIcon = ImageVector.vectorResource(id = com.kiero.R.drawable.ic_kid_camera),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ class KieroCoinAction(
contentDescription = null,
modifier = Modifier
.size(20.dp)
.forcePixelToDp(coin)
)

Text(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
Expand All @@ -21,6 +22,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
Expand Down Expand Up @@ -87,13 +89,15 @@ fun KieroDialog(

Spacer(modifier = Modifier.height(4.dp))

Text(
text = title.orEmpty(),
color = KieroTheme.colors.white,
style = KieroTheme.typography.semiBold.title2,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center
)
if (title != null) {
Text(
text = title.orEmpty(),
color = KieroTheme.colors.white,
style = KieroTheme.typography.semiBold.title2,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center
)
}

if (content != null) {
content()
Expand Down Expand Up @@ -133,7 +137,7 @@ private fun KieroDialogPreview() {
KieroTheme {
KieroDialog(
onDismiss = {},
title = "제목",
title = null,
subDescription = "로그아웃 하시겠습니까?",

cancelAction = KieroCancelAction(
Expand All @@ -144,25 +148,19 @@ private fun KieroDialogPreview() {
text = "확인",
onClick = {}
),

isDisabled = true,
content = {
Row(verticalAlignment = Alignment.CenterVertically) {
val coinImage = painterResource(R.drawable.img_kid_coin)

Image(
painter = coinImage,
contentDescription = null,
modifier = Modifier.forcePixelToDp(coinImage)
)

Spacer(modifier = Modifier.width(10.dp))

Text(
text = "150 개",
color = KieroTheme.colors.main,
style = KieroTheme.typography.semiBold.title4,
val coinImage = painterResource(R.drawable.img_kid_camera_goblin)

Image(
painter = coinImage,
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.size(
width = 62.dp,
height = 70.dp
)
}
)
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import coil.drawable.MovieDrawable
import com.kiero.R
import com.kiero.core.designsystem.component.KieroGifImage
import com.kiero.core.designsystem.theme.KieroTheme

@Composable
fun KieroLoadingIndicator() {
fun KieroLoadingIndicator(
repeatCount : Int = MovieDrawable.REPEAT_INFINITE,
onSuccess: () -> Unit = {}
) {
Box(
modifier = Modifier
.fillMaxSize()
Expand All @@ -20,6 +24,8 @@ fun KieroLoadingIndicator() {
) {
KieroGifImage(
drawableId = R.drawable.gif_loading,
repeatCount = repeatCount,
onSuccess = onSuccess
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ import androidx.compose.runtime.Immutable
@Immutable
data class SnackbarState(
val message: String = "",
val bottomPadding: Int = 90
)
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ class AuthDataSourceImpl @Inject constructor(
val accountCallback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
when {
error != null -> {
Timber.e(error, "❌ 카카오 계정 로그인 실패")
continuation.resume(Result.failure(error))
if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
Timber.d("⚠️ 사용자 웹 로그인 취소")
continuation.resume(Result.failure(error))
} else {
Timber.e(error, "❌ 카카오 계정 로그인 실패")
continuation.resume(Result.failure(error))
}
}
token != null -> {
Timber.i("✅ 카카오 계정 로그인 성공")
Expand Down Expand Up @@ -89,4 +94,4 @@ class AuthDataSourceImpl @Inject constructor(
override suspend fun postAuthKidLogin(authKidRequestDto: AuthKidRequestDto): BaseResponse<AuthKidResponseDto> =
authService.postAuthKidLogin(body = authKidRequestDto)

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class TokenRefreshServiceImpl @Inject constructor(
) : TokenRefreshService {
override suspend fun refresh(refreshToken: String, role: UserRole): Result<Pair<AccessToken, RefreshToken>> = suspendRunCatching {
val response = when (role) {
UserRole.PARENT -> reissueService.reissueAccessToken("Bearer $refreshToken")
UserRole.PARENT -> reissueService.reissueAccessToken("refreshToken=$refreshToken")
UserRole.KID -> reissueService.reissueToken("refreshToken=$refreshToken")
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.kiero.data.demo.remote.api

import com.kiero.core.network.model.BaseResponse
import retrofit2.Response
import retrofit2.http.DELETE
import retrofit2.http.POST

interface DemoService {
@DELETE("api/v1/dummy")
suspend fun deleteDemo(): BaseResponse<Unit>
suspend fun deleteDemo(): Response<Unit>

@POST("api/v1/dummy")
suspend fun postDemo(): BaseResponse<Unit>
suspend fun postDemo(): Response<Unit>
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.kiero.data.demo.remote.datasource

import com.kiero.core.network.model.BaseResponse
import retrofit2.Response

interface DemoDataSource {
suspend fun deleteDemo(): BaseResponse<Unit>
suspend fun deleteDemo(): Response<Unit>

suspend fun postDemo(): BaseResponse<Unit>
suspend fun postDemo(): Response<Unit>
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.kiero.data.demo.remote.datasourceimpl

import com.kiero.core.network.model.BaseResponse
import com.kiero.data.demo.remote.api.DemoService
import com.kiero.data.demo.remote.datasource.DemoDataSource
import retrofit2.Response
import javax.inject.Inject

class DemoDataSourceImpl @Inject constructor(
private val demoService: DemoService
) : DemoDataSource {
override suspend fun deleteDemo(): BaseResponse<Unit> = demoService.deleteDemo()
override suspend fun deleteDemo(): Response<Unit> = demoService.deleteDemo()

override suspend fun postDemo(): BaseResponse<Unit> = demoService.postDemo()
override suspend fun postDemo(): Response<Unit> = demoService.postDemo()
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.kiero.data.kid.schedule.di

import com.kiero.core.network.di.AuthNetwork
import com.kiero.data.kid.schedule.remote.api.S3Service
import com.kiero.data.kid.schedule.remote.api.ScheduleService
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.create
import javax.inject.Singleton
Expand All @@ -19,4 +21,14 @@ object ScheduleServiceModule {
@AuthNetwork retrofit: Retrofit
): ScheduleService =
retrofit.create()

@Provides
@Singleton
fun provideS3Service(): S3Service {
return Retrofit.Builder()
.baseUrl("https://s3.ap-northeast-2.amazonaws.com/")
.client(OkHttpClient.Builder().build())
.build()
.create(S3Service::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.kiero.data.kid.schedule.model

import com.kiero.data.kid.schedule.remote.dto.response.PresignedUrlResponse

data class PresignedUrlModel(
val presignedUrl: String,
val fileName: String
)

fun PresignedUrlResponse.toModel() = PresignedUrlModel(
presignedUrl = this.data.presignedUrl,
fileName = this.data.fileName
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.kiero.data.kid.schedule.remote.api

import okhttp3.RequestBody
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.PUT
import retrofit2.http.Url

interface S3Service {
@PUT
suspend fun uploadImageToS3(
@Url url: String,
@Body image: RequestBody
): Response<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ import com.kiero.data.kid.schedule.remote.dto.response.ScheduleFireResponseDto
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleImageUploadResponseDto
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleSkipResponseDto
import com.kiero.data.kid.schedule.remote.dto.response.ScheduleTodayResponseDto
import okhttp3.RequestBody
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.PATCH
import retrofit2.http.POST
import retrofit2.http.PUT
import retrofit2.http.Path
import retrofit2.http.Url

interface ScheduleService {
@PATCH("api/v1/schedules/today")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.kiero.data.kid.schedule.remote.dto.response

import com.google.gson.annotations.SerializedName

data class PresignedUrlResponse(
@SerializedName("status") val status: Int,
@SerializedName("message") val message: String,
@SerializedName("data") val data: PresignedUrlData
)

data class PresignedUrlData(
@SerializedName("presignedUrl") val presignedUrl: String,
@SerializedName("fileName") val fileName: String
)
Loading