-
Notifications
You must be signed in to change notification settings - Fork 1
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
fix: 추억 생성 및 수정 썸네일 사진 업로드 오류 수정 #535 #542
Conversation
- 사진 A를 업로드 중 사진 B로 변경하면 네트워크 연결 불안정 스낵바가 뜨는 오류 해결
- 사진 A를 업로드 중 사진 B로 변경하면 네트워크 연결 불안정 스낵바가 뜨는 오류
- 이전: thumbnailUri - 이후: uri
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.
해나!! 리팩터링과 트러블 슈팅도 하시느라 너무 고생많으셨습니다!!
추억 썸네일 이미지 업로드 중 작업 취소에 대한 처리도 꼼꼼하게 잘 해주셨고, ProtocolException
의 발생 원인을 정말 자세하게 공부하셨네요! 역시 해나도 한 딥다이브 한다니까요...!! 😆
앞서 코루틴 작업 취소에 대해서 트러블 슈팅을 해준 빙티 덕분에 빠르게 에러를 잡을 수 있었네요~ 외쳐 갓티! 갓나!
많은 지식 얻어갑니다! 🙇♂️
수정하면 좋을 부분들을 몇 가지 코멘트로 남겨보았어요. 천천히 확인해주시면 감사하겠습니다.
기능적으로 크게 고쳐야 할 부분은 없는 것 같아, 우선 Approve 드리겠습니다!
data class ThumbnailUiModel( | ||
val uri: Uri? = null, | ||
val url: String? = null, | ||
) { | ||
fun updateUrl(newUrl: String?): ThumbnailUiModel = this.copy(url = newUrl) | ||
|
||
fun isEqualUri(newUri: Uri?): Boolean = uri == newUri | ||
|
||
fun delete() = this.copy(uri = null, url = null) | ||
} |
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.
추억 썸네일의 이미지 uri 와 url 을 가지고 있는 UiModel을 새로 만들어주신 덕분에 보일러 플레이트 코드가 많이 줄어들었네요! 무척 좋은 구현인 것 같습니다 😄
import kotlinx.coroutines.launch | ||
import java.time.LocalDate | ||
import javax.inject.Inject | ||
|
||
private typealias URI = Uri |
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.
추억 생성, 수정 ViewModel에서 Uri
에 대한 typealias
를 지정하신 이유가 무엇인가요?? (순수 궁금증입니다!)
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.
Map
자료형을 사용할 때 key와 value가 의미하는 것을 명시적으로 나타내기 위해 typealias를 자주 활용하는 편입니다.
mutableMapOf<String, String>()
과 같이 선언하면 key와 value의 값이 의미하는 것을 추측하기 힘들어요.
위 코드도 그런 이유로 typealias
를 지정해두었는데 네이밍을 고민하다가 마땅한 네이밍이 떠오르지 않아서 임시로 적어두고 나중에 바꾼다는 걸 까먹었네요..! ThumbnailUri
라는 이름으로 변경했습니다!
반영 커밋
: d08dcca
private fun createThumbnail( | ||
uri: Uri?, | ||
url: String? = null, | ||
) { | ||
val isEqualUri: Boolean? = _thumbnail.value?.isEqualUri(uri) | ||
if (isEqualUri == false) { | ||
thumbnailJobs[_thumbnail.value?.uri]?.cancel() | ||
_thumbnail.value = ThumbnailUiModel(uri = uri, url = url) | ||
} | ||
} |
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.
업로드하려는 Thumbnail
의 uri
가 동일한지 확인하여, 다른 uri
인 경우에만 새로운 Thumbnail
로 변경해주는 동작을 하는군요! 👍
메서드 이름을 바꾸면 내부 동작이 조금 더 잘 이해될 것 같아요.
저도 마땅히 생각나지는 않지만, checkEqualAndSetUri
, 또는 단순히 새로운 Thumbnail
로 바꾼다는setThumbnail
라는 네이밍은 어떤가요?
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.
추가로 기존 Uri와 다른 Uri인지 확인하는 코드를 아래처럼 메서드로 분리하면 코드가 좀 더 깔끔해질 것 같아요!
private fun createThumbnail( | |
uri: Uri?, | |
url: String? = null, | |
) { | |
val isEqualUri: Boolean? = _thumbnail.value?.isEqualUri(uri) | |
if (isEqualUri == false) { | |
thumbnailJobs[_thumbnail.value?.uri]?.cancel() | |
_thumbnail.value = ThumbnailUiModel(uri = uri, url = url) | |
} | |
} | |
private fun createThumbnail( | |
uri: Uri?, | |
url: String? = null, | |
) { | |
if (isDifferentUri(uri)) { | |
thumbnailJobs[_thumbnail.value?.uri]?.cancel() | |
_thumbnail.value = ThumbnailUiModel(uri = uri, url = url) | |
} | |
} | |
private fun isDifferentUri(uri: Uri?): Boolean = _thumbnail.value?.isEqualUri(uri) == false |
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.
저도 호두의 의견에 동의합니다~
새로운 Thumbnail로 바꾼다는 setThumbnail 라는 네이밍은 어떤가요?
조금 더 구체적으로, Uri만 바꿔준다는 의미까지 포함해 fun setThumbnailUri()
도 괜찮을 것 같아요!
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.
조금 더 구체적으로, Uri만 바꿔준다는 의미까지 포함해 fun setThumbnailUri()도 괜찮을 것 같아요!
해당 메서드는 Uri
만 변경해주는 역할이라 빙티가 제안해주신 setThumbnailUri
가 가장 명시적으로 다가오네요!
반영해두었습니다😊
반영 커밋
: 863b9be
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.
추가로 기존 Uri와 다른 Uri인지 확인하는 코드를 아래처럼 메서드로 분리하면 코드가 좀 더 깔끔해질 것 같아요!
변수로 분리하는 것보다 메서드로 분리하는 게 더 깔끔하겠네요!
private fun setThumbnailUri(
uri: Uri?,
url: String? = null,
) {
if (isNewUri(uri)) {
...
}
}
private fun isNewUri(uri: Uri?): Boolean = _thumbnail.value?.isEqualUri(uri) == false
매개변수로 들어온 Uri가 새로운 Uri일 때 uri를 설정한다는 것을 명시적으로 나타내기 위해 isNewUri
라는 메서드명으로 분리했습니다!
반영 커밋
: 7a1bebc
thumbnailJobs[uri] = job | ||
} | ||
|
||
private fun fetchThumbnail( |
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.
추억 썸네일을 업로드하는 Job을 생성하고 반환해주는 메서드로 역할이 바뀌었으니, createJobFetchingThumbnail
와 같이 Job에 대한 메서드임을 나타내는 것도 좋을 것 같아요!
해나는 어떻게 생각하시나요??
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.
호두가 제안해주신 이름은 "fetching thumbnail
를 수행하는 job을 생성한다"라는 의미를 더 명확하게 전달한다는 점에서 저도 동의합니다!
더해서, 함수 명의 구조를 동사 + 목적어 형태로 하기 위해 createFetchingThumbnailJob
도 좋을 것 같아요~
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.
서버에서 데이터를 불러올 때 fetchXXX 형식을 사용하기로 해서 fetchThumbnail
로 네이밍 했었습니다.
지금은 썸네일 사진 업로드 Job 객체를 반환하는 역할도 포함하고 있기 때문에, 단순히 데이터를 불러오는 작업만 수행한다고 볼 수 없겠네요!
createFetchingThumbnailJob
로 변경했습니다!
반영 커밋
: 9e028d2
private fun setThumbnailUrl(imageResponse: ImageResponse?) { | ||
val newUrl = imageResponse?.imageUrl | ||
_thumbnail.value = _thumbnail.value?.updateUrl(newUrl) | ||
_isPhotoPosting.value = false | ||
} | ||
|
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.
이미지 삭제 버튼 클릭 시, Activity
가 이미지 Url
을 null
로 설정하기 위해서 ImageResponse
를 nullable
로 두었었지만,
지금은 ThumbnailUiModel
의 도입과 함께 해당 메서드가 Activity
에서 사용되지 않으므로, nullable
로 둘 이유가 사라졌네요!
nullable
을 지워도 될 것 같습니다 😃
private fun setThumbnailUrl(imageResponse: ImageResponse?) { | |
val newUrl = imageResponse?.imageUrl | |
_thumbnail.value = _thumbnail.value?.updateUrl(newUrl) | |
_isPhotoPosting.value = false | |
} | |
private fun setThumbnailUrl(imageResponse: ImageResponse) { | |
val newUrl = imageResponse.imageUrl | |
_thumbnail.value = _thumbnail.value?.updateUrl(newUrl) | |
_isPhotoPosting.value = false | |
} |
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.
ThumbnailUiModel
구현 후 이를 적용하는 과정에서 매개변수의 타입 변경을 놓쳤었는데, ImageResponse를 nullable로 둔 이유를 호두가 저에게 질문해 줘서 해당 부분을 짚고 넘어갈 수 있었습니다. 감사합니다!
반영 커밋
: 499b185
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.
버그 해결하느라 고생하셨습니다 해나! 코루틴과 싸워 이기셨군요 👍
|
||
fun isEqualUri(newUri: Uri?): Boolean = uri == newUri | ||
|
||
fun delete() = this.copy(uri = null, url = null) |
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.
사소한 부분인데, delete는 컬렉션의 원소나 인스턴스 자체를 삭제하는 동작을 연상시킨다고 생각해요!
ThumbnailUiModel
의 uri와 url 정보를 모두 null로 설정해 값을 비운다는 의미를 더 명확하게 나타내기 위해 clear
라는 함수명은 어떠신가요?
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.
delete
보다 clear
라는 네이밍이 더 적합하겠네요! clear
로 변경했습니다!
반영 커밋
: 27ecb45
fun setThumbnailUrl(imageResponse: ImageResponse?) { | ||
_thumbnailUrl.value = imageResponse?.imageUrl | ||
_isPhotoPosting.value = false | ||
fun deleteThumbnail() { |
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.
해당 함수명도 마찬가지로 clearThumbnail이 어떨까요?
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.
반영했습니다!
반영 커밋
: c0f5458
private fun createThumbnail( | ||
uri: Uri?, | ||
url: String? = null, | ||
) { | ||
val isEqualUri: Boolean? = _thumbnail.value?.isEqualUri(uri) | ||
if (isEqualUri == false) { | ||
thumbnailJobs[_thumbnail.value?.uri]?.cancel() | ||
_thumbnail.value = ThumbnailUiModel(uri = uri, url = url) | ||
} | ||
} |
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.
저도 호두의 의견에 동의합니다~
새로운 Thumbnail로 바꾼다는 setThumbnail 라는 네이밍은 어떤가요?
조금 더 구체적으로, Uri만 바꿔준다는 의미까지 포함해 fun setThumbnailUri()
도 괜찮을 것 같아요!
val isEqualUri: Boolean? = _thumbnail.value?.isEqualUri(uri) | ||
if (isEqualUri == false) { | ||
thumbnailJobs[_thumbnail.value?.uri]?.cancel() | ||
_thumbnail.value = ThumbnailUiModel(uri = uri, url = url) |
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.
덧붙여서, private fun createThumbnail()
의 url 매개 변수는 항상 null이 되겠네요.
fun createThumbnailUrl(
context: Context,
uri: Uri,
) {
_isPhotoPosting.value = true
createThumbnail(uri) // uri만 넣어주고 있음. url은 항상 default인 null
registerThumbnailJob(context, uri)
}
그렇다면 url 매개변수를 제거하고 아래처럼 null을 직접 넣어주는 것이 더 명시적일 것 같아요~!
_thumbnail.value = ThumbnailUiModel(uri = uri, url = url) | |
_thumbnail.value = ThumbnailUiModel(uri = uri, url = null) |
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.
헉 그렇네요! 수정했습니다~
반영 커밋
: 382d063
thumbnailJobs[uri] = job | ||
} | ||
|
||
private fun fetchThumbnail( |
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.
호두가 제안해주신 이름은 "fetching thumbnail
를 수행하는 job을 생성한다"라는 의미를 더 명확하게 전달한다는 점에서 저도 동의합니다!
더해서, 함수 명의 구조를 동사 + 목적어 형태로 하기 위해 createFetchingThumbnailJob
도 좋을 것 같아요~
fun setThumbnailUrl(imageResponse: ImageResponse?) { | ||
_thumbnailUrl.value = imageResponse?.imageUrl | ||
_isPhotoPosting.value = false | ||
fun deleteThumbnail() { |
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.
추가로, 사진의 X 버튼이 눌렸을 때에도 리소스 관리를 위해 Job.cancel을 수행해야 한다는 생각이 드네요!
thumbnailJobs[_thumbnail.value?.uri]?.cancel()
로직을 deleteThumbnail() 내부로 옮기는 건 어떨까요?
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.
추억 생성 및 수정 화면에서는 사진이 업로드 중일 때 X 버튼이 보여지지 않도록 구현되어 있습니다!
즉, 서버에 사진을 업로드하고 해당 사진의 URL을 서버에서 클라이언트로 전송하는 작업이 완료되어야 사용자가 X 버튼을 사용할 수 있습니다.
따라서 X 버튼이 사용자에게 보여진 시점에는 job
이 마지막 상태인 Completed
에 도달해 invokeOnCompletion
에 의해 자원이 이미 해제된 상태이기 때문에 추가적으로 Job.cancel
을 수행할 필요가 없다고 생각했습니다! 😊
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 (isEqualUri == false) { | ||
thumbnailJobs[_thumbnail.value?.uri]?.cancel() | ||
_thumbnail.value = ThumbnailUiModel(uri = uri, url = url) | ||
} | ||
} | ||
|
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.
thumbnailJobs[_thumbnail.value?.uri]?.cancel()
로직을 deleteThumbnail() 내부로 옮기면 아래처럼 재사용 가능할 것 같네요!
if (isEqualUri == false) { | |
thumbnailJobs[_thumbnail.value?.uri]?.cancel() | |
_thumbnail.value = ThumbnailUiModel(uri = uri, url = url) | |
} | |
} | |
if (isEqualUri == false) { | |
deleteThumbnail() | |
} | |
_thumbnail.value = ThumbnailUiModel(uri = uri) |
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.
#542 (comment) 와 동일한 의견입니다!
) { | ||
val isEqualUri: Boolean? = _thumbnail.value?.isEqualUri(uri) | ||
if (isEqualUri == false) { | ||
thumbnailJobs[_thumbnail.value?.uri]?.cancel() |
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.
아래 두 경우, Job.cancel()을 호출해도 코루틴이 이를 수신할 수 없어 즉시 취소되지 않습니다!
- 코루틴에 suspend 포인트가 없는 경우
- isActive를 확인하지 않는 경우
이렇게 내부적으로 취소될 수 없는 상태인 경우를 고려해 저는 Job.cancel()을 호출하기 전에 isActive로 수동으로 상태를 확인해주곤 하는데요!
if (photoJobs[deletedPhoto.uri.toString()]?.isActive == true) {
photoJobs[deletedPhoto.uri.toString()]?.cancel()
}
Retrofit2 interface에서 지원하는 코루틴은 취소될 수 있는 코루틴일 것 같아 이 과정이 불필요한가? 싶기도 하네요 🤔
시간 되면 같이 '얕게 다이브' 해봐도 좋을 것 같아요!
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.
헉 이 부분을 놓쳤네요!! 감사합니다~ 빙빙 짱!
isActive
를 수동으로 상태를 확인하는 방법으로 변경했습니다!
반영 커밋
: fa613e6
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.
Retrofit2 interface에서 지원하는 코루틴은 취소될 수 있는 코루틴일 것 같아 이 과정이 불필요한가? 싶기도 하네요 🤔
이와 관련해서 Retrofit2의 내부 구현을 찾아 봤는 데 아직 이해가 잘 안 되네요 ㅠㅠ
빙티와 호두의 면접이 끝나고 난 후에 같이 '얕게 다이브' 해보면 좋겠네요!!
- 이전: ImageResponse? - 이후: ImageResponse
- 이전: createThumbnail - 이후: setThumbnailUri
- 이전: delete - 이후: clear
- 이전: deleteThumbnail - 이후: clearThumbnail
- 이전: fetchThumbnail - 이후: createFetchingThumbnailJob
* fix: 누락된 not 연산자 추가 * refactor: whitelist 추가 #489 (#490) * deploy: 1.1.1 배포 #484 (#491) * fix: 누락된 not 연산자 추가 * refactor: whitelist 추가 #489 (#490) --------- Co-authored-by: hxeyexn <[email protected]> * feat: 인덱스 설정 스크립트 작성 #474 (#475) Co-authored-by: BurningFalls <[email protected]> * feat: Bulk Delete 예전 pr 코드 이동 (#487) * refactor: N+1 문제 해결 (#488) * �fix: 스타카토 댓글 UI 오류 해결 및 개선 #493 (#494) * ui: 스타카토 조회 오류 메시지를 strings 리소스에 작성 * ui: 키보드 입력 시 MainActivity의 화면 크기 조정되도록 변경 - MainActivity에 windowSoftInputMode를 adjustPan으로 설정 * refactor: 댓글과 조회 Fragment 병합 및 댓글 화면 개선 StaccatoFragment - 메서드 순서 조정 및 이름 변경 - staccatoId를 lazy 로 지연초기화하여 받아오도록 수정 - 댓글 ViewModel과 Adapter 추가 및 연결 - 댓글 업로드 시 스크롤 뷰의 스크롤을 하단으로 옮기도록 구현 StaccatoCommentsViewModel - 댓글 전송 성공한 상태를 저장하는 LiveData 추가 - Staccato ID 기본값 상수화 fragment_staccato.xml - 댓글 화면 마이그레이션 - 댓글 입력 창을 화면 최하단에 고정 - 전송 버튼 UI 오류 수정: 고정된 크기 * refactor: 기분 선택 fragment 리팩터링 진행 * refactor: 사용하지 않는 댓글 Fragment 제거 * ui: 댓글 전송 버튼 디자인 변경 - 이미지에서 Vector drawable 로 변경 - 색상 수정 * style: ktlint 적용 * refactor: StaccatoFragment 코드 정리 - onViewCreated의 함수 호출 순서대로 메서드 정렬 - pagePhotoAdapter 초기화를 lateinit에서 by lazy로 변경 - 메서드명 수정 - setUpBindings -> setUpBindings - initToolbarHandler -> setNavigationClickListener - initViewPagerAdapter -> setUpViewPager - loadStaccatoData -> loadStaccato * refactor: 메서드 순서를 컨벤션에 맞게 정렬 * refactor: 댓글 ViewModel의 스타카토 ID 설정 로직 수정 - Fragment가 댓글을 불러오는 동작을 알 필요가 없고, ViewModel에게 일일히 지시할 필요가 없다. - Fragment는 스타카토의 ID를 넘겨주기만 하고, ViewModel이 스타카토 ID를 알아서 설정하도록 변경 * refactor: ViewModel을 옵저빙하는 메서드 세분화 - StaccatoViewModel과 StaccatoCommentsViewModel을 옵저빙하는 메서드를 세분화 * refactor: StaccatoFeelingFragment 설정하는 메서드 리팩터링 - 메서드명 변경 : setStaccatoIdToFeelingFragment -> setStaccatoFeelingFragment - Fragment 생성 로직과 fragmentManager에 add하는 동작 분리 * ui: 댓글 입력 창과 전송 버튼 수정 - 댓글 전송 버튼의 크기를 줄이되, padding 설정으로 터치 영역 크기는 그대로 유지 - 댓글 전송 버튼의 제약 조건 수정하여 댓글 입력 창 내부에 위치하도록 변경 - 댓글 입력 창의 textAppearance 설정으로 텍스트 크기 고정 - 댓글 입력 창의 제약 조건 수정하여 전송 버튼을 감싸도록 수정 * ui: 가시성을 변경하는 바인딩어댑터 적용 * ui: viewTreeObserver 의 GlobalLayoutListener 제거 시점 변경 * ui: 댓글 전송 버튼을 텍스트 필드 범위의 바깥으로 이동 * style: ktlint 적용 * refactor: 반응형 ui 적용 및 접근성 향상 #481 (#502) * ui: login 화면 반응형 ui 대응 * ui: 고유 코드 복구 화면 반응형 ui 대응 * ui: 마이페이지 화면 반응형 ui 대응 * ui: 나의 추억들 화면 반응형 ui 대응 * ui: 추억 화면 반응형 ui 대응 - span count 조정 * refactor: 스타카토 생성 화면 반응형 ui 대응 * refactor: 스타카토 수정 화면 반응형 ui 대응 * refactor: 추억 생성 화면 반응형 ui 대응 * refactor: 추억 수정 화면 반응형 ui 대응 * ui: 다크모드 대응 - colors 대응 - themes 대응 - 지도 대응 * fix: 지도 화면의 구성 변경으로 일어나는 크래시 해결 * ui: 스플래시 다크모드 대응 * feat: 스타카토 마커 커스텀 * ui: 스타카토 마커 다크모드 대응 * feat: 사용자 피드백 수집을 위한 구글 폼 연동 * feat: 인스타그램 페이지 연동 * refactor: 마이페이지 버튼 터치 영역 확대 * refactor: TextInputEditText 터치 영역 확대 * refactor: 추억 기간 선택 box 터치 영역 확대 * refactor: 툴바 수정 및 삭제 메뉴 버튼 터치 영역 확대 * refactor: 마이페이지 인스타그램 버튼 터치 영역 확대 * refactor: 스타카토 장소 선택 box 버튼 터치 영역 확대 * refactor: 스타카토 추억, 날짜 및 시간 선택 box 터치 영역 확대 * ui: typography.Body에 Not.Resizable 추가 * ui: styles에 Not.Resizable 적용 * ui: 스타카토 생성 수정 화면 styles 적용 * ui: 추억 생성 수정 화면 styles 적용 * ui: styles_button.xml에 BoundedIconButtonStyle 추가 * ui: 추억, 타임라인 화면에 BoundedIconButtonStyle 적용 * ui: 타임라인 화면 글씨 크기 조절 대응 * ui: layout_photo_attach.xml 글씨 크기 조절 대응 * ui: 추억 조회 화면 글씨 크기 조절 대응 * ui: 행간 겹침 방지를 위해 lineHeight 단위 sp로 수정 * ui: empty 관련 텍스트 Not.Resizable 설정 * ui: 로그인 및 복구 화면 글씨 크기 조절 대응 * refactor: 홈 화면 content description 추가 * refactor: 나의 추억들 화면 content description 추가 * refactor: 추억 화면 content description 추가 * refactor: 추억 생성 및 수정 화면 content description 추가 * refactor: 스타카토 사진 첨부 item content description 추가 * refactor: 나의 추억들 아이템 중첩된 레이아웃 제거 * refactor: 스타카토 화면 content description 추가 * refactor: 마이페이지 화면 content description 추가 * refactor: 로그인 화면 content description 추가 * refactor: 나의 추억들 item content description 추가 * refactor: 댓글 item content description 추가 * refactor: 함께 한 사람들 item content description 추가 * �fix: 스타카토 댓글 UI 오류 해결 및 개선 #493 (#494) * ui: 스타카토 조회 오류 메시지를 strings 리소스에 작성 * ui: 키보드 입력 시 MainActivity의 화면 크기 조정되도록 변경 - MainActivity에 windowSoftInputMode를 adjustPan으로 설정 * refactor: 댓글과 조회 Fragment 병합 및 댓글 화면 개선 StaccatoFragment - 메서드 순서 조정 및 이름 변경 - staccatoId를 lazy 로 지연초기화하여 받아오도록 수정 - 댓글 ViewModel과 Adapter 추가 및 연결 - 댓글 업로드 시 스크롤 뷰의 스크롤을 하단으로 옮기도록 구현 StaccatoCommentsViewModel - 댓글 전송 성공한 상태를 저장하는 LiveData 추가 - Staccato ID 기본값 상수화 fragment_staccato.xml - 댓글 화면 마이그레이션 - 댓글 입력 창을 화면 최하단에 고정 - 전송 버튼 UI 오류 수정: 고정된 크기 * refactor: 기분 선택 fragment 리팩터링 진행 * refactor: 사용하지 않는 댓글 Fragment 제거 * ui: 댓글 전송 버튼 디자인 변경 - 이미지에서 Vector drawable 로 변경 - 색상 수정 * style: ktlint 적용 * refactor: StaccatoFragment 코드 정리 - onViewCreated의 함수 호출 순서대로 메서드 정렬 - pagePhotoAdapter 초기화를 lateinit에서 by lazy로 변경 - 메서드명 수정 - setUpBindings -> setUpBindings - initToolbarHandler -> setNavigationClickListener - initViewPagerAdapter -> setUpViewPager - loadStaccatoData -> loadStaccato * refactor: 메서드 순서를 컨벤션에 맞게 정렬 * refactor: 댓글 ViewModel의 스타카토 ID 설정 로직 수정 - Fragment가 댓글을 불러오는 동작을 알 필요가 없고, ViewModel에게 일일히 지시할 필요가 없다. - Fragment는 스타카토의 ID를 넘겨주기만 하고, ViewModel이 스타카토 ID를 알아서 설정하도록 변경 * refactor: ViewModel을 옵저빙하는 메서드 세분화 - StaccatoViewModel과 StaccatoCommentsViewModel을 옵저빙하는 메서드를 세분화 * refactor: StaccatoFeelingFragment 설정하는 메서드 리팩터링 - 메서드명 변경 : setStaccatoIdToFeelingFragment -> setStaccatoFeelingFragment - Fragment 생성 로직과 fragmentManager에 add하는 동작 분리 * ui: 댓글 입력 창과 전송 버튼 수정 - 댓글 전송 버튼의 크기를 줄이되, padding 설정으로 터치 영역 크기는 그대로 유지 - 댓글 전송 버튼의 제약 조건 수정하여 댓글 입력 창 내부에 위치하도록 변경 - 댓글 입력 창의 textAppearance 설정으로 텍스트 크기 고정 - 댓글 입력 창의 제약 조건 수정하여 전송 버튼을 감싸도록 수정 * ui: 가시성을 변경하는 바인딩어댑터 적용 * ui: viewTreeObserver 의 GlobalLayoutListener 제거 시점 변경 * ui: 댓글 전송 버튼을 텍스트 필드 범위의 바깥으로 이동 * style: ktlint 적용 --------- Co-authored-by: somin <[email protected]> Co-authored-by: hodu <[email protected]> * deploy: 1.1.2 배포 (#504) * fix: 누락된 not 연산자 추가 * refactor: whitelist 추가 #489 (#490) * feat: 인덱스 설정 스크립트 작성 #474 (#475) Co-authored-by: BurningFalls <[email protected]> * feat: Bulk Delete 예전 pr 코드 이동 (#487) * refactor: N+1 문제 해결 (#488) * �fix: 스타카토 댓글 UI 오류 해결 및 개선 #493 (#494) * ui: 스타카토 조회 오류 메시지를 strings 리소스에 작성 * ui: 키보드 입력 시 MainActivity의 화면 크기 조정되도록 변경 - MainActivity에 windowSoftInputMode를 adjustPan으로 설정 * refactor: 댓글과 조회 Fragment 병합 및 댓글 화면 개선 StaccatoFragment - 메서드 순서 조정 및 이름 변경 - staccatoId를 lazy 로 지연초기화하여 받아오도록 수정 - 댓글 ViewModel과 Adapter 추가 및 연결 - 댓글 업로드 시 스크롤 뷰의 스크롤을 하단으로 옮기도록 구현 StaccatoCommentsViewModel - 댓글 전송 성공한 상태를 저장하는 LiveData 추가 - Staccato ID 기본값 상수화 fragment_staccato.xml - 댓글 화면 마이그레이션 - 댓글 입력 창을 화면 최하단에 고정 - 전송 버튼 UI 오류 수정: 고정된 크기 * refactor: 기분 선택 fragment 리팩터링 진행 * refactor: 사용하지 않는 댓글 Fragment 제거 * ui: 댓글 전송 버튼 디자인 변경 - 이미지에서 Vector drawable 로 변경 - 색상 수정 * style: ktlint 적용 * refactor: StaccatoFragment 코드 정리 - onViewCreated의 함수 호출 순서대로 메서드 정렬 - pagePhotoAdapter 초기화를 lateinit에서 by lazy로 변경 - 메서드명 수정 - setUpBindings -> setUpBindings - initToolbarHandler -> setNavigationClickListener - initViewPagerAdapter -> setUpViewPager - loadStaccatoData -> loadStaccato * refactor: 메서드 순서를 컨벤션에 맞게 정렬 * refactor: 댓글 ViewModel의 스타카토 ID 설정 로직 수정 - Fragment가 댓글을 불러오는 동작을 알 필요가 없고, ViewModel에게 일일히 지시할 필요가 없다. - Fragment는 스타카토의 ID를 넘겨주기만 하고, ViewModel이 스타카토 ID를 알아서 설정하도록 변경 * refactor: ViewModel을 옵저빙하는 메서드 세분화 - StaccatoViewModel과 StaccatoCommentsViewModel을 옵저빙하는 메서드를 세분화 * refactor: StaccatoFeelingFragment 설정하는 메서드 리팩터링 - 메서드명 변경 : setStaccatoIdToFeelingFragment -> setStaccatoFeelingFragment - Fragment 생성 로직과 fragmentManager에 add하는 동작 분리 * ui: 댓글 입력 창과 전송 버튼 수정 - 댓글 전송 버튼의 크기를 줄이되, padding 설정으로 터치 영역 크기는 그대로 유지 - 댓글 전송 버튼의 제약 조건 수정하여 댓글 입력 창 내부에 위치하도록 변경 - 댓글 입력 창의 textAppearance 설정으로 텍스트 크기 고정 - 댓글 입력 창의 제약 조건 수정하여 전송 버튼을 감싸도록 수정 * ui: 가시성을 변경하는 바인딩어댑터 적용 * ui: viewTreeObserver 의 GlobalLayoutListener 제거 시점 변경 * ui: 댓글 전송 버튼을 텍스트 필드 범위의 바깥으로 이동 * style: ktlint 적용 * refactor: 반응형 ui 적용 및 접근성 향상 #481 (#502) * ui: login 화면 반응형 ui 대응 * ui: 고유 코드 복구 화면 반응형 ui 대응 * ui: 마이페이지 화면 반응형 ui 대응 * ui: 나의 추억들 화면 반응형 ui 대응 * ui: 추억 화면 반응형 ui 대응 - span count 조정 * refactor: 스타카토 생성 화면 반응형 ui 대응 * refactor: 스타카토 수정 화면 반응형 ui 대응 * refactor: 추억 생성 화면 반응형 ui 대응 * refactor: 추억 수정 화면 반응형 ui 대응 * ui: 다크모드 대응 - colors 대응 - themes 대응 - 지도 대응 * fix: 지도 화면의 구성 변경으로 일어나는 크래시 해결 * ui: 스플래시 다크모드 대응 * feat: 스타카토 마커 커스텀 * ui: 스타카토 마커 다크모드 대응 * feat: 사용자 피드백 수집을 위한 구글 폼 연동 * feat: 인스타그램 페이지 연동 * refactor: 마이페이지 버튼 터치 영역 확대 * refactor: TextInputEditText 터치 영역 확대 * refactor: 추억 기간 선택 box 터치 영역 확대 * refactor: 툴바 수정 및 삭제 메뉴 버튼 터치 영역 확대 * refactor: 마이페이지 인스타그램 버튼 터치 영역 확대 * refactor: 스타카토 장소 선택 box 버튼 터치 영역 확대 * refactor: 스타카토 추억, 날짜 및 시간 선택 box 터치 영역 확대 * ui: typography.Body에 Not.Resizable 추가 * ui: styles에 Not.Resizable 적용 * ui: 스타카토 생성 수정 화면 styles 적용 * ui: 추억 생성 수정 화면 styles 적용 * ui: styles_button.xml에 BoundedIconButtonStyle 추가 * ui: 추억, 타임라인 화면에 BoundedIconButtonStyle 적용 * ui: 타임라인 화면 글씨 크기 조절 대응 * ui: layout_photo_attach.xml 글씨 크기 조절 대응 * ui: 추억 조회 화면 글씨 크기 조절 대응 * ui: 행간 겹침 방지를 위해 lineHeight 단위 sp로 수정 * ui: empty 관련 텍스트 Not.Resizable 설정 * ui: 로그인 및 복구 화면 글씨 크기 조절 대응 * refactor: 홈 화면 content description 추가 * refactor: 나의 추억들 화면 content description 추가 * refactor: 추억 화면 content description 추가 * refactor: 추억 생성 및 수정 화면 content description 추가 * refactor: 스타카토 사진 첨부 item content description 추가 * refactor: 나의 추억들 아이템 중첩된 레이아웃 제거 * refactor: 스타카토 화면 content description 추가 * refactor: 마이페이지 화면 content description 추가 * refactor: 로그인 화면 content description 추가 * refactor: 나의 추억들 item content description 추가 * refactor: 댓글 item content description 추가 * refactor: 함께 한 사람들 item content description 추가 * �fix: 스타카토 댓글 UI 오류 해결 및 개선 #493 (#494) * ui: 스타카토 조회 오류 메시지를 strings 리소스에 작성 * ui: 키보드 입력 시 MainActivity의 화면 크기 조정되도록 변경 - MainActivity에 windowSoftInputMode를 adjustPan으로 설정 * refactor: 댓글과 조회 Fragment 병합 및 댓글 화면 개선 StaccatoFragment - 메서드 순서 조정 및 이름 변경 - staccatoId를 lazy 로 지연초기화하여 받아오도록 수정 - 댓글 ViewModel과 Adapter 추가 및 연결 - 댓글 업로드 시 스크롤 뷰의 스크롤을 하단으로 옮기도록 구현 StaccatoCommentsViewModel - 댓글 전송 성공한 상태를 저장하는 LiveData 추가 - Staccato ID 기본값 상수화 fragment_staccato.xml - 댓글 화면 마이그레이션 - 댓글 입력 창을 화면 최하단에 고정 - 전송 버튼 UI 오류 수정: 고정된 크기 * refactor: 기분 선택 fragment 리팩터링 진행 * refactor: 사용하지 않는 댓글 Fragment 제거 * ui: 댓글 전송 버튼 디자인 변경 - 이미지에서 Vector drawable 로 변경 - 색상 수정 * style: ktlint 적용 * refactor: StaccatoFragment 코드 정리 - onViewCreated의 함수 호출 순서대로 메서드 정렬 - pagePhotoAdapter 초기화를 lateinit에서 by lazy로 변경 - 메서드명 수정 - setUpBindings -> setUpBindings - initToolbarHandler -> setNavigationClickListener - initViewPagerAdapter -> setUpViewPager - loadStaccatoData -> loadStaccato * refactor: 메서드 순서를 컨벤션에 맞게 정렬 * refactor: 댓글 ViewModel의 스타카토 ID 설정 로직 수정 - Fragment가 댓글을 불러오는 동작을 알 필요가 없고, ViewModel에게 일일히 지시할 필요가 없다. - Fragment는 스타카토의 ID를 넘겨주기만 하고, ViewModel이 스타카토 ID를 알아서 설정하도록 변경 * refactor: ViewModel을 옵저빙하는 메서드 세분화 - StaccatoViewModel과 StaccatoCommentsViewModel을 옵저빙하는 메서드를 세분화 * refactor: StaccatoFeelingFragment 설정하는 메서드 리팩터링 - 메서드명 변경 : setStaccatoIdToFeelingFragment -> setStaccatoFeelingFragment - Fragment 생성 로직과 fragmentManager에 add하는 동작 분리 * ui: 댓글 입력 창과 전송 버튼 수정 - 댓글 전송 버튼의 크기를 줄이되, padding 설정으로 터치 영역 크기는 그대로 유지 - 댓글 전송 버튼의 제약 조건 수정하여 댓글 입력 창 내부에 위치하도록 변경 - 댓글 입력 창의 textAppearance 설정으로 텍스트 크기 고정 - 댓글 입력 창의 제약 조건 수정하여 전송 버튼을 감싸도록 수정 * ui: 가시성을 변경하는 바인딩어댑터 적용 * ui: viewTreeObserver 의 GlobalLayoutListener 제거 시점 변경 * ui: 댓글 전송 버튼을 텍스트 필드 범위의 바깥으로 이동 * style: ktlint 적용 --------- Co-authored-by: somin <[email protected]> Co-authored-by: hodu <[email protected]> --------- Co-authored-by: hxeyexn <[email protected]> Co-authored-by: linirini <[email protected]> Co-authored-by: YoonJuHo <[email protected]> Co-authored-by: hodu <[email protected]> Co-authored-by: Hyeyeon Gong <[email protected]> Co-authored-by: somin <[email protected]> * hotfix: 이미지 삭제 전파 (#505) * fix: 이미지 삭제 전파 * fix: 이미지 삭제 전파 수정 * deploy: 1.1.3 배포 (#506) * fix: 누락된 not 연산자 추가 * refactor: whitelist 추가 #489 (#490) * feat: 인덱스 설정 스크립트 작성 #474 (#475) Co-authored-by: BurningFalls <[email protected]> * feat: Bulk Delete 예전 pr 코드 이동 (#487) * refactor: N+1 문제 해결 (#488) * �fix: 스타카토 댓글 UI 오류 해결 및 개선 #493 (#494) * ui: 스타카토 조회 오류 메시지를 strings 리소스에 작성 * ui: 키보드 입력 시 MainActivity의 화면 크기 조정되도록 변경 - MainActivity에 windowSoftInputMode를 adjustPan으로 설정 * refactor: 댓글과 조회 Fragment 병합 및 댓글 화면 개선 StaccatoFragment - 메서드 순서 조정 및 이름 변경 - staccatoId를 lazy 로 지연초기화하여 받아오도록 수정 - 댓글 ViewModel과 Adapter 추가 및 연결 - 댓글 업로드 시 스크롤 뷰의 스크롤을 하단으로 옮기도록 구현 StaccatoCommentsViewModel - 댓글 전송 성공한 상태를 저장하는 LiveData 추가 - Staccato ID 기본값 상수화 fragment_staccato.xml - 댓글 화면 마이그레이션 - 댓글 입력 창을 화면 최하단에 고정 - 전송 버튼 UI 오류 수정: 고정된 크기 * refactor: 기분 선택 fragment 리팩터링 진행 * refactor: 사용하지 않는 댓글 Fragment 제거 * ui: 댓글 전송 버튼 디자인 변경 - 이미지에서 Vector drawable 로 변경 - 색상 수정 * style: ktlint 적용 * refactor: StaccatoFragment 코드 정리 - onViewCreated의 함수 호출 순서대로 메서드 정렬 - pagePhotoAdapter 초기화를 lateinit에서 by lazy로 변경 - 메서드명 수정 - setUpBindings -> setUpBindings - initToolbarHandler -> setNavigationClickListener - initViewPagerAdapter -> setUpViewPager - loadStaccatoData -> loadStaccato * refactor: 메서드 순서를 컨벤션에 맞게 정렬 * refactor: 댓글 ViewModel의 스타카토 ID 설정 로직 수정 - Fragment가 댓글을 불러오는 동작을 알 필요가 없고, ViewModel에게 일일히 지시할 필요가 없다. - Fragment는 스타카토의 ID를 넘겨주기만 하고, ViewModel이 스타카토 ID를 알아서 설정하도록 변경 * refactor: ViewModel을 옵저빙하는 메서드 세분화 - StaccatoViewModel과 StaccatoCommentsViewModel을 옵저빙하는 메서드를 세분화 * refactor: StaccatoFeelingFragment 설정하는 메서드 리팩터링 - 메서드명 변경 : setStaccatoIdToFeelingFragment -> setStaccatoFeelingFragment - Fragment 생성 로직과 fragmentManager에 add하는 동작 분리 * ui: 댓글 입력 창과 전송 버튼 수정 - 댓글 전송 버튼의 크기를 줄이되, padding 설정으로 터치 영역 크기는 그대로 유지 - 댓글 전송 버튼의 제약 조건 수정하여 댓글 입력 창 내부에 위치하도록 변경 - 댓글 입력 창의 textAppearance 설정으로 텍스트 크기 고정 - 댓글 입력 창의 제약 조건 수정하여 전송 버튼을 감싸도록 수정 * ui: 가시성을 변경하는 바인딩어댑터 적용 * ui: viewTreeObserver 의 GlobalLayoutListener 제거 시점 변경 * ui: 댓글 전송 버튼을 텍스트 필드 범위의 바깥으로 이동 * style: ktlint 적용 * refactor: 반응형 ui 적용 및 접근성 향상 #481 (#502) * ui: login 화면 반응형 ui 대응 * ui: 고유 코드 복구 화면 반응형 ui 대응 * ui: 마이페이지 화면 반응형 ui 대응 * ui: 나의 추억들 화면 반응형 ui 대응 * ui: 추억 화면 반응형 ui 대응 - span count 조정 * refactor: 스타카토 생성 화면 반응형 ui 대응 * refactor: 스타카토 수정 화면 반응형 ui 대응 * refactor: 추억 생성 화면 반응형 ui 대응 * refactor: 추억 수정 화면 반응형 ui 대응 * ui: 다크모드 대응 - colors 대응 - themes 대응 - 지도 대응 * fix: 지도 화면의 구성 변경으로 일어나는 크래시 해결 * ui: 스플래시 다크모드 대응 * feat: 스타카토 마커 커스텀 * ui: 스타카토 마커 다크모드 대응 * feat: 사용자 피드백 수집을 위한 구글 폼 연동 * feat: 인스타그램 페이지 연동 * refactor: 마이페이지 버튼 터치 영역 확대 * refactor: TextInputEditText 터치 영역 확대 * refactor: 추억 기간 선택 box 터치 영역 확대 * refactor: 툴바 수정 및 삭제 메뉴 버튼 터치 영역 확대 * refactor: 마이페이지 인스타그램 버튼 터치 영역 확대 * refactor: 스타카토 장소 선택 box 버튼 터치 영역 확대 * refactor: 스타카토 추억, 날짜 및 시간 선택 box 터치 영역 확대 * ui: typography.Body에 Not.Resizable 추가 * ui: styles에 Not.Resizable 적용 * ui: 스타카토 생성 수정 화면 styles 적용 * ui: 추억 생성 수정 화면 styles 적용 * ui: styles_button.xml에 BoundedIconButtonStyle 추가 * ui: 추억, 타임라인 화면에 BoundedIconButtonStyle 적용 * ui: 타임라인 화면 글씨 크기 조절 대응 * ui: layout_photo_attach.xml 글씨 크기 조절 대응 * ui: 추억 조회 화면 글씨 크기 조절 대응 * ui: 행간 겹침 방지를 위해 lineHeight 단위 sp로 수정 * ui: empty 관련 텍스트 Not.Resizable 설정 * ui: 로그인 및 복구 화면 글씨 크기 조절 대응 * refactor: 홈 화면 content description 추가 * refactor: 나의 추억들 화면 content description 추가 * refactor: 추억 화면 content description 추가 * refactor: 추억 생성 및 수정 화면 content description 추가 * refactor: 스타카토 사진 첨부 item content description 추가 * refactor: 나의 추억들 아이템 중첩된 레이아웃 제거 * refactor: 스타카토 화면 content description 추가 * refactor: 마이페이지 화면 content description 추가 * refactor: 로그인 화면 content description 추가 * refactor: 나의 추억들 item content description 추가 * refactor: 댓글 item content description 추가 * refactor: 함께 한 사람들 item content description 추가 * �fix: 스타카토 댓글 UI 오류 해결 및 개선 #493 (#494) * ui: 스타카토 조회 오류 메시지를 strings 리소스에 작성 * ui: 키보드 입력 시 MainActivity의 화면 크기 조정되도록 변경 - MainActivity에 windowSoftInputMode를 adjustPan으로 설정 * refactor: 댓글과 조회 Fragment 병합 및 댓글 화면 개선 StaccatoFragment - 메서드 순서 조정 및 이름 변경 - staccatoId를 lazy 로 지연초기화하여 받아오도록 수정 - 댓글 ViewModel과 Adapter 추가 및 연결 - 댓글 업로드 시 스크롤 뷰의 스크롤을 하단으로 옮기도록 구현 StaccatoCommentsViewModel - 댓글 전송 성공한 상태를 저장하는 LiveData 추가 - Staccato ID 기본값 상수화 fragment_staccato.xml - 댓글 화면 마이그레이션 - 댓글 입력 창을 화면 최하단에 고정 - 전송 버튼 UI 오류 수정: 고정된 크기 * refactor: 기분 선택 fragment 리팩터링 진행 * refactor: 사용하지 않는 댓글 Fragment 제거 * ui: 댓글 전송 버튼 디자인 변경 - 이미지에서 Vector drawable 로 변경 - 색상 수정 * style: ktlint 적용 * refactor: StaccatoFragment 코드 정리 - onViewCreated의 함수 호출 순서대로 메서드 정렬 - pagePhotoAdapter 초기화를 lateinit에서 by lazy로 변경 - 메서드명 수정 - setUpBindings -> setUpBindings - initToolbarHandler -> setNavigationClickListener - initViewPagerAdapter -> setUpViewPager - loadStaccatoData -> loadStaccato * refactor: 메서드 순서를 컨벤션에 맞게 정렬 * refactor: 댓글 ViewModel의 스타카토 ID 설정 로직 수정 - Fragment가 댓글을 불러오는 동작을 알 필요가 없고, ViewModel에게 일일히 지시할 필요가 없다. - Fragment는 스타카토의 ID를 넘겨주기만 하고, ViewModel이 스타카토 ID를 알아서 설정하도록 변경 * refactor: ViewModel을 옵저빙하는 메서드 세분화 - StaccatoViewModel과 StaccatoCommentsViewModel을 옵저빙하는 메서드를 세분화 * refactor: StaccatoFeelingFragment 설정하는 메서드 리팩터링 - 메서드명 변경 : setStaccatoIdToFeelingFragment -> setStaccatoFeelingFragment - Fragment 생성 로직과 fragmentManager에 add하는 동작 분리 * ui: 댓글 입력 창과 전송 버튼 수정 - 댓글 전송 버튼의 크기를 줄이되, padding 설정으로 터치 영역 크기는 그대로 유지 - 댓글 전송 버튼의 제약 조건 수정하여 댓글 입력 창 내부에 위치하도록 변경 - 댓글 입력 창의 textAppearance 설정으로 텍스트 크기 고정 - 댓글 입력 창의 제약 조건 수정하여 전송 버튼을 감싸도록 수정 * ui: 가시성을 변경하는 바인딩어댑터 적용 * ui: viewTreeObserver 의 GlobalLayoutListener 제거 시점 변경 * ui: 댓글 전송 버튼을 텍스트 필드 범위의 바깥으로 이동 * style: ktlint 적용 --------- Co-authored-by: somin <[email protected]> Co-authored-by: hodu <[email protected]> * hotfix: 이미지 삭제 전파 (#505) * fix: 이미지 삭제 전파 * fix: 이미지 삭제 전파 수정 --------- Co-authored-by: hxeyexn <[email protected]> Co-authored-by: linirini <[email protected]> Co-authored-by: BurningFalls <[email protected]> Co-authored-by: hodu <[email protected]> Co-authored-by: Hyeyeon Gong <[email protected]> Co-authored-by: somin <[email protected]> * feat: 기본 추억 제공 구현 #508 (#509) * feat: 기본 추억 생성 구현 * refactor: 기본 추억 설명 수정 * fix: persist 전파되도록 로직 순서 변경 * deploy: 1.2.0 배포 (#510) * fix: 누락된 not 연산자 추가 * refactor: whitelist 추가 #489 (#490) * feat: 인덱스 설정 스크립트 작성 #474 (#475) Co-authored-by: BurningFalls <[email protected]> * feat: Bulk Delete 예전 pr 코드 이동 (#487) * refactor: N+1 문제 해결 (#488) * �fix: 스타카토 댓글 UI 오류 해결 및 개선 #493 (#494) * ui: 스타카토 조회 오류 메시지를 strings 리소스에 작성 * ui: 키보드 입력 시 MainActivity의 화면 크기 조정되도록 변경 - MainActivity에 windowSoftInputMode를 adjustPan으로 설정 * refactor: 댓글과 조회 Fragment 병합 및 댓글 화면 개선 StaccatoFragment - 메서드 순서 조정 및 이름 변경 - staccatoId를 lazy 로 지연초기화하여 받아오도록 수정 - 댓글 ViewModel과 Adapter 추가 및 연결 - 댓글 업로드 시 스크롤 뷰의 스크롤을 하단으로 옮기도록 구현 StaccatoCommentsViewModel - 댓글 전송 성공한 상태를 저장하는 LiveData 추가 - Staccato ID 기본값 상수화 fragment_staccato.xml - 댓글 화면 마이그레이션 - 댓글 입력 창을 화면 최하단에 고정 - 전송 버튼 UI 오류 수정: 고정된 크기 * refactor: 기분 선택 fragment 리팩터링 진행 * refactor: 사용하지 않는 댓글 Fragment 제거 * ui: 댓글 전송 버튼 디자인 변경 - 이미지에서 Vector drawable 로 변경 - 색상 수정 * style: ktlint 적용 * refactor: StaccatoFragment 코드 정리 - onViewCreated의 함수 호출 순서대로 메서드 정렬 - pagePhotoAdapter 초기화를 lateinit에서 by lazy로 변경 - 메서드명 수정 - setUpBindings -> setUpBindings - initToolbarHandler -> setNavigationClickListener - initViewPagerAdapter -> setUpViewPager - loadStaccatoData -> loadStaccato * refactor: 메서드 순서를 컨벤션에 맞게 정렬 * refactor: 댓글 ViewModel의 스타카토 ID 설정 로직 수정 - Fragment가 댓글을 불러오는 동작을 알 필요가 없고, ViewModel에게 일일히 지시할 필요가 없다. - Fragment는 스타카토의 ID를 넘겨주기만 하고, ViewModel이 스타카토 ID를 알아서 설정하도록 변경 * refactor: ViewModel을 옵저빙하는 메서드 세분화 - StaccatoViewModel과 StaccatoCommentsViewModel을 옵저빙하는 메서드를 세분화 * refactor: StaccatoFeelingFragment 설정하는 메서드 리팩터링 - 메서드명 변경 : setStaccatoIdToFeelingFragment -> setStaccatoFeelingFragment - Fragment 생성 로직과 fragmentManager에 add하는 동작 분리 * ui: 댓글 입력 창과 전송 버튼 수정 - 댓글 전송 버튼의 크기를 줄이되, padding 설정으로 터치 영역 크기는 그대로 유지 - 댓글 전송 버튼의 제약 조건 수정하여 댓글 입력 창 내부에 위치하도록 변경 - 댓글 입력 창의 textAppearance 설정으로 텍스트 크기 고정 - 댓글 입력 창의 제약 조건 수정하여 전송 버튼을 감싸도록 수정 * ui: 가시성을 변경하는 바인딩어댑터 적용 * ui: viewTreeObserver 의 GlobalLayoutListener 제거 시점 변경 * ui: 댓글 전송 버튼을 텍스트 필드 범위의 바깥으로 이동 * style: ktlint 적용 * refactor: 반응형 ui 적용 및 접근성 향상 #481 (#502) * ui: login 화면 반응형 ui 대응 * ui: 고유 코드 복구 화면 반응형 ui 대응 * ui: 마이페이지 화면 반응형 ui 대응 * ui: 나의 추억들 화면 반응형 ui 대응 * ui: 추억 화면 반응형 ui 대응 - span count 조정 * refactor: 스타카토 생성 화면 반응형 ui 대응 * refactor: 스타카토 수정 화면 반응형 ui 대응 * refactor: 추억 생성 화면 반응형 ui 대응 * refactor: 추억 수정 화면 반응형 ui 대응 * ui: 다크모드 대응 - colors 대응 - themes 대응 - 지도 대응 * fix: 지도 화면의 구성 변경으로 일어나는 크래시 해결 * ui: 스플래시 다크모드 대응 * feat: 스타카토 마커 커스텀 * ui: 스타카토 마커 다크모드 대응 * feat: 사용자 피드백 수집을 위한 구글 폼 연동 * feat: 인스타그램 페이지 연동 * refactor: 마이페이지 버튼 터치 영역 확대 * refactor: TextInputEditText 터치 영역 확대 * refactor: 추억 기간 선택 box 터치 영역 확대 * refactor: 툴바 수정 및 삭제 메뉴 버튼 터치 영역 확대 * refactor: 마이페이지 인스타그램 버튼 터치 영역 확대 * refactor: 스타카토 장소 선택 box 버튼 터치 영역 확대 * refactor: 스타카토 추억, 날짜 및 시간 선택 box 터치 영역 확대 * ui: typography.Body에 Not.Resizable 추가 * ui: styles에 Not.Resizable 적용 * ui: 스타카토 생성 수정 화면 styles 적용 * ui: 추억 생성 수정 화면 styles 적용 * ui: styles_button.xml에 BoundedIconButtonStyle 추가 * ui: 추억, 타임라인 화면에 BoundedIconButtonStyle 적용 * ui: 타임라인 화면 글씨 크기 조절 대응 * ui: layout_photo_attach.xml 글씨 크기 조절 대응 * ui: 추억 조회 화면 글씨 크기 조절 대응 * ui: 행간 겹침 방지를 위해 lineHeight 단위 sp로 수정 * ui: empty 관련 텍스트 Not.Resizable 설정 * ui: 로그인 및 복구 화면 글씨 크기 조절 대응 * refactor: 홈 화면 content description 추가 * refactor: 나의 추억들 화면 content description 추가 * refactor: 추억 화면 content description 추가 * refactor: 추억 생성 및 수정 화면 content description 추가 * refactor: 스타카토 사진 첨부 item content description 추가 * refactor: 나의 추억들 아이템 중첩된 레이아웃 제거 * refactor: 스타카토 화면 content description 추가 * refactor: 마이페이지 화면 content description 추가 * refactor: 로그인 화면 content description 추가 * refactor: 나의 추억들 item content description 추가 * refactor: 댓글 item content description 추가 * refactor: 함께 한 사람들 item content description 추가 * �fix: 스타카토 댓글 UI 오류 해결 및 개선 #493 (#494) * ui: 스타카토 조회 오류 메시지를 strings 리소스에 작성 * ui: 키보드 입력 시 MainActivity의 화면 크기 조정되도록 변경 - MainActivity에 windowSoftInputMode를 adjustPan으로 설정 * refactor: 댓글과 조회 Fragment 병합 및 댓글 화면 개선 StaccatoFragment - 메서드 순서 조정 및 이름 변경 - staccatoId를 lazy 로 지연초기화하여 받아오도록 수정 - 댓글 ViewModel과 Adapter 추가 및 연결 - 댓글 업로드 시 스크롤 뷰의 스크롤을 하단으로 옮기도록 구현 StaccatoCommentsViewModel - 댓글 전송 성공한 상태를 저장하는 LiveData 추가 - Staccato ID 기본값 상수화 fragment_staccato.xml - 댓글 화면 마이그레이션 - 댓글 입력 창을 화면 최하단에 고정 - 전송 버튼 UI 오류 수정: 고정된 크기 * refactor: 기분 선택 fragment 리팩터링 진행 * refactor: 사용하지 않는 댓글 Fragment 제거 * ui: 댓글 전송 버튼 디자인 변경 - 이미지에서 Vector drawable 로 변경 - 색상 수정 * style: ktlint 적용 * refactor: StaccatoFragment 코드 정리 - onViewCreated의 함수 호출 순서대로 메서드 정렬 - pagePhotoAdapter 초기화를 lateinit에서 by lazy로 변경 - 메서드명 수정 - setUpBindings -> setUpBindings - initToolbarHandler -> setNavigationClickListener - initViewPagerAdapter -> setUpViewPager - loadStaccatoData -> loadStaccato * refactor: 메서드 순서를 컨벤션에 맞게 정렬 * refactor: 댓글 ViewModel의 스타카토 ID 설정 로직 수정 - Fragment가 댓글을 불러오는 동작을 알 필요가 없고, ViewModel에게 일일히 지시할 필요가 없다. - Fragment는 스타카토의 ID를 넘겨주기만 하고, ViewModel이 스타카토 ID를 알아서 설정하도록 변경 * refactor: ViewModel을 옵저빙하는 메서드 세분화 - StaccatoViewModel과 StaccatoCommentsViewModel을 옵저빙하는 메서드를 세분화 * refactor: StaccatoFeelingFragment 설정하는 메서드 리팩터링 - 메서드명 변경 : setStaccatoIdToFeelingFragment -> setStaccatoFeelingFragment - Fragment 생성 로직과 fragmentManager에 add하는 동작 분리 * ui: 댓글 입력 창과 전송 버튼 수정 - 댓글 전송 버튼의 크기를 줄이되, padding 설정으로 터치 영역 크기는 그대로 유지 - 댓글 전송 버튼의 제약 조건 수정하여 댓글 입력 창 내부에 위치하도록 변경 - 댓글 입력 창의 textAppearance 설정으로 텍스트 크기 고정 - 댓글 입력 창의 제약 조건 수정하여 전송 버튼을 감싸도록 수정 * ui: 가시성을 변경하는 바인딩어댑터 적용 * ui: viewTreeObserver 의 GlobalLayoutListener 제거 시점 변경 * ui: 댓글 전송 버튼을 텍스트 필드 범위의 바깥으로 이동 * style: ktlint 적용 --------- Co-authored-by: somin <[email protected]> Co-authored-by: hodu <[email protected]> * hotfix: 이미지 삭제 전파 (#505) * fix: 이미지 삭제 전파 * fix: 이미지 삭제 전파 수정 * feat: 기본 추억 제공 구현 #508 (#509) * feat: 기본 추억 생성 구현 * refactor: 기본 추억 설명 수정 * fix: persist 전파되도록 로직 순서 변경 --------- Co-authored-by: hxeyexn <[email protected]> Co-authored-by: BurningFalls <[email protected]> Co-authored-by: YoonJuHo <[email protected]> Co-authored-by: hodu <[email protected]> Co-authored-by: Hyeyeon Gong <[email protected]> Co-authored-by: somin <[email protected]> * fix: file changed 인식 불가로 인한 순서 변경 (#511) * feat: 모든 화면에서 네트워크 에러 핸들링 #501 (#516) * fix: ApiResponseHandler try-catch문 범위 수정 * refactor: StaccatoApiService의 반환값 Response로 wrapping * refactor: StaccatoDataSource의 반환값 ResponseResult로 wrapping * refactor: StaccatoRepository의 반환값 ResponseResult로 wrapping * refactor: StaccatoRepository를 사용하는 ViewModel에 에러 처리 변경사항 적용 * feat: MessageUtils.kt에 showSnackBarWithAction 추가 * feat: TimelineFragment 네트워크 에러 발생 시 스낵바 처리 * feat: MemoryFragment 네트워크 에러 발생 시 스낵바 처리 * feat: StaccatoFragment 네트워크 에러 발생 시 스낵바 처리 * refactor: 불필요한 Log.e 메서드 제거 * style: 네트워크 에러 메시지 상수명 통일 * refactor: MessageUtils에 getSnackBarWithAction 메서드 추가 * feat: Memory 생성/수정 화면 에러 핸들링 * feat: Staccato 생성/수정 화면 에러 핸들링 * feat: 마이페이지 화면 네트워크 에러 핸들링 * fix: 스타카토 조회 화면 코멘트 에러 핸들링 * refactor: 추억 에러 관련 data class 리네이밍 Photo -> Thumbnail * refactor: 추억 생성 에러 data class 리네이밍 MemoryCreate -> MemoryCreation * refactor: 메서드명 카멜 케이스로 통일 (reCreate) * refactor: 추억 업데이트 에러 data class 리네이밍 MemoryInitialize -> MemoryInitialization * refactor: getSnackBarWithAction의 length를 named arguments로 수정 * refactor: EXCEPTION_NETWORK_ERROR_MESSAGE 텍스트 내용 수정 * refactor: 이미지 업로드 실패 메시지 상수화 * refactor: StaccatoUpdateViewModel의 메시지 상수화 및 PhotoException 분리 * refactor: 스낵바 Util 불필요한 apply 제거 * build: 안드로이드 CI/CD 재설정 #445 (#513) * build: android ci 타겟 브랜치 변경 - develop-an -> develop 브랜치로 변경 * build: 개발 단계용 android ci, cd 설정 - Debug용 APK 파일이 아닌 Release용 APK 파일을 추출하도록 변경 - gradle assembleRelease : 앱을 release 모드로 빌드, Debug 정보를 포함하지 않기에 용량이 더 적고, 난독화가 적용되어 있다. * build: 개발 단계용 android ci, cd 설정 - 타겟 브랜치 변경 : develop -> release-an 으로 변경 - Debug용 APK 파일이 아닌 Release용 APK 파일을 추출하도록 변경 - gradle assembleRelease : 앱을 release 모드로 빌드, Debug 정보를 포함하지 않기에 용량이 더 적고, 난독화가 적용되어 있다. * build: android ci 워크플로우 이름 변경 * build: android cd 재설정 - 구글 플레이 콘솔 자동 배포 설정 * build: Play Console 배포 설정 변경 - 서비스 계정 Key 파일 secret 변수 변경 - whatsNewDirectory 설정 * build: android ci 적용 브랜치 수정 - release-an 브랜치, main 브랜치 추가 * fix: 안드로이드 CI 오류 수정 #519 (#521) * fix: android-ci.yml 파일 수정 * fix: android-ci.yml 파일 수정 * feat: 나의 추억들 정렬 기능 구현 #503 (#507) * ui: 정렬 메뉴 ui 구현 * feat: 나의 추억들 정렬 기능 구현 * feat: 기간 유무에 따른 추억 필터 기능 구현 * refactor: 정렬 타입에 따른 정렬 선택 로직을 view model이 가지도록 변경 - 정렬 타입과 정렬 menu id를 가지고 있는 SortType Enum Class 생성 * refactor: timeline ui model 셋팅 로직 수정 * refactor: 사용자가 선택한 menuId와 일치하는 SortType을 찾는 로직을 팩토리 함수로 분리 * refactor: 원본 timeline clear 로직 추가 * refactor: 기간 있는 추억 내림차순 정렬 조건 추가 * fix: 추억 삭제 후 나의 추억들(타임라인)이 갱신되지 않는 오류 수정 * fix: 나의 추억들(타임라인) 정렬 시 포커스가 유지되는 문제 해결 * refactor: originalTimeline 타입 변경 * ui: 기분 캐릭터 변경 #522 (#523) * ui: 음표 기분 캐릭터 추가 * refactor: 음표 기분 캐릭터 적용 * feat: 카메라 촬영 기능 연결 #514 (#524) * build: androidx camera 의존성 추가 - 버전 카탈로그 활용 * build: AndroidManifest 카메라 접근 기능 수정 - android.hardware.camera.any 로 설정하여 전, 후면 모두 사용 가능하도록 변경 * ui: 사진 업로드 다이얼로그에서 ㄷ사용할 문자열 리소스 설정 - 권한 관련 안내 메시지 추가 * feat: 카메라 기능 추가 - 접근 권한 확인 후 카메라 실행 - 카메라에서 촬영한 사진을 가져와 Activity에게 이미지 URI 전달 * style: ktlint 적용 * fix: 권한 요청 스낵바와 에러 메시지 스낵바 분리 * ui: 권한 요청 스낵바의 문구 수정 * fix: 외부 저장소 쓰기 권한 추가 * deploy: v.1.2.0 배포 준비 #515 (#525) * refactor: versionCode 및 versionName 업데이트 - versionCode: 4 -> 5 - versionName: "1.1.0" -> "1.2.0" * ui: 마이페이지에 노출될 앱 버전 명 업데이트 - 앱 버전: "1.1.0" -> "1.2.0" * docs: 1.2.0 버전 출시 노트 추가 * fix: Android CD 수정 #527 (#528) * fix: push branch 에 release-an 추가 * fix: 출시 노트 옵션 파일경로 수정 * chore: Thread, Hikari CP 변경 (#518) * feat: Hikari CP, Thread 설정 변경 * fix: writer, reader에 각각 hikari 설정 * feat: 기본 추억 제목 변경 #530 (#531) * feat: 기본 추억 이름을 ~의 추억으로 설정 * refactor: 변수 사용 * fix: 스타카토 삭제 시 마커가 갱신되지 않는 오류 해결 #533 (#534) * fix: 스타카토 삭제 시 마커가 갱신되지 않는 오류 해결 * build: versionCode 업그레이드 - versionCode: 5 -> 6 --------- Co-authored-by: Junyoung-WON <[email protected]> * feat & fix: 사진 코루틴 취소 버그 수정 / ACTION_PICK_IMAGES 적용 #536 (#537) * chore: 카메라와 사진 권한 메시지 분리 * feat: ACTION_PICK_IMAGES 적용 및 장 수 선택 제한 * fix: 사진 업로드 코루틴에서 예외 시 isActive 체크 * style: StaccatoUpdateViewModel ktlintFormat * refactor: 코드 리뷰 반영 * refactor: 코드 리뷰 반영 - 상수화 * docs: bug-issue-template 생성 * docs: 기능 이슈 템플릿 작성 * docs: 기능 이슈 템플릿 수정 * docs: 기능 이슈 템플릿 수정 * docs: 리팩터링 이슈 템플릿 작성 * docs: 기존 이슈 템플릿 제거 * chore: cd workflow 작동 브랜치 수정 * refactor: comments api uri 수정 #544 (#549) * feat: comment uri 변경 및 버저닝 * refactor: 불필요한 코드 변경을 최소화하기 위해 uri 상에서 버저닝 위치 변경 * refactor: 스타카토 목록 조회 시 최신순 정렬 #545 (#550) * refactor: 스타카토 목록 조회 시 최신순 정렬하도록 정렬 기준 변경 * test: 검증 메서드 순서 확인 여부 수정 * feat: 스타카토의 방문 날짜가 같다면 생성 기준 최신순으로 조회하도록 구현 * refactor: 스타카토 수정 시 발생하는 조회에서 정렬 없이 조회하도록 수정 * fix: 추억 생성 및 수정 썸네일 사진 업로드 오류 수정 #535 (#542) * fix: 추억 생성 사진 업로드 버그 수정 - 사진 A를 업로드 중 사진 B로 변경하면 네트워크 연결 불안정 스낵바가 뜨는 오류 해결 * fix: 추억 수정 사진 업로드 버그 수정 - 사진 A를 업로드 중 사진 B로 변경하면 네트워크 연결 불안정 스낵바가 뜨는 오류 * refactor: ThumbnailUiModel 구현 및 적용 * refactor: 썸네일 사진용 BindingAdapters 수정 * refactor: 추억 생성 사진 업로드 로직 변경 * refactor: 추억 수정 사진 업로드 로직 변경 * style: MemoryUpdateViewModel 메서드 순서 변경 * refactor: fetchThumbnail의 thumbnailUri 매개변수 이름 변경 - 이전: thumbnailUri - 이후: uri * refactor: 사용하지 않는 ThumbnailUiModel 갱신 메서드 제거 * refactor: 추억 썸네일 uri를 칭하는 typealias 이름 변경 * refactor: thumbnailUrl 설정 메서드의 매개변수 타입 변경 - 이전: ImageResponse? - 이후: ImageResponse * refactor: 추억 썸네일 uri 수정 메서드 이름 변경 - 이전: createThumbnail - 이후: setThumbnailUri * refactor: 새로운 uri인지 확인하는 로직을 메서드로 분리 * refactor: ThumbnailUiModel 초기화 메서드 이름 변경 - 이전: delete - 이후: clear * refactor: Thumbnail 삭제 메서드 이름 변경 - 이전: deleteThumbnail - 이후: clearThumbnail * refactor: uri 설정 메서드의 url 매개변수 제거 * refactor: 추억 썸네일 사진 업로드 후 job을 반환하는 메서드명 변경 - 이전: fetchThumbnail - 이후: createFetchingThumbnailJob * refactor: 사진 업로드 작업 취소 시 isActive 상태 확인 * chore: 개발 서버 이전 #551 (#557) * chore: dev cd workflow 수정 * chore: log 파일 저장 경로 오류 수정 Co-authored-by: YoonJuHo <[email protected]>, BurningFalls <[email protected]> * refactor: 서버 이전에 따른 S3 설정 변경 Co-authored-by: BurningFalls <[email protected]>, YoonJuHo <[email protected]> * refactor: 서버 이전에 따른 S3 폴더 경로 수정 Co-authored-by: BurningFalls <[email protected]>, YoonJuHo <[email protected]> * chore: gradle 캐싱 적용 Co-authored-by: BurningFalls <[email protected]>, YoonJuHo <[email protected]> * chore: gradle 캐싱 적용 Co-authored-by: YoonJuHo <[email protected]>, BurningFalls <[email protected]> * chore: 도커 이미지 제거 명령어 추가 Co-authored-by: YoonJuHo <[email protected]>, BurningFalls <[email protected]> --------- Co-authored-by: YoonJuHo <[email protected]>, BurningFalls <[email protected]> Co-authored-by: BurningFalls <[email protected]>, YoonJuHo <[email protected]> * refactor: comment API의 URI 수정 #560 (#561) * refactor: comment API의 URI 수정 URI 상수 이름 변경 - COMMENTS_PATH -> COMMENTS_URI Path Variable 상수화 - momentId 상수화 : MOMENT_ID - commentId 상수화 : COMMENT_ID 댓글 수정, 삭제 API의 URI 수정 - Query String에서 Path Variable로 변경 - Path Variable로 commentId가 담긴 URI 상수 생성 : COMMENTS_URI_WITH_COMMENT_ID - URI의 v2는 추후 제거 예정 * refactor: CommentApiService 내 moment를 staccato로 변경 누락된 도메인명 수정 사항 반영 - MOMENT_ID -> STACCATO_ID - momentId -> staccatoId - 서버 측은 도메인명이 수정되지 않았으므로, 실제 URI 값은 변경하지 않음 * refactor: CommentRequest 내 moment를 staccato로 변경 누락된 도메인명 수정 사항 반영 - momentId -> staccatoId - 서버 측은 도메인명이 수정되지 않았으므로, SerialName 값은 변경하지 않음 * deploy: v.1.2.1 배포 준비 #539 (#541) * ui: 마이페이지의 앱 버전 업데이트 - 1.2.0 -> 1.2.1 로 업데이트 * build: versionCode 와 versionName 업데이트 - versionCode: 6 -> 7 - versionName: 1.2.0 -> 1.2.1 * docs: 출시 노트 수정 - 1.2.1 버전: 버그 수정 내용 추가 * docs: 출시 노트의 업데이트 날짜 수정 - 10.31 -> 11.27 --------- Co-authored-by: hxeyexn <[email protected]> Co-authored-by: linirini <[email protected]> Co-authored-by: BurningFalls <[email protected]> Co-authored-by: YoonJuHo <[email protected]> Co-authored-by: Hyeyeon Gong <[email protected]> Co-authored-by: somin <[email protected]> Co-authored-by: linirini <[email protected]> Co-authored-by: Somin Lee <[email protected]>
⭐️ Issue Number
🎥 시연 영상
Screen_Recording_20241107-130050_Staccato-DEV.1.mp4
Screen_Recording_20241107-131454_Staccato-DEV.1.mp4
🚩 Summary
🛠️ Technical Concerns
문제 상황
ProtocolException
예외가 발생했고ApiResponseHandler
에서 잡혀 네트워크 불안정 스낵바가 노출되었습니다.ProtocolException
이란?Nginx access.log
를 확인해보니499
에러가 발생하고 있었습니다.access.log란?
499(Client closed the connection)란?
서버가 응답을 완료하기 전에
Application Gateway
로 전송되는 클라이언트 요청이 닫힌 경우를 뜻합니다.Application Gateway
란?발생 원인
Application Gateway
는 기존의 완료되지 않은 요청을 처리하고 있습니다.Nginx
를Application Gateway
의 역할로 사용하고 있습니다.Application Gateway
측에서 프로토콜 위반으로 간주됩니다.ProtocolException
이 발생해ApiResponseHandler
에서 잡혀 네트워크 불안정 스낵바가 보여졌습니다.해결 방법
uri
를 키 값으로 가진 사진 업로드job
들을map
으로 관리하는 방식으로 변경했습니다.invokeOnCompletion
메서드를 활용해job
이Completed
나Cancelled
와 같은 마지막 상태에 도달했을 때 자원을 해제하도록 구현했습니다.uri
가 이전과 동일하지 않다면cancel
메서드를 활용해 코루틴을 취소하도록 변경했습니다.