Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0da5765
[feat] #78 URL 상수 정의
kamja0510 Jan 16, 2026
8b6ebe7
[feat] #78 이용 약관 enum 타입에 Url 변수 추가
kamja0510 Jan 16, 2026
c66a82c
[feat] #78 약관 Row의 arrow 아이콘 클릭 시 노션 페이지 띄우도록 구현
kamja0510 Jan 16, 2026
24d5611
[feat] #78 프로필 사진 기본 이미지 수정
kamja0510 Jan 16, 2026
d446081
[feat] #78 온보딩 pager 1,2 페이지에 사진 추가
kamja0510 Jan 16, 2026
7e49627
[refactor] #78 온보딩 프로필 사진 설정 화면에서 profileImagePath를 Uri객체에서 String 객체…
kamja0510 Jan 16, 2026
7384ba4
[refactor] #78 프로필 사진 영역 컴포넌트화
kamja0510 Jan 16, 2026
129b87a
[feat] #78 setting screen 웹뷰 띄우기 로직 구현
kamja0510 Jan 17, 2026
cd72590
[fix] #78 프로필 수정 api 에서 닉네임 수정 안되는 오류 수정
kamja0510 Jan 17, 2026
ff5c2fd
[feat] #78 등록하기 클릭 후 홈으로 이동 구현
kamja0510 Jan 17, 2026
c732e4f
[feat] #78 커뮤니티 가이드 버튼 클릭 시 커뮤니티 가이드 노션 페이지로 이동 구현
kamja0510 Jan 17, 2026
a2afd84
[feat] #78 보관한 곡 클릭 시 곡 상세 페이지로 이동 구현
kamja0510 Jan 17, 2026
b1a21f9
[feat] #78 MyPage Screen의 함수들 드릴링 하고 bottomNavigationController 만들어 전…
kamja0510 Jan 18, 2026
0bb63e0
[feat] #78 케밥 아이콘 클릭 시 바텀시트 올라오도록 구현
kamja0510 Jan 18, 2026
9e1be81
Merge branch 'develop' into feat/#78-qa-1-ui
kamja0510 Jan 18, 2026
87f36f1
[fix] #78 bottomsheet 디자인 수정
kamja0510 Jan 18, 2026
6ec71d0
[feat] #78 등록한 곡 삭제 구현
kamja0510 Jan 18, 2026
a3f2b5f
[feat] #78 navDisplay의 애니메이션 다 없에고 bottombar에 애니메이션 추가
kamja0510 Jan 18, 2026
7fa46e4
[feat] #78 bottomBar에 애니메이션 되돌리기
kamja0510 Jan 18, 2026
8a12512
[feat] #78 등록된 곡 클릭 시 상세 곡 페이지로 이동
kamja0510 Jan 18, 2026
bdf8c38
[feat] #78 알림 권한 붙이기 아직 안됨
kamja0510 Jan 18, 2026
57e98f6
[chore] #78 ktlint
kamja0510 Jan 18, 2026
8433350
[feat] #78 splash 시간 상수 1000L으로 변경
kamja0510 Jan 18, 2026
24f5c6d
Merge branch 'develop' into feat/#78-qa-1-ui
kamja0510 Jan 18, 2026
5c71b12
[feat] #78 baseimage 처리 구현
kamja0510 Jan 18, 2026
6c8df6c
[feat] #78 탭 로우 아래에 회색 박스 두기
kamja0510 Jan 18, 2026
3a6789d
[chore] #78 ktlint
kamja0510 Jan 20, 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
21 changes: 21 additions & 0 deletions core/common/src/main/java/com/example/common/constant/Url.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.example.common.constant

object Url {
// 서비스 이용 약관
const val TERMS_OF_SERVICE = "https://www.notion.so/2d13aeb558c9801fb8c2db2ae6ac2c3e?source=copy_link"

// 개인정보 처리 방침
const val PRIVACY_POLICY = "https://www.notion.so/2d13aeb558c98003b480f83b06245430?source=copy_link"

// 공지사항
const val ANNOUNCEMENT = "https://www.notion.so/2d13aeb558c980919796c2b4d7109369?source=copy_link"

// 커뮤니티 가이드
const val COMMUNITY_GUIDE = "https://www.notion.so/2d13aeb558c980c7915bf540db799aac?source=copy_link"

// 문의/제안하기
const val INQUIRY = "https://forms.gle/reQb2nmhjSqXVvnq7"

// 에러 뷰
const val ERROR = ""
Comment on lines +19 to +20
Copy link

Copilot AI Jan 18, 2026

Choose a reason for hiding this comment

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

ERROR 상수가 빈 문자열로 정의되어 있습니다. 빈 문자열을 URL로 사용하면 의도하지 않은 동작이 발생할 수 있습니다. null을 반환하거나 유효한 에러 페이지 URL을 제공하는 것이 좋습니다.

Suggested change
// 에러 뷰
const val ERROR = ""
// 에러 뷰 - 빈 문자열 대신 안전한 기본 에러 URL 사용
const val ERROR = "about:blank"

Copilot uses AI. Check for mistakes.
}
7 changes: 5 additions & 2 deletions core/common/src/main/java/com/example/common/type/TermType.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.example.common.type

