-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/#43 프로필 기능을 개발한다 #63
The head ref may contain hidden characters: "feat/#43-\uD504\uB85C\uD544_\uAE30\uB2A5\uC744_\uAC1C\uBC1C\uD55C\uB2E4"
Conversation
https://jaeryo2357.tistory.com/92 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생 많으셨습니다...
코멘트 남겼으니 확인 부탁드립니다!
core/designsystem/src/main/java/com/withpeace/withpeace/core/designsystem/ui/TitleBar.kt
Show resolved
Hide resolved
if (this.data == "true") { | ||
onError(WithPeaceError.GeneralError(code = 2)) | ||
return@suspendMapSuccess emit(false) | ||
} else { | ||
emit(true) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boolean 타입을 String으로 받는 이유가 있을까요?
그리고 저 로직이 어떤 의미인지 이해가 잘 가지 않아서 설명 부탁드려요~
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resposne가 string 타입인줄 알았네요🥲
또한 return에 대해서, flow가 emit을 안하면 메모리 누수가 발생하는 줄 알았는데, 아니었군요..
userService.isNicknameDuplicate(nickname.value).suspendMapSuccess { if (this.data) { onError(WithPeaceError.GeneralError(code = 2)) } else { emit(Unit) } ...이하생략
으로 바꾸었습니다.
onError(WithPeaceError.GeneralError(code = 2))
해당 코드는 "닉네임이 중복이다"는 오류를 도메인 오류로 핸들링 하기 위한 코드입니다.
숫자에 대해서는 임의로 정한 것인데 이는 논의가 더 필요해 보입니다.
개인적으로 WithPeaceErrorCode를 만들어 서버, 클라이언트단 에러 코드를 같이 관리하면 좋겠다고 생각하고 있습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
닉네임 중복에서 true면 onError를 발생시키는 것이 좀 어색해보입니다. 그냥 boolean값을 그대로 흘려보내고 usecase나 viewmodel단에서 처리해야 할 것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
닉네임 중복을 비즈니스 오류로 판단하였습니다! 그래서 WithPeaceError와 함께 쓰이면 좋지 않을까라는 생각에서 코드를 짜보았는데요!
해당 방법을 채택한 생각의 흐름은 아래와 같습니다.
- viewModel까지 boolean 전파시키는 것은 verifyNicknameUseCase에서 어색할 것 같았습니다. (collect 된 값이 format에러인지, duplicate인지 알기 어려운 문제가 있었습니다.)
- 이를 구분하기 위해 따로 onError() 또는 usecase flow response를 통해 구분해야 했습니다.
- 해당 방법 모두 domain을 만들어서 구분이 필요했는데, 에러라는 도메인이라고 생각되었습니다.
- 그래서 WithPeaceError에서 같이 핸들링 처리를 고려했습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repository 함수명이 verifyDuplicated여서 제가 기대하는 것으로는 중복값에 대한 Boolean 값을 뱉는 것을 기대합니다. 따라서, Usecase에서 Response로 처리하면 어떨까 라는 생각입니다.
그리고 Withpeace 에러에 대한 저의 개인적인 생각은 의도치 않은 에러일 경우에 대해서 처리해야 하지 않을까 라는 생각입니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
서버에서 해당 validation을 검증해주는 경우 또한 의도치 않은 에러에 해당될까요?
updateProfile API에서는 nickname에 대한 validate를 400번대 response code로 받아 WithPeaceError로 처리하고 있습니다!
서버에서 하는 validate 우리 도메인에서 하는 validate는 같은 성격을 띄고 있다고 생각하고 있습니다.
return if (beforeProfile.profileImage != afterProfile.profileImage | ||
&& afterProfile.nickname != beforeProfile.nickname && afterProfile.profileImage != null | ||
) { // 이미지 닉네임 둘 다 변경 되었을 때 | ||
userRepository.updateProfile( | ||
afterProfile.nickname.value, afterProfile.profileImage, | ||
onError = onError, | ||
) | ||
} else if (afterProfile.profileImage != null && beforeProfile.profileImage != afterProfile.profileImage | ||
) { // 이미지만 변경되었을 때 | ||
userRepository.updateProfileImage( | ||
profileImage = afterProfile.profileImage, | ||
onError = onError, | ||
) | ||
} else { // 닉네임만 변경 되었을 때 | ||
userRepository.updateNickname(afterProfile.nickname.value, onError = onError) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when 문을 쓰는건 어떨까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
또한 이건 제 개인적인 스타일로는, 닉네임만 변경되었는지, profile만 변경되었는지에 대한 함수를 ChangingProfileInfo로 전가할 것 같아요. Usecase에서는 그 함수를 이용하고요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sealed interface ProfileChangingStatus {
data object OnlyNicknameChanging : ProfileChangingStatus
data object OnlyImageChanging : ProfileChangingStatus
data object AllChanging : ProfileChangingStatus
companion object {
fun getStatus(
beforeProfile: ChangingProfileInfo,
afterProfile: ChangingProfileInfo,
): ProfileChangingStatus {
return if (beforeProfile.profileImage != afterProfile.profileImage
&& afterProfile.nickname != beforeProfile.nickname && afterProfile.profileImage != null
) {
AllChanging
} else if (afterProfile.profileImage != null && beforeProfile.profileImage != afterProfile.profileImage
) {
OnlyImageChanging
} else {
OnlyNicknameChanging
}
}
}
}
해당 코드를 추가하여 when문을 없애고 수정하였습니다! ChangingProfileInfo는 편집시에만 필요한 회원정보를 의미하며, ProfileChangingStatus가 객관적인 상태 분류에 적합할 것이라고 생각했습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when문을 안쓰시는 이유가 있을까요...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 when의 파라미터를 잘 활용할 수 있는 경우나 else를 안쓸 수 있는 경우에 when을 선호하고 있었습니다.
sealed interface ProfileChangingStatus {
data object OnlyNicknameChanging : ProfileChangingStatus
data object OnlyImageChanging : ProfileChangingStatus
data object AllChanging : ProfileChangingStatus
companion object {
fun getStatus(
beforeProfile: ChangingProfileInfo,
afterProfile: ChangingProfileInfo,
): ProfileChangingStatus {
return when {
beforeProfile.profileImage != afterProfile.profileImage &&
afterProfile.nickname != beforeProfile.nickname &&
afterProfile.profileImage != null -> AllChanging
afterProfile.profileImage != null &&
beforeProfile.profileImage != afterProfile.profileImage -> OnlyImageChanging
else -> OnlyNicknameChanging
}
}
}
}
가독성이 저는 if문이 나아보이는데, 스캇은 어떠실까요? 다른 좋은 표현 방법이 있을까요?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if문이 3개가 넘어가면 when문을 쓰는 것이 저는 가독성이 좋아보입니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋습니다 3개의 분기가 넘어가면 when을 쓰는 것으로 하겠습니다! 이 또한 컨벤션이 되겠네요!
data class ChangedProfile( | ||
val nickname: String, | ||
val profileImageUrl: String, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ChangingProfileInfo와의 차이점이 무엇인가요?
여기는 왜 nickname value클래스를 사용하지 않고, profileImage가 Null허용이 안되있나요?
when (mypageUiState) { | ||
MyPageUiState.Loading -> {} | ||
is MyPageUiState.Success -> {} | ||
MyPageUiState.Fail -> { | ||
onShowSnackBar(stringResource(R.string.network_failure_message)) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UiState통해 SnackBar를 띄워주게되면, 화면회전이 되었을 때 계속 스낵바가 호출될 것으로 예상되요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Channel을 이용해야할 것 같습니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UIEvent를 통해 세부에러 처리 이벤트를 Channel로 구현했습니다!
Channel을 이용하는 이유가 sharedFlow와 다르게, 에러 값이 캐싱되었다가 방출한다는 점이 맞을까요?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네 맞습니다. Channel은 기본값으로 버퍼에다가 값을 저장해놓습니다. (Default가 64개 원소를 저장하는 것으로 알고있음)
그러나 Channel 은 한 소비자당 하나의 원소를 가질 수 있다는 점이 단점이고, SharedFlows는 여러 소비자가 같은 값을 공유해서 받을 수 있다는 장점이 있습니다.
따라서, 여러 소비자가 같은 같은 값을 관찰해야 한다면, SharedFlow를 쓰고, 아니라면 Channel을 쓰는것이 좋습니다.
if (_profileEditUiState.value is ProfileEditUiState.NoChanges) { | ||
viewModelScope.launch { | ||
_profileEditUiEvent.send(ProfileEditUiEvent.ShowUnchanged) | ||
} | ||
} else if (_profileEditUiState.value is ProfileEditUiState.Editing) { | ||
val editing = _profileEditUiState.value as ProfileEditUiState.Editing | ||
viewModelScope.launch { | ||
updateProfileUseCase( | ||
beforeProfile = baseProfileInfo.toDomain(), | ||
afterProfile = editing.profileInfo.toDomain(), | ||
onError = { | ||
this.launch { | ||
_profileEditUiEvent.send(ProfileEditUiEvent.ShowFailure) | ||
} | ||
}, | ||
).collect { | ||
_profileEditUiEvent.send(ProfileEditUiEvent.ShowUpdateSuccess) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
viewModelScope로 한번에 감싸면 안되는 이유가 무엇일까요? 그리고 변경이 아무것도 되지 않았으면, 변경완료 버튼을 눌러도 토스트메세지만 띄울 뿐, 마이페이지로 이동을 안하는건가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- onError를 suspend로 감싸서 viewModelScope.launch가 한 번만 사용되도록 했습니다!
�2. 맞습니다! 기획상으로 해당 로직이 수행됩니다
internal fun ProfileUiModel.toDomain(): ChangingProfileInfo { | ||
return ChangingProfileInfo(nickname, profileImage) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
닉네임에 빈칸을 입력하고 변경완료 버튼을 누르면 앱이 터집니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nickname 대한 require exception이 발생했습니다.
잘못된 닉네임이라도 Update API 요청을 할 수 있기 때문에 현재 해당 require을 제거하였습니다.
고민이 되는 부분이 nickname에 대한 중복 검사 API는 있지만, format validate API는 없습니다. 이에 nickname 역할이 모호해지네요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
require를 제거안하고, ChangingProfile에서는 Nickname을 쓰는게 아니라 그냥 String을 쓰는건 어떻게 생각하시나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저도 require 두는 것은 좋은 것 같은데요! ValidNickname, Nickname으로 구분을 해볼까요?! string과 Nickname은 역할 구분이 어려워 보입니다!
feature/profileeditor/src/main/java/com/app/profileeditor/navigation/ProfileEditorNavigation.kt
Show resolved
Hide resolved
if (verified) { | ||
_profileEditUiEvent.send( | ||
ProfileEditUiEvent.ShowNicknameVerified, | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
위 코멘트와 동일합니다
data class ProfileUiModel( | ||
val nickname: String, | ||
val profileImage: String, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저희 모듈이 따로 나뉘어져 있기 떄문에, UI Model이 재활용되지 않고 중복될 가능성이 큰 것 같아요. 이 부분은 고민이 필요해보입니다.
292f5e6
to
e1afaa9
Compare
@chws0508 |
if (this.data == "true") { | ||
onError(WithPeaceError.GeneralError(code = 2)) | ||
return@suspendMapSuccess emit(false) | ||
} else { | ||
emit(true) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repository 함수명이 verifyDuplicated여서 제가 기대하는 것으로는 중복값에 대한 Boolean 값을 뱉는 것을 기대합니다. 따라서, Usecase에서 Response로 처리하면 어떨까 라는 생각입니다.
그리고 Withpeace 에러에 대한 저의 개인적인 생각은 의도치 않은 에러일 경우에 대해서 처리해야 하지 않을까 라는 생각입니다.
|
||
companion object { | ||
private const val NICKNAME_REGEX_PATTERN = "[a-zA-Z0-9가-힣]{2,10}" | ||
fun create(value: String): Nickname = Nickname(value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
create함수를 따로 만든 이유가 있을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 메소드를 통해 자연어처럼 읽히길 원했습니다! Nickname(nickname) Nickname.create(nickname)
afterProfile.profileImage != null && | ||
beforeProfile.profileImage != afterProfile.profileImage -> OnlyImageChanging | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
위 코멘트와 동일합니다
return when { | ||
beforeProfile.profileImage != afterProfile.profileImage && | ||
afterProfile.nickname != beforeProfile.nickname && | ||
afterProfile.profileImage != null -> AllChanging | ||
|
||
afterProfile.profileImage != null && | ||
beforeProfile.profileImage != afterProfile.profileImage -> OnlyImageChanging |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
afterProfile이미지가 왜 Null이 아니어야 하는지 알 수 있을까요?
val updateData = ProfileEditUiState.Editing( | ||
ProfileUiModel( | ||
(it as? ProfileEditUiState.Editing)?.profileInfo?.nickname | ||
?: baseProfileInfo.nickname, | ||
profileImage = imageUri, | ||
), | ||
) | ||
if (baseProfileInfo == updateData.profileInfo) { | ||
return@update ProfileEditUiState.NoChanges | ||
} | ||
updateData |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UI에 가까운 domain이 Data Layer에서 함께 쓰일 때 라는 말을 제가 정확히 이해하진 못했지만, isChanged가 Domain모델 생성자 안에 있지 않기 때문에 영향이 있지 않은 것 같습니다. 제가 가장 원하는 것은 복잡한 로직 또는 비즈니스적 로직이라고 판단되는 로직은 모두 Domain 영역에 위치하기를 원합니다. 따라서, 핵심은 Profile이 변했는지를 분별하는 로직이 Domain에 위치해야 한다는 것이고, Ui영역, 정확히 말하면 viewModel에서 이 로직을 이용하여 화면에 만들어야 할 "상태" 를 만드는 것이 제가 생각하는 이상적인 그림입니다.
internal fun ProfileUiModel.toDomain(): ChangingProfileInfo { | ||
return ChangingProfileInfo(nickname, profileImage) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
require를 제거안하고, ChangingProfile에서는 Nickname을 쓰는게 아니라 그냥 String을 쓰는건 어떻게 생각하시나요?
private fun updateIsNicknameValidStatus(status: ProfileNicknameValidUiState) { | ||
_profileNicknameValidUiState.update { status } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이건 함수로 안해도 될 것 같아요
when (mypageUiState) { | ||
MyPageUiState.Loading -> {} | ||
is MyPageUiState.Success -> {} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
코드 바꿔주세용
data object ShowDuplicateSnackBar : ProfileEditUiEvent | ||
data object ShowInvalidFormatSnackBar : ProfileEditUiEvent | ||
data object ShowUpdateSuccess : ProfileEditUiEvent | ||
data object ShowFailure : ProfileEditUiEvent | ||
data object ShowUnchanged : ProfileEditUiEvent | ||
data object UnAuthorized : ProfileEditUiEvent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네이밍 바꿔 주세용
* docs: 이슈 템플릿을 추가한다 * Update bug_report.yml * initial commit * setup ci * Pull request template을 추가한다. * feat : 멀티 모듈을 위한 세팅 (#3) - 버젼 카탈로그 적용 - Build Logic 컨벤션 적용 * Update pull_request_template.md * Update android.yml * feat: network 세팅을 진행한다 (#7) * feat: core:network 모듈추가 * feat: HiltApplication 추가 * feat: Network hilt 모듈 및 Service 세팅 * feat: data 모듈 추가 * feat: google 로그인 api를 구현 --------- Co-authored-by: kwakjoohyeong <[email protected]> * feat: Token을 저장하는 dataStore 구현 (#10) Co-authored-by: boogiwoogi <[email protected]> * �Featrue/#12_CI_빌드_시간_단축 (#13) * Update android.yml * feat: ci secret key 추가 * Feature/#4 구글 소셜 로그인 기능을 개발 (#14) * feat: 구글 소셜 로그인을 위한 기초 세팅 * feat : 구글 로그인 로직 구현 --------- Co-authored-by: boogiwoogi <[email protected]> Co-authored-by: chws0508 <[email protected]> * Feat/#15 테마 구축 (#16) * feat : 디자인 시스템 구축 * feat : error 수정 * ci 파일 수정 - Google Client Id 에 접근하는 코드와 build하는 코드의 순서를 바꿈 * feat: token interceptor 구현 (#18) * feat: AuthInterceptor 구현 중 * chore: 코드 포맷 * feat: 네트워크 통신을 위한 인터셉터 구현 * feat: 구글 로그인을 통해 access 토근을 받아오는 로직 구현 * feat: signUP 구현 * feat : navigateToLogin 로직 삭제 * feat : 테마 패키지 수정 * feat : suspendOnError를 suspendOnFailure로 수정 * feat : 구글 로그인 에러시 error메세지를 띄우도록 변경 * ci 문법 오류 수정 --------- Co-authored-by: kwakjoohyeong <[email protected]> Co-authored-by: chws0508 <[email protected]> * feat: 로그인 UI 구현 (#19) * feat: 로그인 화면 구성 * feat: 로그인 이벤트 처리 * feat: 로그인 성공 실패에 대한 이벤트 처리 * feat: 로그인 성공 실패시 snack bar 표현 * feat: splash 화면 구현 (#21) * refactor: auth interceptor hilt 적용 (#23) * feat: splash 화면 구현 * refactor: authinterceptor hilt 적용 * Refactor/#12 빌드속도 개선 (#33) * Update android.yml * fix: gradle caching 순서 변경 * fix: gradle build 제거 * feat: test를 모듈별로 병렬 수행하도록 변경 * feat: save cache로 변경 * fix: save cache 오류 수정 * feat: 빌드 캐시 workflow 추가 * feat: add build commend (#36) * feat: add build commend * feat: 병렬실행으로 변경 * Feat/#25 usecase 적용 (#37) * feat : isLoginUSeCase 구현 * test : MainViewModel test 적용 * feat : GoogleLoginManager Scope인자 제거 * feat : 콜백을 제거하도록 리팩토링 및 ViewModelTest 작성 * test : UseCase테스트 작성 * feat : 에러함수 콜백으로 처리 및 Interceptor retrofit을 이용하도록 수정 (#44) * Feat/#45 UI 비율을 360800 수정 (#46) * fix: 디자인 스펙 수정 375x800 -> 360x800 * chore: 불필요한 import 제거 * refactor: PaddingValues 대신 기본 padding 속성 사용 * Feat/#38 401 로직 구현 (#48) * refactor: TokenRepository와 해당 Repository를 사용하는 usecase 변경 * feat: WithpeaceError 추가 * refactor: nullable하게 변경 * refactor: googleLogin Response 수정 (#50) * refactor: googleLogin Response 수정 * chore: response naming 변경 * 47 게시글 등록 기능을 구현한다 (#51) * feat : 게시글 등록 모듈 생성 * feat : 완료 버튼 생성 * feat : 게시글 등록 기능 UI 구현 완료 * feat : UI기능 전까지 완료 * feat : 이미지 삭제 아이콘 적용 및 스크롤 기능 적용 * feat : 커스텀 갤러리 기능 구현 * feat : 이미지 권한 요청 기능 구현 * feat : 갤러리에서 선택한 이미지를 게시글에서 받도록 구현 * feat : 게시글 등록 API 연동 구현 * feat : 설정창으로 이동 다이얼로그 기능 구현 * feat : StringResource 리팩토링 * feat : Dependency Graph 모듈 볼수 있는 플러그인 추가 * feat : 갤러리 이미지 개수 표현 방식 변경 - 기존: 0/3 - 변경: 2/5 * feat : 이미지 최대 개수 넘을 시 토스트 메세지 띄우는 기능 구현 * feat : 화면 회전시 앱이 안보이는 버그 수정 * feat : GetAlbumImagesUseCase로 네이밍 수정 * feat : Cursor -> Query로 네이밍 수정 * feat : GetAlbumImagesUseCase에서 ImagePagingInfo를 주도록 변경 * feat : 게시글 등록 화면 화면회전 대처 * feat : GalleryViewModel Test 작성 * test : GetAllFoldersUseCaseTest 및 RegisterPostUsecaseTest 작성 * feat : releaseMode Proguard 적용 * feat : suspend 키워드 추가 * feat : 게시글 등록 API Type 컬럼 값 변경 * feat : 앱 난독화 적용 * test : RegisterPostViewModel 테스트 작성 * Feat/#53 바텀 네비게이션을 구현한다 (#55) * feat: bottom navigation 화면 추가 * feat: bottom navigation 적용 * feat: bottom navigation 아이콘 변경 적용 * refactor: string res 추출 * feat : firebase crashlytics 적용 (#59) * feat : firebase crashlytics 적용 * feat : google-services ci에 적용 * feat : google-services ci에 적용 * �feat: yml google service 적용 --------- Co-authored-by: Covy <[email protected]> * fix : 폴더가 없는 사진은 가져오지 않도록 수정 (#64) * Feat/#57-게시글 목록 조회 UI를 구현한다 (#60) * feat : 게시글 등록 모듈 생성 * feat : 게시글 등록 기능 UI 구현 완료 * feat : UI기능 전까지 완료 * feat : 커스텀 갤러리 기능 구현 * feat : 갤러리에서 선택한 이미지를 게시글에서 받도록 구현 * feat : 게시글 등록 API 연동 구현 * feat : StringResource 리팩토링 * feat : Dependency Graph 모듈 볼수 있는 플러그인 추가 * feat : 화면 회전시 앱이 안보이는 버그 수정 * feat : GetAlbumImagesUseCase로 네이밍 수정 * feat : GetAlbumImagesUseCase에서 ImagePagingInfo를 주도록 변경 * feat : GalleryViewModel Test 작성 * feat : 앱 난독화 적용 * test : RegisterPostViewModel 테스트 작성 * feat : core-ui 모듈 추가 및 PostTopicUiState core-ui로 이동 * refactor : Rebase 충돌 수정 * refactor : 모듈을 post에서 postList로 수정 * refactor : material3 버젼 업 * feat : 게시글 목록 화면 탭 UI 구현 * feat : Tab에 viewModel 상태 적용 * feat : 게시글 목록 UI 구현 완료 * feat : Date 계산 로직 도메인으로 이동 * feat : 사진 변경사항 적용 - 고정 크기로 변경 - 사진이 없을 경우 대처 * Feat/#43 프로필 기능을 개발한다 (#63) * feat/#52 signup 기능을 구현한다 (#74) * Rebase develop * feat: basicTextField 중앙 정렬 적용 * feat: role에 대한 회원가입 화면 이동로직 추가 * feat: 최초 로그인 profile 수정 * refactor: ProfileEditor, NickNameEditor 공용함수화 * fix: 토큰 저장방식 수정 * feat: 최초로그인 구현 * fix: signUp 버튼 클릭시 이벤트 변경 * feat: role, id 로컬 저장 및 따라 자동로그인 로직 추가 * feat: 회원가입 성공시 권한 업그레이드 * fix: refresh header 추가 (#75) * Feat/#61 게시글 상세 UI 구현 (#66) * refactor : Image폴더로 이동 * feat : PostDetail Navigation 로직 작성 * feat : 게시글 등록 모듈 생성 * feat : 게시글 등록 기능 UI 구현 완료 * feat : UI기능 전까지 완료 * feat : 커스텀 갤러리 기능 구현 * feat : 갤러리에서 선택한 이미지를 게시글에서 받도록 구현 * feat : 게시글 등록 API 연동 구현 * feat : StringResource 리팩토링 * feat : Dependency Graph 모듈 볼수 있는 플러그인 추가 * feat : 화면 회전시 앱이 안보이는 버그 수정 * feat : GetAlbumImagesUseCase로 네이밍 수정 * feat : GetAlbumImagesUseCase에서 ImagePagingInfo를 주도록 변경 * feat : GalleryViewModel Test 작성 * feat : 앱 난독화 적용 * test : RegisterPostViewModel 테스트 작성 * refactor : Rebase 충돌 수정 * feat : 게시글 목록 UI 구현 완료 * feat : Date 계산 로직 도메인으로 이동 * feat : PostScreen UI 구현 * feat : NavHost에 postDetail 화면 추가 * feat : 중첩 그래프 적용 및 windowInset 올바르게 적용 * feat : value class로 변경 * feat : 목록에서 detail로 이동하는 로직 구현 * feat : PostDetail 뒤로가기 버튼 적용 * feat : bottomNavigation 로직 변경 * feat : 오류 및 로딩 화면 간단 대응 * feat : Profile 패딩 적용 * feat : TopBar를 공통으로 사용 * feat : 충돌 해결 * fix: Refresh토큰 API 헤더 변경 (#80) * Feat/#67 게시글 목록 기능 구현 (#79) * feat : 게시글 등록 모듈 생성 * feat : 게시글 등록 기능 UI 구현 완료 * feat : UI기능 전까지 완료 * feat : 커스텀 갤러리 기능 구현 * feat : 갤러리에서 선택한 이미지를 게시글에서 받도록 구현 * feat : 게시글 등록 API 연동 구현 * feat : StringResource 리팩토링 * feat : Dependency Graph 모듈 볼수 있는 플러그인 추가 * feat : 화면 회전시 앱이 안보이는 버그 수정 * feat : GetAlbumImagesUseCase로 네이밍 수정 * feat : GetAlbumImagesUseCase에서 ImagePagingInfo를 주도록 변경 * feat : GalleryViewModel Test 작성 * feat : 앱 난독화 적용 * test : RegisterPostViewModel 테스트 작성 * feat : core-ui 모듈 추가 및 PostTopicUiState core-ui로 이동 * refactor : Rebase 충돌 수정 * refactor : 모듈을 post에서 postList로 수정 * refactor : material3 버젼 업 * feat : 게시글 목록 화면 탭 UI 구현 * feat : Tab에 viewModel 상태 적용 * feat : 게시글 목록 UI 구현 완료 * feat : Date 계산 로직 도메인으로 이동 * feat : 사진 변경사항 적용 - 고정 크기로 변경 - 사진이 없을 경우 대처 * feat : 게시글 목록 가져오는 기능 Usecase 및 Repository 로직 구현 * feat : 게시글 목록 조회 Paging 기능 ViewModel 및 View에 적용 * feat : snapshotList를 쓰지 않도록 수정 - snapshotList는 페이징 적용 x * feat : 에러 이벤트 처리 구현 * feat : UiModel 적용 * feat : 리뷰 반영 * Fix/#77 커스텀 갤러리 이미지 validation 추가 (#81) * refactor: image 정보로 mimeType, size 추가 * feat: 타입, 사이즈 검증 로직 추가 * refactor: 리뷰반영 * Feat/#65 게시글 상세 기능 구현 (댓글 x) * refactor : Image폴더로 이동 * feat : PostDetail Navigation 로직 작성 * feat : 게시글 등록 모듈 생성 * feat : 게시글 등록 기능 UI 구현 완료 * feat : UI기능 전까지 완료 * feat : 커스텀 갤러리 기능 구현 * feat : 갤러리에서 선택한 이미지를 게시글에서 받도록 구현 * feat : 게시글 등록 API 연동 구현 * feat : StringResource 리팩토링 * feat : Dependency Graph 모듈 볼수 있는 플러그인 추가 * feat : 화면 회전시 앱이 안보이는 버그 수정 * feat : GetAlbumImagesUseCase로 네이밍 수정 * feat : GetAlbumImagesUseCase에서 ImagePagingInfo를 주도록 변경 * feat : GalleryViewModel Test 작성 * feat : 앱 난독화 적용 * test : RegisterPostViewModel 테스트 작성 * refactor : Rebase 충돌 수정 * feat : 게시글 목록 UI 구현 완료 * feat : Date 계산 로직 도메인으로 이동 * feat : PostScreen UI 구현 * feat : NavHost에 postDetail 화면 추가 * feat : 중첩 그래프 적용 및 windowInset 올바르게 적용 * feat : value class로 변경 * feat : 목록에서 detail로 이동하는 로직 구현 * feat : PostDetail 뒤로가기 버튼 적용 * feat : bottomNavigation 로직 변경 * feat : 오류 및 로딩 화면 간단 대응 * feat : Profile 패딩 적용 * feat : TopBar를 공통으로 사용 * feat : PostDetail Navigation 로직 작성 * refactor : 모듈을 post에서 postList로 수정 * feat : 게시글 목록 UI 구현 완료 * feat : Date 계산 로직 도메인으로 이동 * feat : 게시글 상세 정보 가져오는 API 기능 구현 * feat : 게시글 상세 정보 가져오는 API viewmodel에 적용 * feat : viewModel 적용 오류 수정 * feat: DateUiModel 생성 및 ProfileDetailUiModel 적용 * feat: BottomSheet 구현 * feat: 삭제 API 연동 * feat: 삭제 기능 UI 적용 * feat: 게시글 수정 기능 및 삭제 API 연동 * feat: 게시글 삭제 다이얼로그 적용 * feat: 게시글 등록 바텀네비게이션 등록 * feat: 백스택 오류 수정 * test: 테스트 수정 * feat: 게시글 수정 완료시 , navOptions 수정 * feat: 이미지 등록 이슈 해결 - URL도 파일로 변환 로직 추가 - 이미지 등록 Column 변경 * Fix/#76 프로필 최초 로그인 qa 사안 적용한다 (#86) * fix: 닉네임 검증 로직 수정 * refactor: 프로필 변경 가능 조건 변경 버튼(on off) * fix: token prefix 추가 * fix: conflict 수정 * refactor: naming 수정 * Refactor/#87 오류처리 개선 (#88) * feat: response 확장함수 추가 * refactor: cheongha error로 에러 통일 및 리팩토링 * refactor: logout api 로직 추가 * test: 테스트 수정 * refactor: onAuthExpired 로직 추가 * Paging 성능 개선 및 테스트 작성 (#89) * refactor: 이미지 관련 페이징 수정 - ket 추가 - Data영역으로 PagingSource 파일 이동 - PagingSource 테스트 작성 - GalleryViewModel 테스트 수정 * refactor: PostList 관련 페이징 수정 - ket 추가 - Data영역으로 PagingSource 파일 이동 - PagingSource 테스트 작성 - PostListViewModel 테스트 작성 * Feat/#91 댓글 기능을 구현한다 (#95) * feat : API 연동 * feat : 댓글 기능 구현 * feat : 이미지 회전 이슈 해결 * feat : 이미지 등록 로딩 구현 * feat : url 이미지 회전 이슈 해결 * feat : 로딩 시에는 완료 버튼이 클릭이 안되도록 방지 * feat : 댓글 요청 형식 변경 대응 * refactor : Delay 제거 * refactor : Default값 제거 * refactor : 현재 시간 Zond을 "Asia/Seoul" 로 변경 * refactor : 1초 이하면, 1초 전으로 표시하도록 수정 * refactor : isContentFocused 변수를 추가하여, 내용 TextField 에 Foucs 되있을 때만 키보드 올라오도록 함 (#99) * feat: PostDetail 애니메이션 변경 (#100) * Feat/#90 청년 정책 리스트 기능을 구현한다 (#96) * feat: 청년 정책 API 연동 * feat: pagingSource 추가 * feat: 지역, 분류 도메인 모델 추가 * feat: 시작페이지 수정 * feat: 필터 request 파라미터 적용 * feat: 흰 상태바 적용 * feat: 정책 카드 추가 * feat: 그림자 추가 * feat: UI단 Paging 의존성 추가 * feat: yml local.properties 추가 * fix: yml local.properties 수정 * feat: API View 연동 * feat: API 예외 케이스 추가 * fix: 뷰 패딩 값 수정 * feat: UiModel 적용 * feat: 정책분야 필터 화면 추가 * fix: 필터 UI 수정 * fix: 필터 높이가 맞지 않던 디자인 수정 * feat: 애니메이션 적용 및 필터 기능 완료 * feat: 로고 수정 * fix: 바텀 시트 높이가 맞지 않는 문제 수정 * fix: onSizeChanged로 변경 * feat: 필터 확장 기능 편의성 추가 확장된 필터로 검색한 후 다시 필터화면으로 돌아가면 확장된 상태이다. * feat: 하단 로딩 뷰 추가 * feat: postList 하단 로딩 뷰 추가 * feat/#106 신고 기능 구현 (#109) * refactor : 게시글 신고 모달 패딩조정 * feat : 게시글 신고 기능 구현 * feat : 댓글 신고 기능 구현 * feat: 사용자의 글 다시보지 않기 섹션 제거 --------- Co-authored-by: chws0508 <[email protected]> * Feat/#110 1차 출시 준비 (#113) * feat: 앱 이름 수정 * feat: 홈, 스플래시 로고 업데이트 * feat: 브랜드 컬러 업데이트 * feat: 임시 앱 로고 추가 * feat: 워크플로 수정 * feat: Divider -> Spacer 변경 * feat: 마이페이지 로딩화면 추가 * feat: scrollable 추가 * feat: post editor round 추가 * feat: 서비스명 업데이트 * feat: 탈퇴 기능 추가 * Fix/#116 로그인 후 백스택 제거 (#119) * feat: 로그인 성공 후 백스택 제거 로직 추가 * feat: 삭제된 유저 validation 추가 * feat: 본인 댓글 안보이게 수정 * chore: version code 변경 --------- Co-authored-by: boogiwoogi <[email protected]> Co-authored-by: Choi Woo Seok <[email protected]>
* docs: 이슈 템플릿을 추가한다 * Update bug_report.yml * initial commit * setup ci * Pull request template을 추가한다. * feat : 멀티 모듈을 위한 세팅 (#3) - 버젼 카탈로그 적용 - Build Logic 컨벤션 적용 * Update pull_request_template.md * Update android.yml * feat: network 세팅을 진행한다 (#7) * feat: core:network 모듈추가 * feat: HiltApplication 추가 * feat: Network hilt 모듈 및 Service 세팅 * feat: data 모듈 추가 * feat: google 로그인 api를 구현 --------- Co-authored-by: kwakjoohyeong <[email protected]> * feat: Token을 저장하는 dataStore 구현 (#10) Co-authored-by: boogiwoogi <[email protected]> * �Featrue/#12_CI_빌드_시간_단축 (#13) * Update android.yml * feat: ci secret key 추가 * Feature/#4 구글 소셜 로그인 기능을 개발 (#14) * feat: 구글 소셜 로그인을 위한 기초 세팅 * feat : 구글 로그인 로직 구현 --------- Co-authored-by: boogiwoogi <[email protected]> Co-authored-by: chws0508 <[email protected]> * Feat/#15 테마 구축 (#16) * feat : 디자인 시스템 구축 * feat : error 수정 * ci 파일 수정 - Google Client Id 에 접근하는 코드와 build하는 코드의 순서를 바꿈 * feat: token interceptor 구현 (#18) * feat: AuthInterceptor 구현 중 * chore: 코드 포맷 * feat: 네트워크 통신을 위한 인터셉터 구현 * feat: 구글 로그인을 통해 access 토근을 받아오는 로직 구현 * feat: signUP 구현 * feat : navigateToLogin 로직 삭제 * feat : 테마 패키지 수정 * feat : suspendOnError를 suspendOnFailure로 수정 * feat : 구글 로그인 에러시 error메세지를 띄우도록 변경 * ci 문법 오류 수정 --------- Co-authored-by: kwakjoohyeong <[email protected]> Co-authored-by: chws0508 <[email protected]> * feat: 로그인 UI 구현 (#19) * feat: 로그인 화면 구성 * feat: 로그인 이벤트 처리 * feat: 로그인 성공 실패에 대한 이벤트 처리 * feat: 로그인 성공 실패시 snack bar 표현 * feat: splash 화면 구현 (#21) * refactor: auth interceptor hilt 적용 (#23) * feat: splash 화면 구현 * refactor: authinterceptor hilt 적용 * Refactor/#12 빌드속도 개선 (#33) * Update android.yml * fix: gradle caching 순서 변경 * fix: gradle build 제거 * feat: test를 모듈별로 병렬 수행하도록 변경 * feat: save cache로 변경 * fix: save cache 오류 수정 * feat: 빌드 캐시 workflow 추가 * feat: add build commend (#36) * feat: add build commend * feat: 병렬실행으로 변경 * Feat/#25 usecase 적용 (#37) * feat : isLoginUSeCase 구현 * test : MainViewModel test 적용 * feat : GoogleLoginManager Scope인자 제거 * feat : 콜백을 제거하도록 리팩토링 및 ViewModelTest 작성 * test : UseCase테스트 작성 * feat : 에러함수 콜백으로 처리 및 Interceptor retrofit을 이용하도록 수정 (#44) * Feat/#45 UI 비율을 360800 수정 (#46) * fix: 디자인 스펙 수정 375x800 -> 360x800 * chore: 불필요한 import 제거 * refactor: PaddingValues 대신 기본 padding 속성 사용 * Feat/#38 401 로직 구현 (#48) * refactor: TokenRepository와 해당 Repository를 사용하는 usecase 변경 * feat: WithpeaceError 추가 * refactor: nullable하게 변경 * refactor: googleLogin Response 수정 (#50) * refactor: googleLogin Response 수정 * chore: response naming 변경 * 47 게시글 등록 기능을 구현한다 (#51) * feat : 게시글 등록 모듈 생성 * feat : 완료 버튼 생성 * feat : 게시글 등록 기능 UI 구현 완료 * feat : UI기능 전까지 완료 * feat : 이미지 삭제 아이콘 적용 및 스크롤 기능 적용 * feat : 커스텀 갤러리 기능 구현 * feat : 이미지 권한 요청 기능 구현 * feat : 갤러리에서 선택한 이미지를 게시글에서 받도록 구현 * feat : 게시글 등록 API 연동 구현 * feat : 설정창으로 이동 다이얼로그 기능 구현 * feat : StringResource 리팩토링 * feat : Dependency Graph 모듈 볼수 있는 플러그인 추가 * feat : 갤러리 이미지 개수 표현 방식 변경 - 기존: 0/3 - 변경: 2/5 * feat : 이미지 최대 개수 넘을 시 토스트 메세지 띄우는 기능 구현 * feat : 화면 회전시 앱이 안보이는 버그 수정 * feat : GetAlbumImagesUseCase로 네이밍 수정 * feat : Cursor -> Query로 네이밍 수정 * feat : GetAlbumImagesUseCase에서 ImagePagingInfo를 주도록 변경 * feat : 게시글 등록 화면 화면회전 대처 * feat : GalleryViewModel Test 작성 * test : GetAllFoldersUseCaseTest 및 RegisterPostUsecaseTest 작성 * feat : releaseMode Proguard 적용 * feat : suspend 키워드 추가 * feat : 게시글 등록 API Type 컬럼 값 변경 * feat : 앱 난독화 적용 * test : RegisterPostViewModel 테스트 작성 * Feat/#53 바텀 네비게이션을 구현한다 (#55) * feat: bottom navigation 화면 추가 * feat: bottom navigation 적용 * feat: bottom navigation 아이콘 변경 적용 * refactor: string res 추출 * feat : firebase crashlytics 적용 (#59) * feat : firebase crashlytics 적용 * feat : google-services ci에 적용 * feat : google-services ci에 적용 * �feat: yml google service 적용 --------- Co-authored-by: Covy <[email protected]> * fix : 폴더가 없는 사진은 가져오지 않도록 수정 (#64) * Feat/#57-게시글 목록 조회 UI를 구현한다 (#60) * feat : 게시글 등록 모듈 생성 * feat : 게시글 등록 기능 UI 구현 완료 * feat : UI기능 전까지 완료 * feat : 커스텀 갤러리 기능 구현 * feat : 갤러리에서 선택한 이미지를 게시글에서 받도록 구현 * feat : 게시글 등록 API 연동 구현 * feat : StringResource 리팩토링 * feat : Dependency Graph 모듈 볼수 있는 플러그인 추가 * feat : 화면 회전시 앱이 안보이는 버그 수정 * feat : GetAlbumImagesUseCase로 네이밍 수정 * feat : GetAlbumImagesUseCase에서 ImagePagingInfo를 주도록 변경 * feat : GalleryViewModel Test 작성 * feat : 앱 난독화 적용 * test : RegisterPostViewModel 테스트 작성 * feat : core-ui 모듈 추가 및 PostTopicUiState core-ui로 이동 * refactor : Rebase 충돌 수정 * refactor : 모듈을 post에서 postList로 수정 * refactor : material3 버젼 업 * feat : 게시글 목록 화면 탭 UI 구현 * feat : Tab에 viewModel 상태 적용 * feat : 게시글 목록 UI 구현 완료 * feat : Date 계산 로직 도메인으로 이동 * feat : 사진 변경사항 적용 - 고정 크기로 변경 - 사진이 없을 경우 대처 * Feat/#43 프로필 기능을 개발한다 (#63) * feat/#52 signup 기능을 구현한다 (#74) * Rebase develop * feat: basicTextField 중앙 정렬 적용 * feat: role에 대한 회원가입 화면 이동로직 추가 * feat: 최초 로그인 profile 수정 * refactor: ProfileEditor, NickNameEditor 공용함수화 * fix: 토큰 저장방식 수정 * feat: 최초로그인 구현 * fix: signUp 버튼 클릭시 이벤트 변경 * feat: role, id 로컬 저장 및 따라 자동로그인 로직 추가 * feat: 회원가입 성공시 권한 업그레이드 * fix: refresh header 추가 (#75) * Feat/#61 게시글 상세 UI 구현 (#66) * refactor : Image폴더로 이동 * feat : PostDetail Navigation 로직 작성 * feat : 게시글 등록 모듈 생성 * feat : 게시글 등록 기능 UI 구현 완료 * feat : UI기능 전까지 완료 * feat : 커스텀 갤러리 기능 구현 * feat : 갤러리에서 선택한 이미지를 게시글에서 받도록 구현 * feat : 게시글 등록 API 연동 구현 * feat : StringResource 리팩토링 * feat : Dependency Graph 모듈 볼수 있는 플러그인 추가 * feat : 화면 회전시 앱이 안보이는 버그 수정 * feat : GetAlbumImagesUseCase로 네이밍 수정 * feat : GetAlbumImagesUseCase에서 ImagePagingInfo를 주도록 변경 * feat : GalleryViewModel Test 작성 * feat : 앱 난독화 적용 * test : RegisterPostViewModel 테스트 작성 * refactor : Rebase 충돌 수정 * feat : 게시글 목록 UI 구현 완료 * feat : Date 계산 로직 도메인으로 이동 * feat : PostScreen UI 구현 * feat : NavHost에 postDetail 화면 추가 * feat : 중첩 그래프 적용 및 windowInset 올바르게 적용 * feat : value class로 변경 * feat : 목록에서 detail로 이동하는 로직 구현 * feat : PostDetail 뒤로가기 버튼 적용 * feat : bottomNavigation 로직 변경 * feat : 오류 및 로딩 화면 간단 대응 * feat : Profile 패딩 적용 * feat : TopBar를 공통으로 사용 * feat : 충돌 해결 * fix: Refresh토큰 API 헤더 변경 (#80) * Feat/#67 게시글 목록 기능 구현 (#79) * feat : 게시글 등록 모듈 생성 * feat : 게시글 등록 기능 UI 구현 완료 * feat : UI기능 전까지 완료 * feat : 커스텀 갤러리 기능 구현 * feat : 갤러리에서 선택한 이미지를 게시글에서 받도록 구현 * feat : 게시글 등록 API 연동 구현 * feat : StringResource 리팩토링 * feat : Dependency Graph 모듈 볼수 있는 플러그인 추가 * feat : 화면 회전시 앱이 안보이는 버그 수정 * feat : GetAlbumImagesUseCase로 네이밍 수정 * feat : GetAlbumImagesUseCase에서 ImagePagingInfo를 주도록 변경 * feat : GalleryViewModel Test 작성 * feat : 앱 난독화 적용 * test : RegisterPostViewModel 테스트 작성 * feat : core-ui 모듈 추가 및 PostTopicUiState core-ui로 이동 * refactor : Rebase 충돌 수정 * refactor : 모듈을 post에서 postList로 수정 * refactor : material3 버젼 업 * feat : 게시글 목록 화면 탭 UI 구현 * feat : Tab에 viewModel 상태 적용 * feat : 게시글 목록 UI 구현 완료 * feat : Date 계산 로직 도메인으로 이동 * feat : 사진 변경사항 적용 - 고정 크기로 변경 - 사진이 없을 경우 대처 * feat : 게시글 목록 가져오는 기능 Usecase 및 Repository 로직 구현 * feat : 게시글 목록 조회 Paging 기능 ViewModel 및 View에 적용 * feat : snapshotList를 쓰지 않도록 수정 - snapshotList는 페이징 적용 x * feat : 에러 이벤트 처리 구현 * feat : UiModel 적용 * feat : 리뷰 반영 * Fix/#77 커스텀 갤러리 이미지 validation 추가 (#81) * refactor: image 정보로 mimeType, size 추가 * feat: 타입, 사이즈 검증 로직 추가 * refactor: 리뷰반영 * Feat/#65 게시글 상세 기능 구현 (댓글 x) * refactor : Image폴더로 이동 * feat : PostDetail Navigation 로직 작성 * feat : 게시글 등록 모듈 생성 * feat : 게시글 등록 기능 UI 구현 완료 * feat : UI기능 전까지 완료 * feat : 커스텀 갤러리 기능 구현 * feat : 갤러리에서 선택한 이미지를 게시글에서 받도록 구현 * feat : 게시글 등록 API 연동 구현 * feat : StringResource 리팩토링 * feat : Dependency Graph 모듈 볼수 있는 플러그인 추가 * feat : 화면 회전시 앱이 안보이는 버그 수정 * feat : GetAlbumImagesUseCase로 네이밍 수정 * feat : GetAlbumImagesUseCase에서 ImagePagingInfo를 주도록 변경 * feat : GalleryViewModel Test 작성 * feat : 앱 난독화 적용 * test : RegisterPostViewModel 테스트 작성 * refactor : Rebase 충돌 수정 * feat : 게시글 목록 UI 구현 완료 * feat : Date 계산 로직 도메인으로 이동 * feat : PostScreen UI 구현 * feat : NavHost에 postDetail 화면 추가 * feat : 중첩 그래프 적용 및 windowInset 올바르게 적용 * feat : value class로 변경 * feat : 목록에서 detail로 이동하는 로직 구현 * feat : PostDetail 뒤로가기 버튼 적용 * feat : bottomNavigation 로직 변경 * feat : 오류 및 로딩 화면 간단 대응 * feat : Profile 패딩 적용 * feat : TopBar를 공통으로 사용 * feat : PostDetail Navigation 로직 작성 * refactor : 모듈을 post에서 postList로 수정 * feat : 게시글 목록 UI 구현 완료 * feat : Date 계산 로직 도메인으로 이동 * feat : 게시글 상세 정보 가져오는 API 기능 구현 * feat : 게시글 상세 정보 가져오는 API viewmodel에 적용 * feat : viewModel 적용 오류 수정 * feat: DateUiModel 생성 및 ProfileDetailUiModel 적용 * feat: BottomSheet 구현 * feat: 삭제 API 연동 * feat: 삭제 기능 UI 적용 * feat: 게시글 수정 기능 및 삭제 API 연동 * feat: 게시글 삭제 다이얼로그 적용 * feat: 게시글 등록 바텀네비게이션 등록 * feat: 백스택 오류 수정 * test: 테스트 수정 * feat: 게시글 수정 완료시 , navOptions 수정 * feat: 이미지 등록 이슈 해결 - URL도 파일로 변환 로직 추가 - 이미지 등록 Column 변경 * Fix/#76 프로필 최초 로그인 qa 사안 적용한다 (#86) * fix: 닉네임 검증 로직 수정 * refactor: 프로필 변경 가능 조건 변경 버튼(on off) * fix: token prefix 추가 * fix: conflict 수정 * refactor: naming 수정 * Refactor/#87 오류처리 개선 (#88) * feat: response 확장함수 추가 * refactor: cheongha error로 에러 통일 및 리팩토링 * refactor: logout api 로직 추가 * test: 테스트 수정 * refactor: onAuthExpired 로직 추가 * Paging 성능 개선 및 테스트 작성 (#89) * refactor: 이미지 관련 페이징 수정 - ket 추가 - Data영역으로 PagingSource 파일 이동 - PagingSource 테스트 작성 - GalleryViewModel 테스트 수정 * refactor: PostList 관련 페이징 수정 - ket 추가 - Data영역으로 PagingSource 파일 이동 - PagingSource 테스트 작성 - PostListViewModel 테스트 작성 * Feat/#91 댓글 기능을 구현한다 (#95) * feat : API 연동 * feat : 댓글 기능 구현 * feat : 이미지 회전 이슈 해결 * feat : 이미지 등록 로딩 구현 * feat : url 이미지 회전 이슈 해결 * feat : 로딩 시에는 완료 버튼이 클릭이 안되도록 방지 * feat : 댓글 요청 형식 변경 대응 * refactor : Delay 제거 * refactor : Default값 제거 * refactor : 현재 시간 Zond을 "Asia/Seoul" 로 변경 * refactor : 1초 이하면, 1초 전으로 표시하도록 수정 * refactor : isContentFocused 변수를 추가하여, 내용 TextField 에 Foucs 되있을 때만 키보드 올라오도록 함 (#99) * feat: PostDetail 애니메이션 변경 (#100) * Feat/#90 청년 정책 리스트 기능을 구현한다 (#96) * feat: 청년 정책 API 연동 * feat: pagingSource 추가 * feat: 지역, 분류 도메인 모델 추가 * feat: 시작페이지 수정 * feat: 필터 request 파라미터 적용 * feat: 흰 상태바 적용 * feat: 정책 카드 추가 * feat: 그림자 추가 * feat: UI단 Paging 의존성 추가 * feat: yml local.properties 추가 * fix: yml local.properties 수정 * feat: API View 연동 * feat: API 예외 케이스 추가 * fix: 뷰 패딩 값 수정 * feat: UiModel 적용 * feat: 정책분야 필터 화면 추가 * fix: 필터 UI 수정 * fix: 필터 높이가 맞지 않던 디자인 수정 * feat: 애니메이션 적용 및 필터 기능 완료 * feat: 로고 수정 * fix: 바텀 시트 높이가 맞지 않는 문제 수정 * fix: onSizeChanged로 변경 * feat: 필터 확장 기능 편의성 추가 확장된 필터로 검색한 후 다시 필터화면으로 돌아가면 확장된 상태이다. * feat: 하단 로딩 뷰 추가 * feat: postList 하단 로딩 뷰 추가 * feat/#106 신고 기능 구현 (#109) * refactor : 게시글 신고 모달 패딩조정 * feat : 게시글 신고 기능 구현 * feat : 댓글 신고 기능 구현 * feat: 사용자의 글 다시보지 않기 섹션 제거 --------- Co-authored-by: chws0508 <[email protected]> * Feat/#110 1차 출시 준비 (#113) * feat: 앱 이름 수정 * feat: 홈, 스플래시 로고 업데이트 * feat: 브랜드 컬러 업데이트 * feat: 임시 앱 로고 추가 * feat: 워크플로 수정 * feat: Divider -> Spacer 변경 * feat: 마이페이지 로딩화면 추가 * feat: scrollable 추가 * feat: post editor round 추가 * feat: 서비스명 업데이트 * feat: 탈퇴 기능 추가 * Fix/#116 로그인 후 백스택 제거 (#119) * feat: 로그인 성공 후 백스택 제거 로직 추가 * feat: 삭제된 유저 validation 추가 * feat: 본인 댓글 안보이게 수정 * chore: version code 변경 * Feat/#104 firebase analytics 적용 (#124) * fix: 바텀 시트 색 변경 * feat: analytics 모듈 추가 * refactor: gradle 의존성 갱신 * feat: analytics 추가 * Feat/#120 2차 버그 수정 및 개선 (#131) * feat: 게시글 리스트 댓글 수 기능 추가 * feat: app logo 갱신 * feat: 게시글 삭제시, 리스트 반영 로직 추가 * test: 테스트 코드 수정 * Update README.md * Feat/#132 청년 정책 상세 기능 구현 (#133) * feat: 정책 분류 이미지 추가 * feat: analytics 리세팅 * feat: 화면 이벤트 적용 * feat: 키보드 높이 적용 * feat: 로깅 작업 완료 * refactor: 로깅 의존성 주입 방식 변경 EntryPoint 적용 * feat: 정책 상세 화면 이동기능 추가 * Revert "refactor: 로깅 의존성 주입 방식 변경" This reverts commit 77275a3. * feat: 정책 상세 데이터 작업 * feat: error 상태 java.lang.IllegalArgumentException: URLDecoder: Illegal hex characters in escape (%) pattern * fix: error 수정 * feat: 하이퍼링크 추가 * feat: title 애니메이션 적용 * feat: padding 수정 * feat: 로깅 작업 * Feat/#134 개인정보 수집 동의 기능 추가 (#136) * feat: 홈 로고 변경 * feat: top app bar 수정 * feat: 정책 상세 추가정보 섹션 추가 * feat: 서비스 이용약관, 개인정보 처리방침 모듈 추가 * feat: 약관 동의 UI 완성 * feat: 정책 상세 UI 수정 * feat: gradle 설정 변경 * feat: 로깅 debug, release 구분 * refactor: 필요없는 로직 제거 * feat: 인앱 업데이트 및 약관 웹뷰 추가 * feat: padding 수정 * chore: 버전코드 수정 --------- Co-authored-by: boogiwoogi <[email protected]> Co-authored-by: Choi Woo Seok <[email protected]>
관련 이슈번호
close #43
작업 사항
- 프로필 화면 - 프로필 편집
기타 사항