import com.example.common.constant.Url

enum class TermType(
val isMandatory: Boolean,
val url: String,
) {
TERMS_OF_SERVICE(isMandatory = true), // 서비스 이용약관 (필수)
PRIVACY_POLICY(isMandatory = true), // 개인정보 처리방침 (필수)
TERMS_OF_SERVICE(isMandatory = true, url = Url.TERMS_OF_SERVICE), // 서비스 이용약관 (필수)
PRIVACY_POLICY(isMandatory = true, url = Url.PRIVACY_POLICY), // 개인정보 처리방침 (필수)
;

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.data.datasource.remote

import com.example.data.model.request.NotificationRequest
import com.example.data.model.request.PatchProfileRequest
import com.example.data.model.response.UserInfoResponse
import com.example.data.service.UserService
import kotlinx.serialization.InternalSerializationApi
Expand Down Expand Up @@ -32,7 +33,10 @@ class UserRemoteDataSource

userService.patchProfile(
profileImg = imagePart,
request = nickname,
request =
PatchProfileRequest(
nickname,
),
)
} catch (e: Exception) {
Timber.e(e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ fun UserResponse.toDomain(): Writer =
Writer(
userId = this.userId,
nickname = this.nickname,
profileImg = this.profileImg ?: "",
profileImg = this.profileImg,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.data.model.request

import kotlinx.serialization.Serializable

@Serializable
data class PatchProfileRequest(
val nickname: String?,
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.example.data.constant.ApiConstants.SCRAPS
import com.example.data.constant.ApiConstants.USERS
import com.example.data.constant.ApiConstants.VERSIONS
import com.example.data.model.request.NotificationRequest
import com.example.data.model.request.PatchProfileRequest
import com.example.data.model.response.BaseResponse
import com.example.data.model.response.NotificationResponse
import com.example.data.model.response.RegisteredTracksResponse
Expand All @@ -30,7 +31,7 @@ interface UserService {
@PATCH("$API/$VERSIONS/$USERS/$ME")
suspend fun patchProfile(
@Part profileImg: MultipartBody.Part?,
@Part("nickname") request: String?,
@Part("changeProfileRequest") request: PatchProfileRequest,
Copy link

Copilot AI Jan 18, 2026

Choose a reason for hiding this comment

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

@part 어노테이션에서 @part("changeProfileRequest")로 복잡한 객체를 전달하고 있는데, Multipart 요청에서는 일반적으로 JSON 객체를 @part로 직접 전달할 수 없습니다. RequestBody로 변환하거나 각 필드를 개별 @part로 전달해야 합니다. 현재 구현은 서버 요청이 실패할 가능성이 높습니다.

Copilot uses AI. Check for mistakes.
): BaseResponse<Unit>

@GET("$API/$VERSIONS/$USERS/{userId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fun DPlayLargeCover(
isBookmarkChecked: Boolean,
isLikeChecked: Boolean,
likeCount: Int,
writerProfileImageUrl: String,
writerProfileImageUrl: String?,
writerNickname: String,
content: String,
musicImageUrl: String,
Expand Down Expand Up @@ -130,7 +130,7 @@ fun DPlayLargeCover(
modifier = Modifier.noRippleClickable(onClick = onWriterProfileClick),
) {
AsyncImage(
model = writerProfileImageUrl,
model = writerProfileImageUrl ?: R.drawable.base_profile_image,
contentDescription = null,
modifier =
Modifier
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.example.designsystem.component

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.shape.CircleShape
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.layout.ContentScale
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import com.dplay.designsystem.R
import com.example.designsystem.theme.DPlayTheme
import com.example.designsystem.util.noRippleClickable

@Composable
fun DPlayProfileImageArea(
onProfileImageClick: () -> Unit,
profileImagePath: String?,
modifier: Modifier = Modifier,
content: @Composable () -> Unit = {},
) {
Box(
modifier =
modifier
.noRippleClickable(
onClick = { onProfileImageClick() },
),
contentAlignment = Alignment.BottomEnd,
) {
AsyncImage(
model = profileImagePath ?: R.drawable.base_profile_image,
contentDescription = null,
modifier =
Modifier
.clip(CircleShape)
.border(
width = 1.dp,
color = DPlayTheme.colors.gray200,
shape = CircleShape,
),
contentScale = ContentScale.Crop,
)
Comment on lines +35 to +44
Copy link

Copilot AI Jan 18, 2026

Choose a reason for hiding this comment

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

Box에 적용된 modifier (size 포함)가 AsyncImage로 전달되지 않고 있습니다. AsyncImage에 matchParentSize() 또는 fillMaxSize()를 적용하지 않으면 이미지가 Box의 크기를 채우지 못합니다. AsyncImage의 modifier를 Modifier.matchParentSize()로 시작하도록 수정해야 합니다.

Copilot uses AI. Check for mistakes.

content()
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ package com.example.domain.model
data class Writer(
val userId: Long,
val nickname: String,
val profileImg: String,
val profileImg: String?,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.example.ui.controller

import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue

class BottomNavigationController {
var bottomNavigationVisible by mutableStateOf(true)
private set

fun show() {
bottomNavigationVisible = true
}

fun hide() {
bottomNavigationVisible = false
}
}

val LocalBottomNavigationController =
compositionLocalOf<BottomNavigationController> {
error("BottomNavigationController not provided")
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,9 @@ class CommentContract {
data object NavigateToBack : CommentSideEffect

data object NavigateToHome : CommentSideEffect

data class OpenWebView(
val url: String,
) : CommentSideEffect
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -47,6 +48,8 @@ fun CommentRoute(
) {
val state by viewModel.uiState.collectAsStateWithLifecycle()

val uriHandler = LocalUriHandler.current

LaunchedEffect(track) {
viewModel.handleIntent(CommentContract.CommentIntent.Initialize(track))
}
Expand All @@ -60,6 +63,9 @@ fun CommentRoute(
CommentContract.CommentSideEffect.NavigateToHome -> {
navigator.clearAndNavigateTo(Home)
}
is CommentContract.CommentSideEffect.OpenWebView -> {
uriHandler.openUri(sideEffect.url)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.example.comment

import androidx.lifecycle.viewModelScope
import com.example.common.constant.Url
import com.example.domain.repository.PostRepository
import com.example.ui.base.BaseViewModel
import com.example.ui.model.TrackState
Expand Down Expand Up @@ -42,7 +43,7 @@ class CommentViewModel
}
}
CommentContract.CommentIntent.OnMoreGuideClick -> {
// 가이드 노션으로 이동
setSideEffect(CommentContract.CommentSideEffect.OpenWebView(Url.COMMUNITY_GUIDE))
}
CommentContract.CommentIntent.OnRegisterButtonClick -> {
registerPost()
Expand All @@ -59,7 +60,7 @@ class CommentViewModel
track = track,
comment = currentState.commentInput,
).onSuccess {
setSideEffect(CommentContract.CommentSideEffect.NavigateToBack)
setSideEffect(CommentContract.CommentSideEffect.NavigateToHome)
}.onFailure {
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ private fun DetailScreen(
verticalAlignment = Alignment.CenterVertically,
) {
AsyncImage(
model = state.writer.profileImg,
model = state.writer.profileImg ?: R.drawable.base_profile_image,
contentDescription = null,
modifier =
Modifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
Expand All @@ -17,22 +16,19 @@ 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.shape.CircleShape
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.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil3.compose.AsyncImage
import com.dplay.designsystem.R
import com.example.designsystem.component.DPlayButtonBottomSheet
import com.example.designsystem.component.DPlayProfileImageArea
import com.example.designsystem.component.DplayLeftIconTitleTopAppBar
import com.example.designsystem.component.button.DPlayCircleButton
import com.example.designsystem.component.button.DPlayLargePinkButton
Expand Down Expand Up @@ -136,36 +132,20 @@ fun EditProfileScreen(

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

Box(
DPlayProfileImageArea(
onProfileImageClick = onProfileImageClick,
profileImagePath = state.profileImagePath,
modifier =
Modifier
.align(Alignment.CenterHorizontally)
.noRippleClickable(
onClick = { onProfileImageClick() },
),
.size(116.dp)
.align(Alignment.CenterHorizontally),
) {
AsyncImage(
model = state.profileImagePath ?: R.drawable.img_profile,
contentDescription = null,
modifier =
Modifier
.size(116.dp)
.clip(CircleShape)
.border(
width = 1.dp,
color = DPlayTheme.colors.gray200,
shape = CircleShape,
),
contentScale = ContentScale.Crop,
)

DPlayCircleButton(
circleButtonType =
CircleButtonType.SmallPlus(
R.string.add_profile_image_button_icon_description,
),
onClick = { onProfileImageClick() },
modifier = Modifier.align(Alignment.BottomEnd),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ fun BottomNavigationBar(
) {
if (isVisible) {
Box(
modifier = modifier.fillMaxWidth(),
modifier =
modifier
.fillMaxWidth(),
) {
Row(
modifier =
Expand Down
Loading