From 28d8ef6e36a25aed9608df50a5363803d50cdeab Mon Sep 17 00:00:00 2001 From: k_dragonm <78788847+briandr97@users.noreply.github.com> Date: Wed, 8 Nov 2023 13:03:32 +0900 Subject: [PATCH] =?UTF-8?q?[ALL]=20=EB=B2=84=EC=A0=84=205=20=EC=B6=9C?= =?UTF-8?q?=EC=8B=9C=20release/v3.1=EC=97=90=EC=84=9C=20main=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=BD=94=EB=93=9C=20=EB=A8=B8=EC=A7=80=20(#551)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [ALL] 버전 5 출시 release/v3.1 로 백엔드 코드 머지 (#549) * feat: 명세서 기준으로 Dto들 생성 (#89) * feat: 명세서 기준으로 Dto들 생성 * feat: 변경된 API 명세에 맞춰 Dto 변경 * feat: 디바이스의 위치를 받아와 뷰에 보여주는 기능 구현 (#93) * feat: 디바이스의 위치를 받아와 뷰에 보여주는 기능 구현 * refactor: 좌표를 문자열로 반환하는 기능 함수분리 * feat: 도메인 모델 생성 (#91) * refactor: ERROR를 NONE으로네이밍 변경 * feat: 도메인 객체 생성 (미완) * feat: 도메인 객체 수정 및 추가 생성 * feat: 도메인 수정 * rename: 패키지명 수정 * feat: 통계 path 레트로핏 서비스 구현 #101 * feat: 서버에서 Rank 관련 데이터를 받아올 때 사용될 service 생성 (#100) * feat: 3차 데모데이용 Game Path 레트로핏 서비스 생성 (#102) * feat: 장소 path 레트로핏 서비스 구현 (#103) * feat: AdventureHistoryActivity 구현 (#106) * design: AdventureHistory 뷰에 필요한 string resource 추가 * design: AdventureHistory 뷰에 필요한 drawable resource 추가 * design: 리사이클러뷰에 들어갈 Item 레이아웃 생성 * feat: 모험 기록을 보여 주는 리사이클러뷰 어댑터 생성 * feat: AdventureHistory 액티비티 구현 * feat: AdventureHistoryActivity에 모험 기록을 보여줄 리사이클러뷰 구현 * feat: 뒤로가기 버튼 구현 * refactor: 함수 이름 변경 * refactor: 이름이 길어질 때 줄여쓰기가 되도록 기능 추가 * refactor: Mock 데이터 생성 방법 수정 * refactor: 불필요한 함수 인자 삭제 * feat: RankRepository 생성 (#109) * refactor: Service 명 수정 * feat: RankRepository Interface 구현 * feat: PlayerDto를 도메인 객체로 바꿔주는 도메인 mapper 생성 * feat: RankDto를 도메인 객체로 바꿔주는 도메인 mapper 생성 * feat: 서버와 Rank 데이터를 주고 받기 위해 팔요한 rank service 객체 생성 * feat: RankRepository 구현체 생성 * refactor: 함수 인자 표시 * feat: StatisticsRepository 생성 (#110) * rename: 파일명 수정 * feat: StatisticsRepository 인터페이스 생성 * feat: 서버와의 Statistics 관련 통신을 위한 service 객체 생성 * feat: StatisticsDto 객체를 도메인 객체로 바꿔주는 Mapper 생성 * feat: StatisticsRepository 구현체 생성 * refactor: 함수 인자 표시 * feat: 3차 데모데이 기획 변경에 맞는 AdventureRepository 설계 및 구현 (#111) * feat: 3차 데모데이 기획 변경에 맞는 AdventureRepository 설계 및 구현 * chore: 잘못 위치한 파일 위치 변경 * feat: PlaceRepository 생성 (#118) * feat: 장소 repository interface 생성 * feat: 서비스풀에 장소 서비스 추가 * feat: place mapper 생성 * feat: 장소 repository 구현체 생성 * refactor: 오류처리 변경에 따른 repository 코드 수정 * feat: 통계 path api 목서버 구현 (#116) * feat: 랭크 path api 목서버 구현 (#117) * feat: 랭크 path api 목서버 구현 * feat: 필요없는 변수 변환 로직 제거 * feat: RankActivity 구현 (#119) * feat: RankActivity 생성 * feat: RankActivity의 Intent를 생성해주는 함수 구현 * feat: 내 순위 및 전체 순위 목 데이터를 라이브 데이터 값으로 넣어주는 기능 구현 * design: RankActivity에 필요한 string resource 추가 * design: 내 순위 및 전체 순위를 보여주는 뷰 구현 * feat: 전체 순위를 띄워줄 리사이클러뷰 생성 및 구현 * feat: LiveData를 이용해 리사이클러뷰에 리스트 전달 * feat: 창 닫기 버튼 추가 구현 * refactor: Manifest 내의 rankActivity 위치 이동 * refactor: 컨벤션에 맞게 id 변경 * design: elevation을 활용해 그림자 추가 * refactor: dimens 적용 * refactor: 그림자 적용 * feat: 카메라로 찍은 사진을 뷰에 띄우고 Uri 추출기능 구현 (#120) * feat: 촬영한 사진을 이미지뷰에 보여주는 기능 구현 * feat: 촬영한 사진의 Uri 추출 기능 구현 * refactor: 권한 요청 로직 수정 및 함수 위치 변경 - 업로드 화면으로 이동 시 시스템 권한 요구 상자 팝업(카메라, 위치) - 거절한 권한에 대해 권한요청 다이얼로그 프래그먼트 팝업 * feat: 좌표 이미지를 클릭하여 좌표를 받아 보여주는 기능 구현 * feat: 닫기 버튼 추가 * feat: 3차 데모데이 뼈대 코드 추가 (#130) * refactor: AuthInterceptor에서 인증처리만 하도록 변경 * feat: PlayerException 추가 * feat: Player를 MemberId로 조회하는 기능 추가 * refactor: 로그인 된 PlayerId를 받는 ArgumentResolver 구현 * refactor: PlayerService 적용 refactor: Request DTO 와 Command DTO 분리 * feat: MyPageActivity 구현 (#121) * refactor: ERROR를 NONE으로네이밍 변경 * feat: 도메인 객체 생성 (미완) * feat: 도메인 객체 수정 및 추가 생성 * feat: 인터넷 권한 추가 * feat: 마이페이지의 아이템에 필요한 리사이클러뷰 구현 * feat: 마이페이지에 재사용이 여러번 될 가능성이 있는 뷰를 커스텀 뷰로 제작 * feat: 마이페이지 액티비티 생성 * style: 개행 * feat: 마이페이지 아이템의 두가지 경우의 레이아웃을 따로 제작 * feat: 레이아웃이 두개로 나눠짐에 따라 어댑터 수정중 * feat: 마이페이지 커스텀 아이템 레이아웃 수정 * feat: 마이페이지 커스텀 아이템 내부 리사이클러뷰 구현 방식 변경 (멀티 뷰홀더 적용) * feat: 마이페이지 뷰 구현 * feat: 도메인 모델을 UI모델로 변경할 매퍼 함수 생성 * design: mypage 레이아웃 디자인 변경 * feat: 뒤로가기 클릭리스너 추가 * remove: 중복된 객체 삭제 * refactor: view의 id 수정 * feat: Statistics 도메인 객체 수정으로 인해 자료형 변환 로직 추가 * fix: BaseEntity에 맞춘 data.sql 수정 (#133) * [BE] refactor: Pull Request 워크플로우 수정 (#134) * refactor: DTO들이 모두 record로 구현되도록 수정 (#136) * refactor: Pull Request 워크플로우 재수정 * feat: merge 워크 플로우 추가 (#137) * [BE] feat: merge 워크 플로우 추가 * [BE] refactor: merge 워크플로우 수정 * [BE] feat: 도커파일 생성 * [BE] refactor: 도커파일 이름 수정 * [BE] refactor: merge 워크플로우 재수정 * refactor: merge 워크 플로우 추가 (#139) * feat: merge 워크 플로우 추가 --------- Co-authored-by: zillionme <100172683+zillionme@users.noreply.github.com> Co-authored-by: dooboocookie <79090478+dooboocookie@users.noreply.github.com> * feat: 랭크 조회 기능 구현 (#94) * feat: 맴버 아이디로 플레이어 찾는 기능 구현 * feat: RankResponse dto 구현 * feat: RankResponse 정적팩토리 생성자 구현 * feat: 전체 랭크 조회 기능 구현 * feat: 나의 랭크 조회 기능 구현 * refactor: 요청 파라미터 예외 설정 * test: 테스트코드 추가 * refactor: 예외처리 로직 수정 * refactor: json 명세 수정으로 인한 dto 수정 * refactor: players 도메인을 삭제하고 Rank도메인으로 리팩토링 * refactor: 변수명 수정 * test: 테스트 오류 수정 * style: 디버깅 삭제 * feat: 랭크 뷰 기능 구현 및 서버 통신 구현 (#138) * remove: 필요없는 목 서버 삭제 * feat: 인자가 있는 ViewModel 생성을 위해 ViewModelFactory 생성 * feat: RankDto에 Serializable을 달아주어 직렬화가 가능하도록 구현 * refactor: 불필요한 null 검증 로직 제거 * feat: 서버와 통신해 전체 랭크와 내 랭크 정보를 받아온 후 사용자에게 보여주는 기능 구현 * feat: 서버 통신을 실패해 데이터를 불러오지 못했을 때 메시지를 띄운 후 창이 닫히도록 구현 * refactor: Retrofit Builder에 목서버 url로 갈아끼움 * refactor: 서버 통신 실패 시 에러 처리 로직 함수 분리 * feat: 시작 화면에서 랭크 버튼 클릭 시 랭크 화면으로 이동하도록 구현 * refactor: 함수 이름 변경 * refactor: 리사이클러뷰 애니메이터 설정 변경 * refactor: 내 등수 단위 표시 string 추가 * refactor: ktlint 적용 * refactor: 랭킹 관련 레트로핏 서비스의 path 변경 * feat: 게임 결과 뷰 서버 통신 및 기능 구현 (#143) * feat: gameId 값을 받아오는 intent * feat: 뷰모델에 인자로 레포지터리를 넘겨주기 위해 뷰모델 팩토리 생성 * refactor: RankDto에 Serializable을 달아주어 직렬화가 가능하도록 구현 * design: 게임 결과 화면에 필요한 string resource 추가 * refactor: 목 서버와의 연결을 위해 baseUrl 변경 * refactor: 랭크 API 통신을 위해 ViewModel에 RankRepository 인자 추가 * feat: 서버와 통신해 게임 결과를 받아온 후 사용자에게 보여주는 기능 구현 * feat: 서버와 통신해 내 랭크를 받아온 후 사용자에게 보여주는 기능 구현 * feat: 총 플레이 시간을 포매팅해서 보여주는 기능 구현 * feat: 메인으로 돌아가기 버튼을 누를 시 메인으로 돌아가게 하는 기능 구현 * refactor: timeFormatter의 패턴 상수화 처리 * refactor: 불필요한 Log 삭제 * design: color resource 추가 * refactor: 함수 분리 * refactor: 뷰 간격 조절 * feat: 서버에서 받아 온 imageUrl을 Glide를 사용해 이미지로 띄워주는 기능 구현 * design: 버튼 크기 조절 * feat: 모험 결과 DTO와 도메인 객체의 raisedRank 삭제 * feat: 랭크 변동 상황을 알려주는 뷰 삭제 * feat: 인자 변경에 따른 수정 사항 적용 * feat: 모험 기록 뷰 기능 구현 및 서버 통신 구현 (#151) * design: 모험 기록 뷰 디자인 변경 * design: 모험 기록 뷰 리사이클러뷰 아이템 디자인 변경 * refactor: 뷰 생성 위치 변경, 함수명 변경 * feat: 아이템에 사진 넣는 로직 추가 * feat: 뷰모델 팩토리 생성, 로컬 목데이터에서 가져오던 데이터를 서버로부터 가져오도록 변경 * feat: manifest exported 변경 * feat: 이미지 뷰 corner radius 적용 * design: 색상 변경 및 그림자 적용 * design: 마진값 변경 * [AN] feat: MyPage 기능 구현 (#146) * feat: 게임 결과 조회 기능 구현 (#152) * feat: 게임 아이디를 통해 게임결과를 조회한다 * feat: 결과 반환을 위한 responseDTO 생성 * refactor: 게임 결과를 위한 도메인 수정 * feat: 게임 결과 반환 기능 구현 완료 * style: 코드 컨벤션에 맞게 수정 * style: 코드 컨벤션에 맞게 수정 * refactor: 게임 도메인의 오류 리팩토링 * refactor: final 추가 * refactor: 게임 전체 결과 가져오는 로직 수정 * feat: 게임 종료 API 및 게임 조회 테스트 구현 (#147) * test: 게임 종료 기능 테스트 * feat: 게임 종료 기능 기본 구조 추가 * feat: 게임 종료 기능 구현 * test: 게임 점수 계산 기능 테스트 * feat: 게임 점수 계산 기능 구현 * test: 게임 점수 계산 테스트 수정 * test: 게임 종료 및 게임 결과 저장 서비스 테스트 * feat: 게임 종료 서비스 및 dto 구현 * test: 게임 종료 api 테스트 * feat: 게임 종료 api 구현 * test: 게임 종료 api 테스트 수정 * test: sql파일 수정 및 게임 종료 api 테스트 추가 * feat: 모험 결과 DTO와 도메인 객체의 raisedRank 삭제 * feat: 랭크 변동 상황을 알려주는 뷰 삭제 * feat: 인자 변경에 따른 수정 사항 적용 * test: 게임 종료 api 예외 처리 테스트 추가 * refactor: Game 클래스 필요없는 메서드 제거 및 리팩터링 * feat: 모험 기록 뷰 기능 구현 및 서버 통신 구현 (#151) * design: 모험 기록 뷰 디자인 변경 * design: 모험 기록 뷰 리사이클러뷰 아이템 디자인 변경 * refactor: 뷰 생성 위치 변경, 함수명 변경 * feat: 아이템에 사진 넣는 로직 추가 * feat: 뷰모델 팩토리 생성, 로컬 목데이터에서 가져오던 데이터를 서버로부터 가져오도록 변경 * feat: manifest exported 변경 * feat: 이미지 뷰 corner radius 적용 * design: 색상 변경 및 그림자 적용 * design: 마진값 변경 * [AN] feat: MyPage 기능 구현 (#146) * feat: 게임 결과 조회 기능 구현 (#152) * feat: 게임 아이디를 통해 게임결과를 조회한다 * feat: 결과 반환을 위한 responseDTO 생성 * refactor: 게임 결과를 위한 도메인 수정 * feat: 게임 결과 반환 기능 구현 완료 * style: 코드 컨벤션에 맞게 수정 * style: 코드 컨벤션에 맞게 수정 * refactor: 게임 도메인의 오류 리팩토링 * refactor: final 추가 * refactor: 게임 전체 결과 가져오는 로직 수정 * refactor: 테스트 fixture 클래스 생성 * refactor: 테스트 fixture 적용 * fix: 레포지토리 테스트 truncate.sql 추가 * fix: 서비스 테스트 트랜잭션 추가 * test: 게임 식별자로 게임 조회 테스트 추가 * chore: 식별자로 게임 조회 메서드명 변경 * chore: 머지 컨플릭트 해결 --------- Co-authored-by: hyunji1203 Co-authored-by: k_dragonm <78788847+briandr97@users.noreply.github.com> Co-authored-by: krrong Co-authored-by: chaewon121 <80631952+chaewon121@users.noreply.github.com> * feat: 장소 등록 api 구현 * feat: BaseEntity 생성 * feat: Player 도메인 생성 * feat: Hint 도메인 생성 Co-authored-by: dooboocookie * feat: GameResult 도메인 생성 Co-authored-by: dooboocookie * style: import문 최적화 Co-authored-by: dooboocookie * feat: 스프링 부트 어플리케이션에 @EnableJpaAuditing 추가 Co-authored-by: dooboocookie * refactor: 게임 도메인 수정 Co-authored-by: dooboocookie * refactor: 장소 도메인 생성 Co-authored-by: dooboocookie * refactor: Score 도메인 생성 Co-authored-by: dooboocookie * refactor: Place에 BaseEntity 상속 추가 * refactor: Member에 BaseEntity 상속 추가 및 생성자 추가 * test: 장소를 주가하는 기능 tdd test: 테스트에서 사용되는 값 fixture 생성 * feat: 장소 저장하는 기능 구현 * feat: 장소 저장하는 기능 구현 * feat: places 응답 DTO 추가 * test: 장소 생성 API E2E 테스트 추가 feat: 장소 생성 API 구현 * refactor: PlaceCheckService 도메인 서비스 생성 refactor: MultipartFileManager 파일 저장기 생성 * feat: 임시 커밋 * refactor: File 저장 경로 profile에서 변수로 관리하도록 변경 * feat: Place 전체 조회 기능 추가 - 정렬 기능 * feat: Place 단건 조회 기능 추가 * feat: Place 추천 서비스 도메인 서비스로 분리 * feat: Place 생성 서비스 로직 매개변수로 CreatePlaceCommand 받도록 수정 * refacotr: 파일 저장 경로 application.properties에서 받도록 수정 * test: Fixture 수정 및 테스트 수정 * test: 장소 추가 API 테스트 추가 test: 장소 추가 API 예외 테스트 추가 test: 아이디 장소 조회 API 테스트 추가 test: 장소 조회 API 테스트 추가 * test: 테스트 수정 * chore: 충돌 해결 --------- Co-authored-by: kokodak * chore: 안드로이드 CI workflow 수정 * feat: 힌트 생성 API 설계 및 구현 (#142) * feat: 위경도 좌표를 통해 방향을 계산하는 기능 구현 * feat: memberId 로 Member 를 찾는 기능 구현 * feat: PlayerService 생성 * feat: 힌트 생성에 대한 Command DTO 생성 * feat: 힌트 결과에 대한 DTO 생성 * feat: 힌트에 대한 Service 생성 * feat: 게임에서 힌트를 더 사용할 수 있는지에 대한 판단 기능 구현 * feat: 힌트 생성에 대한 Request DTO 생성 * feat: 힌트 생성에 대한 Command DTO 생성 * feat: 힌트 개수에 따른 생성 제약 조건 및 예외 추가 * feat: GameController 에 힌트 생성 API 로직 구현 * fix: 힌트 최대 사용 개수 수정 * refactor: 게임 최대 시도 횟수를 상수로 추출 * test: 로컬 테스트 환경 설정 * feat: cascade 조건 추가 * test: 더미데이터를 담은 테스트용 fixture 생성 * test: 힌트 생성 기능에 대한 테스트 작성 * chore: RestAssured 의존성 추가 * fix: Game 에서의 cascade 적용 철회 및 테스트 일부 수정 * test: 힌트 생성 API 테스트 코드 작성 * style: 코드 정렬 * feat: 특정 게임의 힌트 단건 조회 API 설계 및 구현 (#157) * feat: 힌트 조회 Command DTO 생성 * feat: 힌트 관련 예외 추가 * refactor: MemberFixture 에서 매직넘버를 상수로 추출 * feat: 힌트 id를 통해 힌트를 조회하는 기능 구현 * feat: 힌트 id를 통한 힌트 조회 API 구현 refactor: HintResponse 구조 수정 remove: DirectionResponse 삭제 * chore: 병합 충돌 해결 * style: 코드 정렬 * feat: 인게임 화면 기능 및 서버통신 구현 (#149) * feat: OnAdventure의 기능목록 작성 * feat: 분리된 Factory 클래스 삭제. ViewModle의 동반객체로 이동 * feat: 기능 개발중.. 임시 커밋 * feat: 라이브데이터를 상황에 맞게 커스텀 하려고 시도중 * feat: 도메인이 추가 및 변경됨에 따라 UiModel과 Mapper를 생성 * feat: Place 도메인 기능 추가 * feat: 인게임 화면에서 필요한 상태 및 로직들을 뷰모델에 작성 * feat: 네이버맵에 대한 코드로 인해 액티비티가 너무 길어져 액티비티 코드를 줄이기 위해 분리를 시도중 * style: 아이콘 추가 * feat: 목서버 base url 적용 * feat: 라이브데이터로부터 옵저버가 처음 한번만 notify를 받을 수 있는 라이브데이터 생성 * design: 아이콘 추가 * feat: Positive 버튼과 Negative 버튼이 존재하는 다이얼로그를 재사용할 수 있도록 생성 및 포기하기, 힌트 사용하기 다이얼로그 빌더 함수 생성 * feat: OnAdventureActivity에서 네이버맵 관련 작업을 분리한 코드 작성 - 힌트 마커 추가 - 목적지 마커 추가 - 네이버 로고 위치 조정 - 나침반 위치 조정 - 내 위치 버튼 위치 조정 * feat: OnAdventureViewmodel 재구현 * feat: Dto에 빠진 Serializable 어노테이션 추가 * feat: 뷰모델 변경으로 인해 데이터바인딩 수정 * design: string resources 추가 * feat: OnAdventureActivity 기능 구현 - 오류 처리 - 서버 통신(목서버) - 다이얼로그 띄우기 * feat: adventureRepository 변경으로 인한 수정 * feat: 뷰모델 팩토리 위치 변경 * feat: 도메인 변경으로 인한 코드 수정 * style: 매니페스트 정리 * refactor: NaagaAlertDialog 개선. 버튼 클릭 이벤트를 다이얼로그 생성시 무조건 받도록 수정함 * feat: AdventureResultActivity를 생성하는 인텐트를 받아오는 방식 변경 및 adventureId를 함께 넘겨줌 * chore: 백엔드 CD 워크플로우 수정 --------- Co-authored-by: zillionme <100172683+zillionme@users.noreply.github.com> * feat: 점진적 리팩토링이 완료됨에 따라 파일 정리 (#156) * refactor: 기존에 사용하던 Adventure 도메인 객체와 AdventureRepository가 완전히 대체되었으므로 삭제하고 새로 생성한 객체들의 임시 네이밍을 변경 * docs: 기능 구현이 완료되었으므로 기능 목록을 제거한다. * refactor: 도메인의 점진적 리팩토링이 완료됨에 따라 UiModel과 Mapper 또한 사용되지 않는 것들을 삭제하고 임시 네이밍을 변경했습니다. * refactor: 점진적 리팩토링이 완료됨에 따라 사용되지 않는 dto들을 삭제하고 패키지 구조를 변경 * refactor: dto와 도메인이 변경됨에 따라 Mapper가 변경됨 * refactor: 서비스 인터페이스와 서비스 풀에서 더 이상 사용하지 않는 파일 삭제 및 dto 변경으로 인한 변경 * refactor: 점진적 리팩토링이 완료됨에 따라 사용하지 않는 레포지토리 구현체 삭제 * rename: repository 네이밍 변경으로 인한 수정 * refactor: 도메인 변경으로 인한 스플래시 변경 및 기능 개선 * rename: 도메인 변경으로 인한 변경 * rename: adventureRepository와 그 구현체 네이밍 변경으로 인한 수정 * feat: 통계 조회 기능 구현 (#159) * feat: Statistic 반환dto 생성 * feat: Statistic 도메인 생성 및 계산로직 구현 * feat: 나의 통계 조회 기능 구현 완료 * fix: 시간계산 오류 수정 * test: @Sql조건 수정 * refactor: 총 플레이 시간과 게임 시간 값 수정 * fix: 인터셉터 패턴 추가 (#161) * feat: 게임 시작 화면 기능 구현 (#162) * design: BeginAdventureActivity에 필요한 string resource 추가 * refactor: 이동할 뷰에게 getIntent 함수를 이용해 intent 생성 * fix: Splash 화면에서 바로 인게임 화면으로 넘어가는 오류 수정 * feat: 메뉴를 누르면 해당 화면으로 이동하도록 구현 * refactor: 게임 결과 화면이 자신의 Intent를 생성하도록 수정 * refactor: ktlint 적용 * feat: 게임 생성 로직 수정 (#166) * fix: 잘못된 인덱스 로직 수정 * feat: Location 헤더로부터 id를 추출하는 기능 구현 * refactor: 매직넘버를 상수로 대체 * feat: 3차 데모데이 API 명세에 맞추어 응답 DTO 필드 추가 * test: 게임 생성 API 테스트 작성 * chore: 서브 모듈 설정 추가 * feat: firebase crashlytic 초기 환경 설정 (#170) * feat: FirebaseAnalytics 생성 및 로그 삽입을 담당할 객체 생성 및 상수 모음 파일 생성 (#171) * fix: application 파일 복구 (#174) * chore: 더미 데이터 추가 (#176) * feat: API 수정으로 인한 변경사항 적용 (#177) * feat: 명세서 변경으로 인해 dto 변경 * feat: 도메인 객체의 타입 변경 * feat: 받아올 값의 타입과 보여줄 뷰의 형태 변화를 반영한 코드 수정 * design: 제약 변경, 보여줄 데이터의 단위 추가 * feat: 목데이터를 실제 값으로 변경 * feat: 인텐트 값을 받아오는 것의 예외 상황에 대한 처리 * refactor: RankReponse 수정 (#179) * refactor: 변수명 수정 * refactor: 변수명 수정 * feat: baseUrl 변경 및 감추기와 그에 따른 yml 파일 변경 (#182) * feat: baseUrl이 노출되지 않도록 하며 github secret으로부터 가져올 수 있도록 yml 파일 수정 * feat: local.properties로부터 baseUrl을 가져올 수 있도록 변경 * feat: baseUrl을 BuildConfig로부터 가져올 수 있도록 변경 * ci 파일 1차 수정 * ci 파일 2차 수정 * ci 파일 3차 수정 * ci 파일 4차 수정 * refactor: 쿼리와 uri 수정 (#184) * refactor: 변수명 수정 * refactor: 변수명 수정 * refactor: 변수명 수정 * fix: uri 쿼리파라미터 오류 수정 * feat: 업로드 뷰 기능 구현 (#181) * feat: 제목, 설명을 입력받는 기능 구현 * feat: 촬영한 사진의 uri를 뷰모델에 저장 * feat: 모든 정보가 입력되지 않은 경우 전송하지 못하도록 하는 기능 구현 * refactor: 함수명 수정 * feat: 좌표 확장함수 생성 및 전송 기능 수정 - 필요한 정보가 하나라도 입력되지 않은 경우 정보를 입력해달라는 토스트 메시지 출력 - ViewModel에 좌표를 전달하고, 뷰에 좌표를 출력하기 위해 원하는 형태의 text로 변환하는 확장함수 생성 * feat: post 시 필요한 데이터를 파트로 분리 * feat: ViewModel 생성에 필용한 팩토리 추가 * feat: place 등록 기능 구현 * feat: viewModel 생성방법 변경 및 등록 버튼 리스너 연결 * fix: GET /games 쿼리 스트링 없어도 되도록 수정 (#187) * fix: 게임 전체 조회 기능 수정 * fix: 게임 전체 조회 기능 재수정 * fix: 랭크 전체조회 쿼리 파라미터 조건 수정 (#191) * fix: 장소데이터 추가 및 인터셉터 설정 변경 * refactor: 컨트롤러 요청 수정 (#193) * fix: POST /games/{gameId}/hints 쿼리 스트링 없어도 되도록 수정 (#195) * fix: 힌트 생성 api * fix: 힌트 생성 api 재수정 * feat: 게임 종료 시, 플레이어 점수 덧셈 기능 추가 (#198) * feat: 게임 종료 시, 플레이어 점수 덧셈 기능 추가 * refactor: 게임 결과 거리 조회 수정 * feat: Firebase Analytics 버튼 클릭 로그 추가 (#183) * feat: view id를 가져오기 위한 확장함수 추가 * feat: BeginAdventureActivity firebase용 버튼 로그 추가 * feat: LocationPermissionDialog firebase용 버튼 로그 추가 * refactor: 함수명 및 함수위치 통일 * feat: AdventureResultActivity firebase용 버튼 로그 추가 * feat: MyPageActivity firebase용 버튼 로그 추가 * feat: OnAdventureActivity firebase용 버튼 로그 추가 * refactor: 함수명 통일 * feat: UploadActivity firebase용 버튼 로그 추가 * feat: CameraPermissionDialog firebase용 버튼 로그 추가 * feat: xml에 있는 onClick 함수 삭제 및 firebase 버튼 로그 추가 * [BE] chore: spring profile에 대한 yml 파일 수정 * chore: yml 파일 수정 * chore: submodule 수정 * fix: @Value 어노테이션 삭제 * fix: 서버 통신 수정 (#196) * feat: NaagaThrowable을 수정하면서 data layer에서 400 / 500 / onFailure 세가지만 판단 * feat: 변경된 명세에 따라 AdventureStatusDto 변경 * feat: OnAdventureActivity에서 에러 로그를 볼 수 있도록 추가 * feat: OnAdventureActivity에서 도착 실패시 다시 시도하라는 토스트 발생 * feat: 다른 라이브 데이터를 받아서 한번만 호출할 수 있도록 효율적으로 변경 - 기존에는 DiposableLiveData를 만들고 이 데이터에 setValue까지 직접 해줘야했는데 이제는 다른 라이브데이터를 받아서 DisposableLiveData까지 setValue해주지 않아도 된다. * feat: 기존 게임을 불러올 경우 기존의 힌트를 찍어주는 로직 작성 * rename: 매개변수명 변경 --------- Co-authored-by: hyunji <83613106+hyunji1203@users.noreply.github.com> * refactor: dev 서버 환경 구축 (#236) * chore: submodule url 프로토콜 수정 * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * chore: update submodule * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * chore: update submodule * chore: update submodule * chore: MySql 의존성 추가 * chore: update submodule * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * chore: update submodule --------- Co-authored-by: kokodakadokok <45879491+kokodak@users.noreply.github.com> Co-authored-by: kokodak * fix: 깃허브 액션 워크플로우 수정 (#239) * feat: 소셜 로그인 기능 구현 (#235) * design: LoginActivty에 필요한 drawable source 추가 * design: LoginActivty에 필요한 string source 추가 * feat: 소셜 로그인을 위한 gradle 추가 * feat: 난독화 시 카카오 SDK가 포함되지 않도록 규칙 설정 * feat: 카카오 로그인 API key 숨김 처리 * feat: 인터넷 사용 권한 허용 * feat: 카카오 로그인 기능을 위한 Redirect URI 설정 추가 * feat: Kakao SDK를 초기화하는 application 구현 * feat: Kakao 로그인 기능 Util 구현 * design: LoginActivity 뷰 구현 * feat: 게임 상태가 진행 중이 아닐 때 Splash 화면에서 로그인 화면으로 이동하도록 구현 * feat: 상태바 색상 변경 * feat: 로그인 기능 구현 * feat: 사용자의 카카오 계정 닉네임을 마이페이지에 보여주는 기능 구현 * feat: 서버와 통신해 토큰을 얻어올 때 필요한 Dto, Domain 객체 생성 * feat: Dto, Domain 변환 mapper 추가 * feat: 서버와 통신하여 로그인 인증을 해주는 retrofit service 구현 * feat: 로그인 인증을 통해 토큰을 가져와주는 레포지토리 구현 * feat: 서버에게 받은 토큰을 저장하는 SharedPreference 구현 * feat: 서버에게 토큰을 받아와 로컬 저장소에 저장하는 기능 구현 * feat: 카카오 API KEY 감추기에 따른 yml 파일 수정 * fix: yml 파일 오류 수정 * fix: yml 파일 오류 수정 * fix: yml 파일 오류 수정 * fix: yml 파일 오류 수정 * refactor: ktlint 적용 * refactor: yml 파일 코드 정리 * refactor: 암호화 처리 되는 EncryptedSharedPreferences로 변경 * feat: retrofit Header에 서버에서 받아온 토큰 넣어주기 구현 * refactor: 카카오 토큰을 함수 인자로 받아오도록 수정 * rename: preference가 사용된 파일명을 datasource로 변경 * refactor: 함수 인자명 변경 * chore: 오류 코드 정리 및 예외 핸들러 보완 * chore: 오류 코드 문서와 통일 * refactor: 에러코드 문서화에 맞춘 코드 수정 * refactor: 요청 바디에 대한 입력 오류 예외 핸들러 추가 * fix: 원격 저장소와의 코드 변경 수정 * Update backend_dev_merge_workflow.yml * hotfix: workflow 긴급 수정 * hotfix: yml 파일 삭제 * fix: 게임 종료 실패 시, 남은 도전 횟수 줄지 않는 문제 해결 * chore: 서브모듈 추가 * 게임 종료 특정 예외 롤백 예외 적용 * fix: 도착 실패시, 시도 횟수 롤백 문제 수정 * test: 테스트 추가 * chore: workflow 수정 * chore: workflow 수정 --------- Co-authored-by: zillionme * feat: 자동 로그인 및 로그인 로직 수정 (#241) * feat: AuthInterceptor 만드는 중 * feat: 닉네임은 서버에서 내려주는 정보이므로 직접 가져올 필요가 없다. 로직 삭제 * rename: 카카오라는 플랫폼에 종속적이지 않은 인증정보 저장소이므로 네이밍 변경 * chore: NaagaApplication은 특정 뷰에 종속된 것이 아닌 어플리케이션 전체를 관장하는 객체이므로 패키지 변경 * feat: Application의 서브클래스 수정 및 해당 위치에서 AuthDataSource 생성 * rename: Preference 네이밍 변경 * feat: 도메인에서 엑세스 토큰과 리프레시 토큰에 대한 내용은 필요가 없다고 생각되어 삭제 * feat: preference에 refresh 로직 추가 * feat: AuthRepository 수정, 데이터 레이어에서 토큰을 저장할 수 있도록 변경 * feat: 주석 추가 및 고차함수를 통해 콜백에서 발급되는 토큰을 받아감 * rename: AuthService의 함수명 변경 * refactor: object에서 class로 변경 * refactor: DefaultAuthRepository에서 dataSource를 외부에서 주입받도록 변경 * refactor: 토큰 가져오는 방식이 변경됨 * feat: 카카오 로그인 방식에 문제가 있어 변경함 * feat: AuthInterceptor 완성 * feat: 예외처리 (#243) * feat: 데이터 레이어에서 사용할 Custom Throwable 클래스 생성 * feat: 통신 오류시 DataThrowable을 사용하는 코드 스니펫 작성 * feat: RankRepository의 서버 통신을 DataThrowable을 사용하는 통신으로 변경 * feat: 예상하는 예외 발생 시 토스트메시지로 보여주는 기능 구현 * refactor: sort, order를 도메인 Enum 클래스를 사용하도록 변경 * feat: PlaceRepository의 서버 통신을 DataThrowable을 사용하는 통신으로 변경 * feat: StatisticsRepository의 서버 통신을 DataThrowable을 사용하는 통신으로 변경 * feat: upload 기능 서버 통신 연결 해제 * refactor: 점진적 리팩토링 종료 및 불필요한 코드 삭제 * feat: http 응답코드 500번대, body가 null일 때 반환할 에러 추가 * feat: 통신 오류시 DataThrowable을 사용하는 코드 스니펫에 예외 핸들링 추가 * fix: 잘못된 파라미터 수정 * feat: 클라이언트에서 사용하는 hintThrowable 추가 * feat: AdventureRepository의 서버 통신을 DataThrowable을 사용하는 통신으로 변경 * feat: 장소등록 페이지로 이동하지 못하도록 구현 * style: 불필요한 개행 삭제 * refactor: 뷰모델 코드 통일 및 핸들링할 예외 수정 * refactor: 예외 발생 시 보여주는 방법 변경 * refactor: ViewModelProvider의 factory를 ViewModel의 동반객체로 이동 * refactor: 사용하지 않는 예외 클래스 삭제 * refactor: 인증관련 에러 삭제 * refactor: 에러 코드 변경 * feat: 소셜 로그인 기능과 인터셉터 인가 처리 및 아규먼트 리졸버 기능 추가 * feat: OAuth 연습 * feat: OAuth 연습2 * chore: 연습 코드 삭제 * feat: JWT 생성 로직 * feat: AccessToken과 RefreshToken 담고있는 AuthTokens 생성 * feat: 카카오 토큰으로 카카오로부터 유저 정보 받아오는 요청 로직 추가 * feat: 인증 정보 조회에 대한 서비스 로직 추가 * feat: 로그인 관련 요청 추가 * feat: JWT에서 멤버 ID 추출하는 기능 추가 * feat: 인터셉터에서 Authorization 헤더에서 토큰 추출해서 memberId 조회하는 기능 추가 * feat: 멤버 회원가입 시, 플레이어 함께 생성하도록 추가 chore: 네이밍 변경 Co-authored-by: chaewon121 * refactor: Member에 Password 삭제 test: Basic 헤더에서 Bearer + 토큰으로 변경 Co-authored-by: chaewon121 * chore: 패키지 구조 변경 Co-authored-by: chaewon121 * test: AuthInterceptor 테스트 추가 Co-authored-by: chaewon121 * test: AuthArgumentResolver 테스트 추가 Co-authored-by: chaewon121 * test: AuthController 테스트 추가 Co-authored-by: chaewon121 * test: AuthService 테스트 추가 Co-authored-by: chaewon121 * chore: 필요없는 프로필 삭제 Co-authored-by: chaewon121 * feat: 서브모듈 추가 Co-authored-by: chaewon121 * feat: 예외 처리 추가 Co-authored-by: chaewon121 * remove: 테스트 프로필 삭제 Co-authored-by: chaewon121 * chore: 스타일 수정 * test: pull 후 테스트 통과되도록 수정 Co-authored-by: chaewon121 * feat: 난독화를 위해 모든 Dto 필드에 SerialName을 추가 (#245) * fix: AuthInfo에 기본 생성자 추가 * fix: 서브모듈 업데이트 * feat: 앱 아이콘 설정 (#253) * fix: 메인으로 돌아갈 시 해당 액티비티가 사라지도록 수정 (#255) * feat: 사용자가 GPS 기능을 껐을 때 이를 인지하고 키도록 유도하는 기능 구현 (#258) * feat: 장치 구성 변경 대응 (#250) * feat: 화면을 세로모드로 고정 * feat: 다크모드를 사용해도 다크테마가 나오지 않도록 변경 * feat: 난독화 방지를 위한 ProGuard 수정 (#259) * refactor: 좌표 간 거리를 M 단위로 변경 및 힌트/시도횟수 변경 * refactor: 좌표간 거리를 m 단위로 변경 * refactor: 힌트 최대 사용 개수와 최대 시도 횟수 변경 * fix: 서브모듈 최신화 * feat: Firebase Analytics 서버 통신 에러 로그 추가 (#260) * refactor: 게임 종료 타입에 따른 점수 계산 기능 수정 * refactor: 메서드 명 변경 * refactor: 게임 시작 위치와 목적지의 직선 거리 구하는 기능 추가 * refactor: 게임 종료 타입에 따른 점수 계산 기능 수정 * refactor: 게임 결과에 따른 점수 계산 기능 수정 * refactor: gameScore 관련 패키지 네이밍 변경 * refactor: enum을 클래스의 상수로 빼놓은 것 수정 * refactor: gamescore 도메인에 스프링 의존성 제거 * refactor: 스코어 정책 못 찾을 때 예외 발생하도록 변경 feat: InternalException과 Exception에 대한 핸들러 추가 * chore: 스타일 수정 --------- Co-authored-by: dooboocookie * feat: 로깅 기능 추가 (#268) * feat: 이어하기 기능 추가 (#263) * feat: 이어하기 기능 구현 * feat: 뒤로가기 버튼을 2초내에 두 번 눌려야 종료되도록 기능 구현 * feat: splash를 거치면 login 액티비티로 이동하도록 수정 * feat: splash에서 adventure를 받아온 경우 BeginAdventureActivity까지 전달 - 이를 통해 이어하기가 가능하도록 기능 구현 * feat: 진행중인 게임이 있는 경우 이어하기가 표시되도록 변경 * feat: 게임결과 화면에서 뒤로가기 버튼 클릭 시 BeginAdventureActivity로 이동하도록 구현 * refactor: 버전에 따른 분기처리 함수에 Compat suffix 추가 * refactor: 문자열 strings.xml로 이동 * refactor: 사진 저장 경로 수정 (#269) * refactor: 이미지 저장하는 경로와 URL 경로 수정 * chore: 서브모듈 업데이트 * chore: 프로덕트 서버 배포 * chore: prod 서버 배포 * chore: prod 서버 배포 * fix: OnAdventureActivity 수정 (#265) * chore: lottie 의존성 추가 * design: 로티 애니메이션과 뷰 추가 * feat: 로딩 기능 추가 * feat: 뷰모델 불필요한 로직 정리 * feat: 중복 값에는 갱신되지 않는 라이브데이터 생성 * feat: 로티를 지도 위로 띄우기 위해 elevation을 적용 * feat: 로티 배경 흐린 색으로 수정 * design: string 리소스 추가 * feat: 힌트 잔여횟수 표시하도록 변경, 정답 도전 잔여 시도 횟수 표기, 토스트에서 스낵바를 띄우도록 변경, 목적지가 없을 시 종료 * design: 불필요한 + 버튼 삭제 * design: margin값 변경 * feat: snackbar를 toast로 변경 * feat: 로그인 시 사용자의 토큰이 로그에 보여지지 않도록 수정 (#271) * feat: 스플래시에서 받아온 게임을 넘겨주는 기능 삭제 (#274) * refactor: 로그 경로 변경 * chore: 서브모듈 수정 * fix: 잘못된 로직 수정 (#276) * feat: 스플래시에서 받아온 게임을 넘겨주는 기능 삭제 * fix: 잘못된 로직 수정 * feat: 시작 액티비티 변경 * feat: BeginAdventureActivity에서 진행중인 게임이 있는지 판단하는 기능 구현 (#277) * design: 로딩을 위한 스켈레톤 UI 생성 * feat: 진행중인 상태의 게임을 받아오고 로딩하는 과정을 추가 * feat: 작업중 * rename: 로티 파일 이름 변경 * design: 스켈레톤 뷰 지우고 로티 뷰 추가 * feat: 로티 로딩뷰로 수정 * style: 로그 삭제 * feat: 뷰 진행 플로우 변경 * refactor: 직접 만든 로직을 이미 존재하는 코틀린 api로 대체 * fix: 에러 수정 * fix: 사진 저장 시 1번 회원으로만 저장되는 오류 수정 * fix: 사진 저장 시 1번 회원으로만 저장되는 오류 수정 * chore: 서브모듈 업데이트 * chore: 서브모듈 업데이트 * chore: 추천 범위 500km로 수정 * test: 테스트 fixture 및 builder 추가 및 적용 * fix: 잘못된 거리 계산 수정 * feat: 테스트 Builder 패턴 적용 및 Fixture 생성 remove: 기존의 Fixture 파일 삭제 * test: 테스트 Builder 적용 및 기존의 cascade 옵션 삭제 * fix: application.yml 수정 * chore: 리커시브 컴페리전 이그노어 필드 추가 --------- Co-authored-by: dooboocookie * feat: Refresh Token 구현 및 자동 로그인 API, 회원 탈퇴 API, 로그아웃 API 구현 * test: 액세스 토큰 재발급 e2e 테스트 작성 * fix: 로그 환경셜정 변경 * feat: 액세스 토큰 재발급 기능 추가 * refactor: 액세스 토큰 재발급 기능 리팩터링 * refactor: 최초 액세스 토큰 발급 시 AuthToken 영속화 * chore: 임시 커밋 * test: 일부 테스트 수정 및 삭제 * feat: 아규먼트 리졸버 변경 및 추가 * feat: 소셜 로그인 연결 끊기 기능 추가 * fix: 아규먼트 리졸버 스프링 빈 등록 * refactor: 기본 설정파일 수정 * chore: 서브모듈 업데이트 * refactor: 멤버, 플레이어 삭제 필드 추가 * feat: 멤버, 플레이어 삭제 기능 추가 * feat: 토큰 삭제 기능 추가 * feat: AuthToken에 멤버 필드 추가 * feat: 로그아웃 API 추가 * chore: 패키지 구조 변경 * test: 회원탈퇴 로그아웃 E2E 테스트 추가 * chore: 서브모듈 업데이트 * refactor: 소프트 딜리트 @SqlDelete로 수정 refactor: cascade 옵션 PERSIST로 수정 test: 회원탈퇴 로그아웃 서비스, 컨트롤러 테스트스 작성 * chore: 충돌 해결 * chore: 서브모듈 업데이트 * chore: 충돌 해결 --------- Co-authored-by: zillionme * test: 작성되지 않은 테스트 코드 추가 * fix: 잘못된 거리 계산 수정 * feat: 테스트 Builder 패턴 적용 및 Fixture 생성 remove: 기존의 Fixture 파일 삭제 * test: 테스트 Builder 적용 및 기존의 cascade 옵션 삭제 * test: 없는 예외 테스트 추가 * test: StatisticTest 와 gameServiceTest 추가 * Update backend_dev_pr_workflow.yml * fix: Thread.sleep 추가 * Update GameControllerTest.java * Update GameControllerTest.java * Update backend_dev_pr_workflow.yml * Update backend_dev_pr_workflow.yml * Update backend_dev_pr_workflow.yml * Update GameControllerTest.java * Update backend_dev_pr_workflow.yml * Update backend_dev_pr_workflow.yml * test: 테스트 fixture 및 builder 추가 및 적용 * fix: 잘못된 거리 계산 수정 * feat: 테스트 Builder 패턴 적용 및 Fixture 생성 remove: 기존의 Fixture 파일 삭제 * test: 테스트 Builder 적용 및 기존의 cascade 옵션 삭제 * fix: application.yml 수정 * chore: 리커시브 컴페리전 이그노어 필드 추가 --------- Co-authored-by: dooboocookie * feat: Refresh Token 구현 및 자동 로그인 API, 회원 탈퇴 API, 로그아웃 API 구현 * test: 액세스 토큰 재발급 e2e 테스트 작성 * fix: 로그 환경셜정 변경 * feat: 액세스 토큰 재발급 기능 추가 * refactor: 액세스 토큰 재발급 기능 리팩터링 * refactor: 최초 액세스 토큰 발급 시 AuthToken 영속화 * chore: 임시 커밋 * test: 일부 테스트 수정 및 삭제 * feat: 아규먼트 리졸버 변경 및 추가 * feat: 소셜 로그인 연결 끊기 기능 추가 * fix: 아규먼트 리졸버 스프링 빈 등록 * refactor: 기본 설정파일 수정 * chore: 서브모듈 업데이트 * refactor: 멤버, 플레이어 삭제 필드 추가 * feat: 멤버, 플레이어 삭제 기능 추가 * feat: 토큰 삭제 기능 추가 * feat: AuthToken에 멤버 필드 추가 * feat: 로그아웃 API 추가 * chore: 패키지 구조 변경 * test: 회원탈퇴 로그아웃 E2E 테스트 추가 * chore: 서브모듈 업데이트 * refactor: 소프트 딜리트 @SqlDelete로 수정 refactor: cascade 옵션 PERSIST로 수정 test: 회원탈퇴 로그아웃 서비스, 컨트롤러 테스트스 작성 * chore: 충돌 해결 * chore: 서브모듈 업데이트 * chore: 충돌 해결 --------- Co-authored-by: zillionme * chore: 충돌 해결 --------- Co-authored-by: kokodak Co-authored-by: kokodakadokok <45879491+kokodak@users.noreply.github.com> Co-authored-by: dooboocookie Co-authored-by: dooboocookie <79090478+dooboocookie@users.noreply.github.com> Co-authored-by: zillionme * feat: 버전 변경 (#290) * feat: 로깅하기 (#291) * 임시저장 * 임시저장 * feat: 환경 설정별 로깅 추가 * refactor: 로그 파일 및 warn, error 로그 메시지 수정 * refactor: db 로그 출력 분리 * refactor: db 로그 레벨 수정 * chore: 서브모듈 업데이트 * chore: 워크 플로우 수정 * feat: 장소 업로드 기능 구현 (#301) * refactor: Part를 PartMap으로 변경 * feat: 업로드 화면으로 이동하는 기능 구현 * feat: 정보를 서버로 전송하는 기능 구현 - 필요한 정보를 RequestBody 형태로 만들고 Map에 저장하여 전송하는 방식 * feat: 정보를 성공, 실패했을 때의 로직 구현 * feat: 원하는 예외만 핸들링 하도록 구현 * feat: 잡은 예외에 토스트로 알맞는 문구를 띄워주는 기능 구현 * fix: 자료형 변경 * refactor: 문자열 string.xml 로 추출 * refactor: toRequestBody 변수 삭제 * refactor: key값 companion object에 저장 * fix: 위치관련 버그 수정 (#302) * feat: 업로드 화면으로 들어간 시점에 위치를 받아오는 기능 구현 * feat: 업로드 화면으로 이동하는 기능 구현 * feat: 위치 로딩을 기다리도록 하기 위한 로딩 로티 추가 * feat: 위치를 받아오고 저장할 때까지 로딩로티를 보여주는 기능 구현 * refactor: branch 변경 (#311) * refactor: 네트워크 작업 코루틴으로 변경 (#312) * refactor: Service함수 suspend로 변경 * feat: 값을 반환하거나 예외를 던지는 Response 확장함수 구현 * refactor: 반환 값 Response, suspend 적용 * refactor: 코루틴 적용 * refactor: ViewModel이 Application을 참조하지 않도록 변경 (#307) * Delete .idea directory * chore: 전체 gitignore 지정 (#320) * refactor: Login 뷰에서 진행하는 네트워크 작업 코루틴으로 변경 (#328) * feat: service와 repository에 suspend 추가 * refactor: repository 내 코루틴 사용 * refactor: repository 생성 시 Dispatcher 전해주도록 수정 * refactor: 코루틴 사용 * refactor: 불필요한 인자 제거 * refactor: 불필요한 로그 제거 * refactor: 불필요한 import 제거 * refactor: my page뷰에서 진행하는 네트워크 작업 코루틴으로 변경 (#323) * refactor: suspend 함수로 수정 및 반환 값을 Response로 수정 * refactor: DefaultStatisticsRepository의 네트워크 작업을 Response의 확장함수로 선언한 getValueOrThrow를 사용하도록 변경 * refactor: DefaultStatisticsRepository에서 하는 네트워크 작업을 코루틴을 사용하도록 변경 * refactor: suspend 함수로 수정 및 반환 값을 Response로 수정 * refactor: PlaceRepository에서 하는 네트워크 작업을 Response의 확장함수로 선언한 getValueOrThrow를 사용하도록 변경 * refactor: PlaceRepository에서 하는 네트워크 작업을 코루틴을 사용하도록 변경 * refactor: PlaceRepository 변경사항 적용 * style: ktlint 적용 * style: ktlint 적용 * feat: Setting 뷰 구현 (#331) * design: Setting 페이지 이동 버튼 생성 * feat: Setting 뷰 구현 * feat: 설정으로 이동하는 기능 구현 * feat: 뒤로가기 기능 추가 * feat: manifest에 activity 추가 * fix: History 뷰의 리사이클러뷰 image 오류 문제 해결 (#317) * fix: History 뷰dml 리사이클러뷰 image 오류 문제 해결 * design: 뒤로가기 버튼 위치 변경 * refactor: Adventure 도메인에 해당하는 네트워크 작업 코루틴으로 변경 (#315) * refactor: AdventureService의 함수들에 suspend 키워드 추가 * refactor: AdventureRepository의 함수들을 callback 구조에서 coroutine을 통한 반환값을 뱉는 형태로 변경 * refactor: AdventureRepository 변경에 따른ViewModel 변경 * refactor: 에러 상수화 (리뷰 반영) * feat: 장소 업로드 시 로딩 창이 뜨는 기능 구현 (#308) * feat: SingleLiveData 추가 * feat: 업로드 상태를 3가지로 관리하는 enum 클래스 생성 * feat: 전송이 완료될 때까지 로딩 로티가 보이는 기능 구현 * refactor: 전송 이벤트의 변경을 ViewModel에서만 관리하도록 변경 * refactor: 업로드 상태를 뷰모델에서 관리하도록 변경 * refactor: 뷰의 visibility 관리를 함수로 추출 * fix: 마이페이지 글자 깨지는 오류 수정 (#333) * chore: 전체 gitignore 지정 * fix: 마이페이지 글자 크기 계산 로직 오류 수정 * feat: AdventureHistoryViewModel 테스트 추가 (#340) * feat: ViewModelTest를 위한 Dependency 추가 * feat: LiveData 테스트를 위한 Class 추가 * test: 내 게임 결과 목록이 잘 불러와지는 지 확인 하는 뷰모델 테스트 추가 * style: ktlint 체크 * refactor: fake 객체 위치 변경 * feat: 회원 탈퇴 기능 구현 (#335) * feat: 서버와 회원 탈퇴 통신을 해주는 service 추가 * feat: 카카오 sdk의 unlink 메서드 추가 * feat: 회원 탈퇴 기능 추기 * feat: 회원탈퇴 버튼 클릭 시 회원 탈퇴가 되도록 하는 기능 구현 * feat: Service의 API 주소 수정 * refactor: Service의 반환 값 수정 * feat: 로그 수정 * refactor: ktlint 수정 * refactor: 메서드 반환 값이 non-nullable 하도록 수정 * refactor: 변수명 변경 * refactor: 에러 코드 상수화 * refactor: 회원 탈퇴 repository 메서드 내 runCatching 삭제 * feat: 회원 탈퇴 후 로그인 창으로 이동 시 백 스택에 쌓인 뷰를 리셋해주는 기능 구현 * feat: 회원 탈퇴 다이얼로그 생성 * feat: RankViewModel 테스트 추가 (#337) * feat: ViewModelTest를 위한 Dependency 추가 * feat: LiveData 테스트를 위한 Class 추가 * feat: 내 랭킹을 조회해오는 메서드 테스트 추가 * feat: 전체 랭킹을 조회 해오는 메서드 테스트 추가 * feat: 로그아웃 기능 구현 (#341) * feat: 로그아웃 요청 및 처리 로직 추가 * feat: DELETE 요청인 경우 body가 null이어도 에러를 반환하지 않도록 구현 * feat: 로그아웃 기능 버튼에 연결 * style: 로그아웃 성공시 출력할 문구 추가 * feat: 로그인 상태, 에러를 관리하는 라이브데이터 추가 * feat: 뷰모델 데이터 구독 및 적절한 처리 로직 구현 * chore: 사용하지 않는 파일 삭제 - Call의 확장함수 삭제 * feat: EncryptedSharedPreferences에 저장된 Access, Refresh 토큰 삭제 * feat: 로그아웃 클릭 시 다이얼로그창이 뜨는 기능 구현 * feat: 로그아웃 성공 후 뒤로가기 클릭 시 이전 액티비티가 나오지 않도록 기능 구현 * refactor: 문구 수정 * refactor: 코드 통일 * refactor: return 삭제 * refactor: GameService.endGame() 리팩토링 (#304) * refactor: game 도메인 패키지와 gaemResult 도메인 패키지 분리 * refactor: Game.endGame() 메서드 Game이 갖는 상태에 대해서만 처리하도록 변경 - ResultType, 즉 성공 실패 여부는 Game이 알 요소가 아니므로 메서드 내에서 계산하는 부분 삭제 * refactor: Game.endGame() 메서드 Game이 갖는 상태에 대해서만 처리하도록 변경 - ResultType, 즉 성공 실패 여부는 Game이 알 요소가 아니므로 메서드 내에서 계산하는 부분 삭제 * refactor: GameFinishService 게임 결과 생성하는 서비스 인터페이스 추가 및 GameResultService로 결과 생성하는 로직 구현 * refactor: PlayerService에 점수 더하는 로직 추가 * refactor: 서비스 메서드에 대한 NoRollbackFor 제거 후 새로운 트랜잭션 열어서 횟수 차감하는 서비스 로직 추가 * fix: NoRollbackFor 원복 * refactor: endGame() 메서드의 동작 분리 * chore: GameResultService 패키지 변경 * refactor: GameManageService 도메인 서비스 생성 * refactor: GameManageService 도메인 서비스 삭제하고 메서드 도메인으로 넣음 * refactor: Game 시도횟수 줄일 때 검증 추가 * test: GameTest endGame 관련 테스트 추가 * test: GameResultService 테스트 추가 * test: PlayerService 점수 추가 로직 테스트 추가 * test: GameServiceTest 게임 종료 로직 테스트 추가 * chore: 워크플로우 수정 * chore: 워크플로우 수정 * chore: 테스트 통과하도록 수정 * chore: game과 gameresult 패키지의 persistence 패키지를 repository로 변경 * chore: setDone() 메서드 네이밍 변경 * chore: 컨벤션으로 메서드 호출 순서대로 메서드 명시 * refactor: 종료되지 않은 게임에 대한 에러를 GameException으로 변경 * refactor: endGame 메서드 진행중 게임 검증을 제일 처음에 진행하도록 변경 * refactor: findPlayerById 재활용하도록 수정 * feat: AdventureResultViewModel 테스트 추가 (#338) * feat: ViewModelTest를 위한 Dependency 추가 * feat: LiveData 테스트를 위한 Class 추가 * test: 성공한 게임 결과가 잘 불러와지는 지 확인 하는 뷰모델 테스트 추가 * test: 실패한 게임 결과가 잘 불러와지는 지 확인 하는 뷰모델 테스트 추가 * test: 내 랭킹 결과가 잘 불러와지는 지 확인 하는 뷰모델 테스트 추가 * style: ktlint 체크 * style: ktlint 체크 * style: ktlint 체크 * refactor: 리포지터리에 의존성 주입 라이브러리 적용 (#349) * feat: Hilt 의존성 추가 * feat: by viewModels 를 사용하기 위해 의존성 추가 * refactor: Hilt를 사용하여 의존성 주입 자동화 * refactor: 불필요한 로깅 삭제 * refactor: datasource 의존성 주입 라이브러리 사용 (#352) * refactor: retrofit 의존성 주입 라이브러리 적용 (#353) * feat: DataSource Module 추가 * feat: Service Module 추가 * refactor: Repository에 의존성 주입을 자동화하기 위해 수정 * refactor: Repository에 Service 주입 자동화 * refactor: lint check * feat: 자동로그인 기능 구현 및 스플래시 분리 (#346) * chore: 전체 gitignore 지정 * feat: AuthInterceptor에서 소셜 로그인은 제외하는 로직 추가, Bearer prefix를 빼먹어서 붙임 * feat: bearer를 붙인 토큰을 반환하도록 변경 * feat: 서버 통신에 필요한 dto 생성 및 refresh api 요청 함수 작성 * feat: 토큰 refresh 요청을 위한 레포지토리 로직 작성 * design: splash가 분리되면서 splash layout design 변경 * feat: 스플래시에서 토큰을 리프레시하고 다음 화면을 정하는 분기처리 로직 추가 * feat: 스플래시 액티비티를 따로 분리함 * feat: AuthRepository에 refresh 기능 선언 추가 * fix: 마이페이지 글자 크기 계산 로직 오류 수정 * style: 로그 삭제 * feat: response의 바디를 한번 확인하면 다시 사용할 수 없는 (closed 이슈)를 해결 * feat: 스플래시 로직을 수정하여 토큰 여부에 따라 화면을 분기 * feat: 로그인 액티비티 시작하는 intent flag 수정 * feat: Interceptor 로직 수정 * feat: 토큰 확인용 api 변경 및 에러로깅 추가 * feat: 사용하지 않는 변수 삭제 * feat: UploadViewModel 테스트 추가 (#343) * feat: ViewModelTest를 위한 Dependency 추가 * feat: LiveData 테스트를 위한 Class 추가 * feat: Robolectric 추가 * test: UploadViewModel test 추가 * chore: 오타 삭제 * refactor: 양방향 데이터 바인딩을 통해 뷰모델에서 안드로이드 의존성 제거 * refactor: lint 적용 * refactor: 필요없는 코드 삭제 * refactor: 전송을 위한 데이터가 다 채워졌는지 검사를 뷰모델에서 진행하도록 변경 * test: 안드로이드 의존성 없이 테스트 진행 * test: 뷰모델 테스트 진행 * test: 테스트를 위한 의존성 추가 * test: 필요하지 않은 구문 삭제 * fix: 데브 브랜치 머지 워크 플로우 수정 * hotfix: PlayerRepository.findAll() 호출 시 N+1 문제 수정 (#360) * refactor: Player의 Member 필드 지연로딩으로 변경 * refactor: PlayerRepository.findAll() Fetch Join 진행 * test: 지연 로딩으로 인한 테스트 에러 임시 수정 * refactor: 디자인 수정을 위한 공통 요소 추가 (#378) * style: 메인 색상 추가 * style: 메인 글꼴 추가 - 던파 비트비트체 ver2 * style: 프로젝트 전체 색상 변경 * style: 아이콘 추가 * refactor: 폰트명 변경 * refactor: rect_main 삭제, 테마 배경색을 color로 지정 * feat: 장소 검수 기능 뼈대코드 설계 및 구현 (#373) * feat: 검수가 필요한 장소 엔티티 구현 * feat: 장소 검수 컨트롤러 구현 * feat: 장소 검수 Repository 구현 --------- Co-authored-by: kokodak * feat: 장소 좋아요 기능 도메인 설계 및 뼈대코드 작성 (#344) * feat: 좋아요/싫어요 뼈대코드 도메인 설계 * chore: 좋아요 도메인 패키지 이동 * feat: 장소 통계 도메인 생성 - 역정규화로 인한 통계 테이블 분리 * feat: 장소 좋아요 JpaRepository 생성 * test: PlaceLike 테스트 픽스쳐, 엔티티 빌더 생성 * feat: PlaceStatics JpaRepository 생성 * feat: PlaceStatics 생성자 추가 * test: PlaceStatistics 테스트 픽스처, 엔티티 빌더 생성 * chore: 불필요한 개행 삭제 --------- Co-authored-by: kokodak Co-authored-by: dooboocookie * fix: OkHttpClient의 interceptor를 AuthInterceptor로 변경 (#375) * feat: 장소 등록 검수 관리자 페이지 제작 및 인가 인터셉터 추가 (#374) * feat: 관리자 관련 인가처리하는 인터셉터 구현 * feat: HttpMethod 와 PathPattern에 따라서 인터셉터 연결 여부를 결정하는 인터셉터 추가 * feat: HttpMethod 와 PathPattern에 따라서 인터셉터 연결 여부를 결정하는 인터셉터 추가 * feat: HttpMethod를 가변인자로 받을 수 있고 안보내면 전체 HttpMethod를 다 매핑하도록 수정 * refactor: 기존 AuthInterceptor 매핑 PathMatcherInterceptor로 변경 * test: RequestPatternTest 추가 * test: PathMatcherInterceptorTest 추가 * feat: manager 페이지에 대해서 CORS 설정 * chore: 네이밍 변경 * refactor: Auth 헤더의 값이 id:password 들어오지 않을 때 검증 추가와 예외 정의 * refactor: Auth 헤더의 값이 id:password 들어오지 않을 때 검증 추가와 예외 정의 * refactor: stream 대신 asList로 리스트 변환하도록 변경 * refactor: PathMatcher를 관리하는 정적 클래스 생성 * test: Path는 맞고 Method는 틀린 경우 테스트 케이스 추가 * refactor: 메서드 호출 순서에 맞게 선언 순서 배치 * chore: stream 제거하고 새로 ArrayList 생성하도록 변경 * chore: Controller 목객체로 변경 * chore: trim()을 stip()으로 변경 * [BE] fix: 나의 통계 조회 시 성능 저하 문제 해결 (#364) * refactor: 게임 결과 조회 n+1 문제 수정 * feat: gameRepository 테스트코드 작성 * refactor: 쿼리문 가독성 있게 수정 * refactor: gameResult 의 game 객체 지연 로딩 추가 * fix: 테스트 오류 수정 * fix: 트렌젝셔널 추가 * refactor: 게임결과 조회시 목적지 조회도 함께 조회되도록 쿼리 수정 * fix: 게임 통계 조회 시 실패 게임도 거리 집계되는 문제 해결 (#382) * refactor: 게임 결과 조회 n+1 문제 수정 * feat: gameRepository 테스트코드 작성 * refactor: 쿼리문 가독성 있게 수정 * refactor: gameResult 의 game 객체 지연 로딩 추가 * fix: 테스트 오류 수정 * fix: 트렌젝셔널 추가 * fix: 실패한 게임 통계에 거리 잡히지 않도록 수정 * refactor: GameRecord 레코드로 변환 * test: 테스트 시, 거리에 대한 컬럼도 테스트 --------- Co-authored-by: chaewon121 Co-authored-by: chaewon121 <80631952+chaewon121@users.noreply.github.com> * fix: 모든 게임 결과 조회 시, 진행중 게임 있으면 예외 발생하는 사항 수정 (#383) * refactor: 게임 결과 조회 n+1 문제 수정 * feat: gameRepository 테스트코드 작성 * refactor: 쿼리문 가독성 있게 수정 * refactor: gameResult 의 game 객체 지연 로딩 추가 * fix: 테스트 오류 수정 * fix: 트렌젝셔널 추가 * fix: 게임을 통해 게임 결과를 가져오는 방식에서 게임결과들을 플레이어 아이디로 조회 * test: GameService의 게임 통계 테스트에 진행중 게임 데이터 추가하고 테스트 --------- Co-authored-by: chaewon121 Co-authored-by: chaewon121 <80631952+chaewon121@users.noreply.github.com> * Refactor/#391 모험 기록 뷰 디자인 변경 (#396) * design: color resource 추가 * design: 성공, 실패를 보여주는 라벨 추가 * design: 뷰 제목 변경을 위해 strings resource 변경 * design: drawable resource 이름변경으로 인한 코드 수정 * design: 폰트 변경 * design: color resource 이름 변경 * feat: 앱 강제 업데이트 기능 구현 (#400) * feat: firebase-config 의존성 추가 * feat: 확장함수 패키지 생성, 이동 및 추가 * feat: 확인 다이얼로그 추가 - 강제 업데이트를 위해 외부가 클릭되어도 다이얼로그가 꺼지지 않도록 구현 * feat: 강제 업데이트 기능 구현 * refactor: 함수명 변경 * refactor: text gravity 수정 * refactor: 다이얼로그 title 글씨 크기 수정 * refactor: 다이얼로그 패키지 이동 * refactor: 로그인 뷰 디자인 변경 (#399) * design: 빌딩과 별 drawable 추가 * design: strings resource 변경 * design: 로그인 디자인 변경 * refactor: 불필요한 상태바 설정 코드 삭제 * refactor: 업로드 뷰 디자인 변경 (#381) * refactor: 업로드 뷰 디자인 변경 * refactor: 사용하지 않는 변수 삭제 * refactor: AppCompatButton 사용해서 배경색 지정하도록 변경 * refactor: editText에 hint 추가 * refactor: ktlint * refactor: 버튼 배경 변경 * refactor: editText 밑줄 삭제 * refactor: editText marginTop 수정 * refactor: 이미지뷰 marginTop 수정 * fix: 버튼 id 수정 * refactor: 사용하지 않는 함수 삭제 * refactor: 설정 뷰 디자인 변경 (#397) * design: 폰트 적용 * design: strings resource 추가 * design: 빌딩과 별 drawable 추가 * design: 백그라운드에 빌딩과 별 이미지 추가 * refactor: strings resource 띄어쓰기 수정 * [BE] refactor: 로깅 구체화 하기 (#318) * feat: 로그 필터 구현 * fix: application prod를 local로 수정 * feat: logback gradle 의존성 추가 * feat: 기존 로깅 파일 삭제 * feat: logback xml 파일 설정 * feat: 로그 필터 구현 * feat: mdc 필터 구현 * feat: 필터 빈등록 * feat: exceptionHandler 수정 * feat: 깃허브 설정 * refactor: mdc 이넘 추가 * refactor: info 로그 출력 message추가 * refactor: 추가 메서드 삭제 * refactor: 사용하지 않는 상수 삭제 * chore: 쿼리 튜닝 및 성능 조회를 위한 변경사항 * chore: 쿼리 정보 로그 삭제 * feat: 로깅 추가 (#359) * feat: 로그 필터 구현 * fix: application prod를 local로 수정 * feat: logback gradle 의존성 추가 * feat: 기존 로깅 파일 삭제 * feat: logback xml 파일 설정 * feat: 로그 필터 구현 * feat: mdc 필터 구현 * feat: 필터 빈등록 * feat: exceptionHandler 수정 * feat: 깃허브 설정 * refactor: mdc 이넘 추가 * refactor: info 로그 출력 message추가 * refactor: 추가 메서드 삭제 * refactor: 사용하지 않는 상수 삭제 * chore: 쿼리 튜닝 및 성능 조회를 위한 변경사항 * chore: 쿼리 정보 로그 삭제 --------- Co-authored-by: chaewon121 * fix: 워크플로우 수정 * hotfix: PlayerRepository.findAll() 호출 시 N+1 문제 수정 (#360) * refactor: Player의 Member 필드 지연로딩으로 변경 * refactor: PlayerRepository.findAll() Fetch Join 진행 * test: 지연 로딩으로 인한 테스트 에러 임시 수정 * refactor: 코드컨벤션 젹용 * refactor: 날짜 수정 * refactor: mdc 필터 제거 * refactor: 사용하지 않는 mdc토큰 제거 * refactor: 로깅 전략 변경에 따른 코드 수정 * refactor: xml파일에서 mdc 출력 삭제 * refactor: 환경분리 및 패턴 수정 * fix: 환경분리 오류 수정 * refactor: mdc 요소 추가 * chore: 워크플로우 수정 * fix: 트렌젝션 테스트에 추가 * fix: 에러로그 출력 오류 수 * refactor: info로그 수정 * refactor: warn로그 수정 * refactor: error로그 수정 * refactor: 사용하지 않는 enum 삭제 * refactor: 주석 제거 * refactor: 패키지 이동 * refactor: 사용하지 않는 코드 제거 * refactor: warn 레벨 info 로 수정 --------- Co-authored-by: dooboocookie Co-authored-by: dooboocookie <79090478+dooboocookie@users.noreply.github.com> * refactor: my page 뷰 디자인 변경 (#395) * refactor: 통계 뷰 변경, 리사이클러뷰 사용 * refactor: 패키지 구조 변경 * refactor: 리사이클러뷰 반영 * refactor: 다른이름의 같은 속성의 파일을 하나로 사용하도록 변경 * refactor: 아이템마다 배경이 다르게 지정되도록 변경 * refactor: StatisticsModel 생성 코드를 StatisticsModel 내부로 이동 * refactor: String 상수화 * refactor: 내가 추가한 장소 뷰 디자인 수정 * refactor: 마진 수정 * refactor: 내가 추가한 장소 커스텀 뷰 수정 - 뷰타입에 따라 분리하지 않음 - 리사이클러뷰에서 뷰홀더를 하나로 사용 * refactor: 리사이클러뷰 가로 스크롤로 변경 * refactor: 글씨 크기, 마진 변경 * feat: 장소를 추가한 적 없는 유저에게는 다른 뷰가 보이도록 함 * refactor: 마진 수정 * refactor: ktlint * refactor: drawable 변경 * refactor: 아이콘 변경 * refactor: apply 적용 * refactor: marginTop 추가 * refactor: 모험 결과 뷰 디자인 변경 (#402) * design: 성공, 실패를 나타내주는 라벨 drawable 생성 * design: main blue 색을 이용한 그라데이션 배경 resource 추가 * design: 버튼 drawable resource 추가 * design: 모험 결과 디자인 변경 * refactor: string 한글로 변경 * refactor: margin 변경 * refactor: drawable 이름 변경 * fix: 장소 추천 범위 정상화 (#411) * fix: 장소 추천 범위 300m로 정상화 * test: 300미터 추천 못할 떄 테스트 보완 * refactor: 게임 시작 뷰 디자인 변경 (#408) * chore: 전체 gitignore 지정 * feat: 버튼 이미지 추가 * feat: BeginActivity에서 자주 쓰이는 Text style 생성 * feat: BeginActivity 뷰 구현 중 * feat: button drawable을 png에서 vector asset으로 변경 및 네이밍 변경 * feat: BeginAdventureActivity 뷰 레이아웃 변경 - setting 버튼 추가 - 빌딩 이미지 화면 사이즈에 맞춤 - 기타 마진 및 패딩 변경 * feat: BeginAdventureActivity 변경된 뷰에 따라 클릭리스너 연결 코드 변경 * feat: 다이얼로그 버튼 배경 변경 * feat: 임시로 설정해놓은 visibility 원상복구 * feat: 사용하지 않는 resource 삭제 * feat: bg_yellow_button drawable 변경 * feat: 사용하지 않는 파일 삭제 * feat: 버튼 백그라운드 적용 * feat: 버튼 백그라운드 적용 * feat: 업로드 화면에서 뒤로가기 기능 구현 (#413) * feat: 게임 입장 시 사진이 먼저 뜨는 기능 구현 (#407) * feat: 검수 중인 장소에 대한 장소 등록 허가 API 구현 (#398) * feat: 임시용 TemporaryPlaceService 생성 * refactor: 바뀐 요구사항에 맞게 createPlace 로직 리팩터링 * refactor: 바뀐 API 명세에 따라 컨트롤러 로직 리팩터링 * fix: 잘못된 base64 디코딩 과정 수정 * feat: 장소 등록 API에 매니저 인터셉터 적용 * feat: 등록할 장소 기준 반경 20M 내에 또 다른 등록된 장소가 존재한다면 예외를 터뜨리도록 수정 * test: 주변 반경 20M 내에 등록된 장소가 있을 때 예외 발생 확인을 위한 테스트 코드 추가 * refactor: collect() 에서 toList() 로 변경 * chore: 주석 삭제 * feat: 검수 중인 장소에 대한 등록 승인 거절 API 구현 (#401) * refactor: 바뀐 API 명세에 따라 컨트롤러 로직 리팩터링 * feat: 리베이스 충돌 해결 * feat: 검수 장소에 대한 테스트 빌더 구현 * feat: 검수 장소 삭제 API 구현 * feat: 검수 장소 삭제 API 에 ManagerAuthInterceptor 적용 * feat: 검수 장소에서 Player 에 대해 지연로딩 적용 * test: mocking 삭제 및 상태 검증 테스트로 변경 * test: 행위 검증에서 상태 검증 테스트로 변경 * feat: 검수할 장소 등록/ 조회 API 구현 (#404) * fix : ManagerAuthInterceptor 디코딩 수정 * feat: 인터셉터에 검수중 장소 조회 path 등록 * feat: 검수할 장소 등록 기능 추가 * feat: 검수할 장소 등록 API 구현 * feat: 검수할 장소 목록 조회 기능 구현 * feat: 검수할 장소 목록 조회 API 구현 * fix: 서비스 객체 빈 등록 및 인터셉터 추가 * test: TemporaryPlaceBuilder 및 TemporaryPlaceFixture 작성 * test: ManagerAuthInterceptorTest 디코딩 문제 수정 * feat: TemporaryPlace예외 처리 추가 및 적용 * test: 검수할 장소 등록 테스트 추가 * test: 필요없는 테스트 삭제 * test: 20미터에 이미 등록된 목적지가 있다면 예외응답 테스트 * refactor: 필요없는 메서드 삭제 * refactor: PlaceCheckService 패키지 변경 및 예외 수정 * test: 검수할 장소 목록 조회 기능 테스트 * refactor: 콘솔 로깅 디버그 레벨로 변경 * refactor: TemporaryPlace관련 조회 쿼리 n+1문제 리팩터링 * refactor: TemporaryPlaceResponse에 플레이어 정보 추가 * chore: 개행 제거 * test: TemporaryPlaceControllerTest 수정 * refactor: 서비스 메서드명 변경 * refactor: TemporaryPlaceResponse 필드명 변경 * refactor: 검수할 장소 조회 오래된 순으로 정렬 순서 변경 --------- Co-authored-by: dooboocookie * refactor: 버튼 디자인 일관성 있도록 변경 (#417) * refactor: 버튼 drawable 추가 * refactor: 버튼 background 변경 * refactor: 버튼 background 변경 * refactor: 버튼 background 변경 * refactor: 버튼 background 변경 * refactor: 게임 시작 뷰 디자인 변경 (#408) * chore: 전체 gitignore 지정 * feat: 버튼 이미지 추가 * feat: BeginActivity에서 자주 쓰이는 Text style 생성 * feat: BeginActivity 뷰 구현 중 * feat: button drawable을 png에서 vector asset으로 변경 및 네이밍 변경 * feat: BeginAdventureActivity 뷰 레이아웃 변경 - setting 버튼 추가 - 빌딩 이미지 화면 사이즈에 맞춤 - 기타 마진 및 패딩 변경 * feat: BeginAdventureActivity 변경된 뷰에 따라 클릭리스너 연결 코드 변경 * feat: 다이얼로그 버튼 배경 변경 * feat: 임시로 설정해놓은 visibility 원상복구 * feat: 사용하지 않는 resource 삭제 * feat: bg_yellow_button drawable 변경 * feat: 사용하지 않는 파일 삭제 * feat: 버튼 백그라운드 적용 * feat: 버튼 백그라운드 적용 * feat: 업로드 화면에서 뒤로가기 기능 구현 (#413) * feat: 게임 입장 시 사진이 먼저 뜨는 기능 구현 (#407) * refactor: 불필요한 속성 제거 * refactor: 불필요한 속성 제거 * refactor: guideline 추가해 뷰 배치 --------- Co-authored-by: k_dragonm <78788847+briandr97@users.noreply.github.com> Co-authored-by: krrong * refactor: 스플래시 디자인 변경 (#416) * refactor: 뷰 id 변경 * refactor: 안드로이드 12에서 나오는 스플래시가 보이지 않는 것처럼 구현 * refactor: 불필요한 코드 삭제 * refactor: warning 제거 애노테이션 추가 * refactor: 불필요한 파일 삭제 * refactor: 기본 스플래시를 사용하도록 변경 * refactor: 스플래시 액티비티 디자인 변경 * refactor: 아이콘 변경 * refactor: 인게임 뷰 디자인 변경 (#418) * chore: 전체 gitignore 지정 * feat: 목적지와의 남은 거리를 나타내는 텍스트 리디자인 * feat: 아이콘 생성 * feat: strings resource화 * feat: 인게임 뷰 리디자인 적용 * feat: 폴라로이드 다이얼로그 디자인 변경 * feat: NaagaAlertDialog의 positive 버튼과 negative 버튼의 위치 변경 및 색상 변경 * feat: 버튼 백그라운드 이미지 적용 * feat: 로티 visibility 원상복구 * feat: 로딩시 거리가 null로 보여지는 것을 0으로 변경 * feat: 버튼 마진값 조절 * feat: 사용하지 않는 아이콘 삭제 * chore: release/v2.0 변경 사항 적용 (#425) * chore: dev_backend 커밋 내역 Merge * chore: 워크플로우 수정 chore: 로그 경로 수정 --------- Co-authored-by: kokodak * refactor: NaagaAlertDialog와 ConfirmDialog 통일 (#421) * chore: 전체 gitignore 지정 * feat: NaagaAlertDialog에서 Cancelable 여부를 정할 수 있도록 변경 * feat: ConfirmDialog를 삭제하고 AlertDialog로 대체 * feat: 함수 네이밍 변경 및 사용하지 않는 함수 삭제 * chore: 다이얼로그를 한 패키지에 모음 * feat: 사용되지 않는 다이얼로그의 layout 삭제 * refactor: 장소 등록 api 수정 (#369) * refactor: 장소 등록을 검수할 수 있도록 검수중으로 등록한다 * refactor: 변경된 API 명세 반영 * refactor: string 변경 * feat: 장소등록 성공시 토스트 메시지를 띄워줌 * refactor: 인게임 버튼 drawable resource 변경 (#424) * chore: 전체 gitignore 지정 * feat: 버튼의 배경 resource를 변경 * feat: 하단 버튼들의 margin값 변경 * refactor: permission dialog 통일 (#426) * refactor: 다이얼로그 패키지 이동 * refactor: 다이얼로그 패키지 이동 * refactor: 다이얼로그 폰트 변경 * refactor: 사용하지 않는 파일 삭제 * refactor: string 정리 * refactor: 함수 분리 * feat: 문의하기 기능 구현 (#427) * feat: strings resource 추가 * feat: 문의하기를 누르면 나아가 공식 계정으로 이메일이 보내 지는 기능 구현 * refactor: 이메일 제목 strings에 추가 * feat: 버전코드 및 버전이름 수정 (#431) * feat: 쪽지 기능 뼈대코드 설계 및 구현 (#389) * feat: 쪽지 도메인 생성 * feat: Letter JpaRepository 생성 * test: Letter Fixture, Builder 생성 * feat: LetterController 생성 * chore: 불필요한 개행 삭제 * refactor: BaseEntity 상속 * chore: 코드 컨벤션 적용 * hotfix: 액세스 토큰 리프레시 및 자동 로그인 로직 수정 (#438) * [ALL] 버전 1 출시 main 브랜치 머지 (#299) * chore: 안드로이드 프로젝트 폴더 생성 (#2) (#3) * feat: 안드로이드 프로젝트 초기 세팅 (#5) * chore: 안드로이드 프로젝트 폴더 생성 (#2) * feat: 안드로이드 프로젝트 초기 세팅 * chore: gitignore 수정 및 불필요한 파일 삭제 * feat: 프로젝트 초기 세팅 (#7) * fix: 초기 설정 삭제 (#10) * feat: 백엔드 프로젝트 초기 세팅 (#11) * feat: 프로젝트 초기 세팅 * chore: .DS_Store 파일 삭제 및 gitignore 추가 * chore: .DS_Store 파일 삭제 및 gitignore 추가 * chore: 패키지 구조 설정 (#12) * [BE] feat: 엔티티 설계 (#15) * chore: 프로퍼티 파일 수정 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Member 엔티티 생성 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Place 엔티티 생성 - Position 도메인 생성 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Game 엔티티 생성 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Position의 동등성 기능 추가 --------- Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: 초기 resource 파일 세팅 (#16) * feat: DTO 생성 (#18) * feat: 위치를 나타내는 Dto 생성 * feat: 목적지를 나타내는 Dto 생성 * chore: gitkeep 파일 삭제 * feat: Domain 설계 및 생성 (#21) * refactor: 좌표를 나타내는 Dto 이름 변경 * feat: 좌표를 저장하는 도메인 클래스 생성 * feat: 목적지를 저장하는 도메인 클래스 생성 * feat: 도메인 repository 인터페이스 생성 * feat: 네이버 맵을 화면에 띄우는 기능 구현 (#23) * feat: 네이버 맵을 사용하기 위한 의존성을 gradle에 추가 * feat: manifest에 네이버 맵을 사용하기 위한 메타 데이터 추가 * feat: 액티비티 네이밍 변경, 네이버 맵을 화면에 띄우는 기능 구현 * chore: .gitignore 수정 * chore: 네이버 지도 사용을 위해 gradle.properties에 제티파이어를 추가하여 버전 차이 문제를 해결 * feat: 회원 인증 기능 구현 (#26) * feat: 회원정보 추출 기능 구현 * feat: 회원 인증 어노테이션 커스텀 구현 * feat: 인터셉터 추가 * refactor: argumentResolver 리팩토링 * feat: 설정정보 인터셉터 추가 * refactor: 회원 정보 조회 예외처리 중복 수정 * feat: 위치 권한 요청 기능 구현 (#27) * chore: repository 패키지 위치 이동 * feat: 모험시작 액티비티 생성 - 필요한 위치권한 Manifest에 등록 - 위치권한 요청 * design: UI관련 resource 추가 * feat: 게임 시작 기능 액티비티 추가 및 권한 요청 기능 구현 * design: 문자열 strings 리소스화 * design: 배경 및 버튼 색상 변경 * feat: 네이버지도에서 현재 위치를 잡는 기능 구현 (#28) * feat: 위치 권한을 승인한 경우 모험 액티비티로 이동하는 기능 구현 * feat: 내 위치를 잡으면 트래킹하도록 기능 구현 * feat: isLocationButtonEnabled 활성화 구현 * feat: 장소 추천 기능 구현 (#29) * chore: 프로퍼티 파일 수정 * feat: 위치 기준으로 반경 거리내의 장소 추천 쿼리 작성 * feat: Game 엔티티 빈 생성자 추가 * refactor: 패키지명 수정 * chore: 더미 데이터 추가 * feat: Game 엔티티 생성 * feat: Place 서비스 계층 생성 feat: 장소 선정 로직 기능 구현 * feat: GameRepository 생성 * feat: Game 서비스 계층 생성 feat: 장소 선정 기능 구현 * feat: Place 응답 DTO 구현 * feat: Game 컨트롤러 계층 생성 * style: 코드 정렬 * feat: 목적지와 현재위치 사이 거리를 계산하여 사용자에게 보여주는 기능 구현 (#35) * feat: repository 목 구현체 생성 * feat: OnAdventureViewModel 생성 * refactor: 거리 반환값의 자료형을 Int로 수정 * feat: 목적지와 현재위치 사이 거리를 계산하여 사용자에게 보여주는 기능 구현 * feat: Coordinate를 받아 해당 위치에 좌표를 찍는 기능 구현 (#39) - 목적지를 임시로 상수처리 - 추후 목적지를 서버에서 받아 마커를 찍는 방식으로 수정 필요 * feat: 사진 버튼을 클릭하면 사진 다이얼로그를 띄우는 기능 구현 (#40) * design: close icon 추가 * feat: 화면에 관련된 유틸 파일과 메서드 생성 * design: OnAdventure 액티비티에서 사진을 보여주기 위한 다이얼로그 UI 구현 * feat: 목적지에 대한 사진을 띄워주는 DestinationPhotoDialog 구현 * refactor: LocationDialogFragment의 메서드를 DisplayUtil로 분리 * style: 코드 정렬 * feat: 생성시 액티비티로부터 사진을 받아오는 기능 구현 * design: 사진 아이콘 버튼 추가 * feat: 액티비티에서 사진 아이콘 버튼 클릭시 다이얼로그를 띄우는 로직 구현 * feat: 사진이 로딩중 문구 strings 리소스화 * feat: 뷰모델로부터 얻어온 사진을 넘기도록 로직 수정 * refactor: 다이얼로그 및 변수 네이밍 변경 * refactor: strings 리소스화 * refactor: 객체 네이밍 변경 * feat: 목적지에 도착 시 도착 버튼 활성화 기능 구현 (#41) * design: 비활성화 버튼 color resource 추가 * design: 버튼의 상태에 따라 버튼 UI가 변경 되는 selector 생성 * feat: 목적지 도달 시 모험 종료 버튼 활성화 기능 추가 * refactor: 기존에 있는 drawable 활용해 selector 생성 * refactor: 도착 버튼 string을 resource에 추가 * refactor: API 명세 변경으로 인한 기능 수정 (#43) * refactor: 조회 쿼리의 결과를 List로 받도록 수정 * feat: 인증 관련 예외 기능 추가 * feat: 게임 관련 예외 기능 추가 * feat: 장소 관련 예외 기능 추가 * feat: 회원 관련 예외 기능 추가 * feat: 수정된 API 명세에 맞춰 게임 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 게임 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 장소 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 회원 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 게임 서비스 로직 수정 * feat: 게임에 대한 응답 DTO 생성 * feat: 수정된 API 명세에 맞게 컨트롤러 수정 * feat: 수정된 API 명세에 맞게 컨트롤러 수정 * style: import문 최적화 * refactor: 기존 런타임 예외를 인증 커스텀 예외로 수정 * refactor: 사용하지 않은 메서드 삭제 * refactor: 상수 이름 변경 * refactor: final 키워드 추가 * refactor: @Transactional 어노테이션에 readOnly 속성 추가 * refactor: 패키지 수정 --------- Co-authored-by: kokodak * feat: 서버통신 초기세팅 (#44) * feat: Adventure 도메인 클래스 생성 * feat: Adventure 상태를 갖는 enum 클래스 생성 * feat: 기능 변경에 따른 repository 변경 * chore: 사진 다이얼로그 패키지 위치 변경 * feat: AdventureDto 클래스 생성 * feat: Dto와 domain 클래스간의 mapper 구현 * refactor: repository 이름 변경 * feat: repository 기능 변경으로 인한 mock repository 변경 * feat: retrofit service 인터페이스 생성 * feat: adventure ERROR 상태 클래스 추가 * feat: Repository 변경에 따른 ViewModel 변경 및 서버 통신 오류 처리 * feat: Retrofit 객체 생성 및 interceptor 구현 * chore: AdventureService 패키지 위치 변경 * feat: 목적지 도착 여부 확인 기능 구현 (#47) * feat: 좌표사이의 거리를 키로미터로 계산하는 로직 구현 * feat: 도착여부 판단 및 접근 권한 검증 기능 구현 * feat: 장소의 유효범위 여부 검증 구현 * feat: 게임 종료기능 api 구현 * refactor: 게임 관련 예외를 사용하도록 변경 * refactor: 인증 관련 예외 추가 및 적용 * style: final 키워드 추가 및 코드 정렬 * fix: 파라미터명 수정 * feat: 백엔드 ci workflows 초안 작성 (#49) * chore: step 이름 추가 (#50) * [BE] fix: 백엔드 ci workflows 초안 작성 (#51) * chore: step 이름 추가 * fix: default working directory 추가 * fix: working directory 상대경로로 변경 (#52) * chore: step 이름 추가 * fix: default working directory 추가 * fix: working directory 상대경로로 변경 * feat: 서버에 모험 시작을 요청하는 기능 구현 (#48) * refactor: AdventureRepository 수정 * feat: Coordinate 객체의 Domain to Dto 매핑 함수 생성 * feat: Result의 failure에서 사용할 나아가 팀만의 Throwable 생성 * feat: 서버통신이 성공적이지 않을 때에 대한 객체와 서버통신 코드를 단순화할 메서드 생성 * feat: AdventureRepository의 beginAdventure 함수 구현 * refactor: 코드 방식 변경 get() -> [] * feat: MockRepository의 beginAdventure 함수 구현 * refactor: 타입을 표현해줌 * feat: 실제 base url 등록 * feat: http 통신 허용 * fix: json 변환 과정 수정 * fix: TODO 주석처리 * feat: 코루틴 의존성 추가 * feat: 모험을 시작하는 서버통신 구현 * feat: 모험이 끝났을 때 서버에게 모험이 종료 됐음을 알려주는 기능 구현 (#53) * feat: 모험 종료 시 서버에게 데이터를 받아 올 Dto 생성 * feat: 모험 종료 시 서버에게 받아 온 Dto mapper 생성 * refactor: 데이터 반환 값 타입 변경 * feat: AdventureRepository의 endAdventure 구현 * feat: 모험 종료 시 서버와 통신해 현재 모험 상태를 받아온 후 상황에 맞게 분기 처리 해주는 기능 구현 * refactor: mock Repository의 endAdventure 함수 구현 * fix: onClick에서 사용된 함수에게 인자를 넣어 Databinding 오류 해결 * feat: 서버에서 목적지를 받아오는 기능 구현 (#54) * refactor: 게임 정보를 가져오는 서비스 수정 * feat: 서버에서 목적지를 받아오는 기능 구현 * fix: 목적지 도착 버튼 클릭 시 발생하는 오류 수정 (#56) * fix: RetrofitService Path 수정 * fix: Serializable 어노테이션 추가 * refactor: iteration 명칭 변경 및 타입 명시 제거 * feat: 안드로이드 프로젝트에 firebase 추가 (#75) * feat: 필요 없는 파일 삭제 잘못 올린 파일을 삭제합니다. * chore: gitignore 수정 (#78) * feat: 안드로이드 CI 자동화 (#77) * chore: ktlint를 위한 config 파일 추가 * chore: ci 자동화를 위한 yml 파일 추가 * style: ktlint에 걸린 코드 정렬 * chore: ci 자동화 json 파일 추가 * style: ktlint에 걸린 코드 정렬 * style: ktlint에 걸린 코드 정렬 * chore: ci 자동화 json 파일 추가 * style: ktlint에 걸린 코드 정렬 * style: ktlint에 걸린 코드 정렬 * chore: ci 자동화 파일 수정 * style: ktlint 규칙 변경에 따른 수정 * feat: 스플래시 화면에서 진행 중인 모험이 있는지 판단하고 분기 하는 기능 구현 (#58) * chore: apk 및 aab 추출을 위한 파일 * design: splash를 위한 스타일 생성 * feat: 레포지토리에 모험 상태를 통해 모험 목록을 받아오는 기능 추가 * feat: 모험 상태를 통해 모험목록을 받아오는 retrofit 인터페이스 작성 * feat: 모험 상태를 통해 모험 목록을 반환하는 레포지토리 기능 구현 * feat: 이전 액티비티로부터 OnAdventureActivity로 화면을 전환할때 필요한 인텐트를 반환하는 함수 작성 * feat: 스플래시 액티비티와 뷰모델(및 팩토리) 생성 - 스플래시에서 서버통신을 통해 현재 진행 중인 모험이 있는지 확인한다. - 현재 진행 중인 모험이 있다면 해당 모험과 함께 OnAdventureActivity로 이동한다. - 현재 진행 중인 게임이 없다면 BeginAdventureActivity로 이동한다. * feat: 화면간 데이터 이동을 위한 uiModel 생성 - gradle에 parcelize 플러그인 추가 - AdventureUiModel 및 Mapper 생성 - CoordinateUiModel 및 Mapper 생성 - DestinationUiModel 및 Mapper 생성 * feat: parcelable한 데이터를 인텐트로부터 받기 쉽게할 유틸 함수 작성 * feat: OnAdventureActivity가 열리는 두 가지 경우에 따라 모험을 지정 - 이미 모험이 진행 중이면 이전 화면으로부터 모험을 전달 받고 모험을 서버에 요청하지 않는다. - 진행 중인 모험이 없다면 서버로부터 모험을 요청한다. * refactor: OnAdventureActivity에서 Intent를 생성해주므로 해당 함수를 이용하도록 변경 * [AN] feat: registerForActivityResult 분기처리 기능 구현 (#72) * design: 대락적인 위치 권한만 허용됐을 시 보여줄 문구 string 리소스로 추가 * feat: Dialog 내에서 권한을 체크하여 대략적인 위치 권한이 있는 상태와 전혀 없는 상태를 구분하여 다른 문구를 보여주도록 구현 * feat: BeginAdventureActivity 권한 코드 수정 - 유저가 권한 요청을 허용 및 거절 했을 시 토스트 메시지로 즉각적인 피드백을 주도록 구현 - 함수 분리 - 다이얼로그 태그 상수화 * feat: BeginAdeventureActivity UI 변경사항 적용 (#71) * design: 랭크, 마이페이지, 업로드 아이콘 추가 * design: 기존의 background를 지정하고 tint로 색을 지정하는 방식은 elevation을 반영하지 못해 색이 있는 shape을 새로 생성함 * design: BeginAdventureActivity에서 사용될 style 생성 * design: BeginAdventureActivity xml 레이아웃 작성 * feat: AdventureResultActivity 구현 (#80) * design: 모험 결과 상태에 따른 스탬프 drawable 리소스 추가 * design: 모험 결과 페이지에 필요한 strings 리소스 추가 * feat: 모험 결과에 따라 다른 UI가 띄워지는 액티비티 구현 * fix: manifest 오류 수정 * feat: 3차 데모데이 엔티티 설계 (#84) * feat: BaseEntity 생성 * feat: Player 도메인 생성 * feat: Hint 도메인 생성 Co-authored-by: dooboocookie * feat: GameResult 도메인 생성 Co-authored-by: dooboocookie * style: import문 최적화 Co-authored-by: dooboocookie * feat: 스프링 부트 어플리케이션에 @EnableJpaAuditing 추가 Co-authored-by: dooboocookie * refactor: 게임 도메인 수정 Co-authored-by: dooboocookie * refactor: 장소 도메인 생성 Co-authored-by: dooboocookie * refactor: Score 도메인 생성 Co-authored-by: dooboocookie * refactor: Place에 BaseEntity 상속 추가 * refactor: Member에 BaseEntity 상속 추가 및 생성자 추가 --------- Co-authored-by: dooboocookie * feat: OnAdventureActivity UI 변경사항 적용 (#73) * design: OnAdventureActivity에서 사용하는 아이콘 추가 * rename: drawable 컨벤션 유지 * design: 색상 추가 * design: 원 형태의 백그라운드 추가 * design: 문구 변경 * feat: OnAdventureActivity UI 변경사항 적용 * feat: 서버로부터 받아온 목적지에 핀을 꽂는 기능 제거 * rename: 일관성을 위한 아이콘 이름 수정 * design: 하단 버튼 높이 통일 * design: 흰색 배경 drawable 생성 * design: 버튼 그림자 생성 * feat: 충돌 해결 * feat: 충돌 해결 * feat: 충돌해결 * [AN] feat: UploadActivity 구현 * chore: gitignore 수정 * design: 카메라, 좌표 아이콘 추가 * design: 출력 문구 추가 * design: 마진 사이즈 추가 * feat: UploadActivity 구현 * feat: UploadActivity의 인텐트를 가져오는 함수 구현 * chore: string.xml 변수명 변경 * refactor: 사진이 들어갈 이미지뷰와 카메라 아이콘을 분리 * feat: 카메라 권한 요청 기능 구현 (#92) * design: 카메라 권한 관련 아이콘 추가 * feat: 카메라 권한 추가 * feat: dataBinding 사용하도록 xml 변경 * feat: 카메라 위치권한을 요구하는 다이얼로그 생성 * feat: 카메라 권한이 없는 경우 권한 요청 다이얼로그를 띄우는 기능 구현 * chore: 레이아웃 id 컨벤션 유지 * refactor: 다이얼로그의 tag를 다이얼로그 클래스에 위치하도록 통일 * refactor: 매직넘버 상수화 * rename: drawable 파일명 변경 * feat: 명세서 기준으로 Dto들 생성 (#89) * feat: 명세서 기준으로 Dto들 생성 * feat: 변경된 API 명세에 맞춰 Dto 변경 * feat: 디바이스의 위치를 받아와 뷰에 보여주는 기능 구현 (#93) * feat: 디바이스의 위치를 받아와 뷰에 보여주는 기능 구현 * refactor: 좌표를 문자열로 반환하는 기능 함수분리 * feat: 도메인 모델 생성 (#91) * refactor: ERROR를 NONE으로네이밍 변경 * feat: 도메인 객체 생성 (미완) * feat: 도메인 객체 수정 및 추가 생성 * feat: 도메인 수정 * rename: 패키지명 수정 * feat: 통계 path 레트로핏 서비스 구현 #101 * feat: 서버에서 Rank 관련 데이터를 받아올 때 사용될 service 생성 (#100) * feat: 3차 데모데이용 Game Path 레트로핏 서비스 생성 (#102) * feat: 장소 path 레트로핏 서비스 구현 (#103) * feat: AdventureHistoryActivity 구현 (#106) * design: AdventureHistory 뷰에 필요한 string resource 추가 * design: AdventureHistory 뷰에 필요한 drawable resource 추가 * design: 리사이클러뷰에 들어갈 Item 레이아웃 생성 * feat: 모험 기록을 보여 주는 리사이클러뷰 어댑터 생성 * feat: AdventureHistory 액티비티 구현 * feat: AdventureHistoryActivity에 모험 기록을 보여줄 리사이클러뷰 구현 * feat: 뒤로가기 버튼 구현 * refactor: 함수 이름 변경 * refactor: 이름이 길어질 때 줄여쓰기가 되도록 기능 추가 * refactor: Mock 데이터 생성 방법 수정 * refactor: 불필요한 함수 인자 삭제 * feat: RankRepository 생성 (#109) * refactor: Service 명 수정 * feat: RankRepository Interface 구현 * feat: PlayerDto를 도메인 객체로 바꿔주는 도메인 mapper 생성 * feat: RankDto를 도메인 객체로 바꿔주는 도메인 mapper 생성 * feat: 서버와 Rank 데이터를 주고 받기 위해 팔요한 rank service 객체 생성 * feat: RankRepository 구현체 생성 * refactor: 함수 인자 표시 * feat: StatisticsRepository 생성 (#110) * rename: 파일명 수정 * feat: StatisticsRepository 인터페이스 생성 * feat: 서버와의 Statistics 관련 통신을 위한 service 객체 생성 * feat: StatisticsDto 객체를 도메인 객체로 바꿔주는 Mapper 생성 * feat: StatisticsRepository 구현체 생성 * refactor: 함수 인자 표시 * feat: 3차 데모데이 기획 변경에 맞는 AdventureRepository 설계 및 구현 (#111) * feat: 3차 데모데이 기획 변경에 맞는 AdventureRepository 설계 및 구현 * chore: 잘못 위치한 파일 위치 변경 * feat: PlaceRepository 생성 (#118) * feat: 장소 repository interface 생성 * feat: 서비스풀에 장소 서비스 추가 * feat: place mapper 생성 * feat: 장소 repository 구현체 생성 * refactor: 오류처리 변경에 따른 repository 코드 수정 * feat: 통계 path api 목서버 구현 (#116) * feat: 랭크 path api 목서버 구현 (#117) * feat: 랭크 path api 목서버 구현 * feat: 필요없는 변수 변환 로직 제거 * feat: RankActivity 구현 (#119) * feat: RankActivity 생성 * feat: RankActivity의 Intent를 생성해주는 함수 구현 * feat: 내 순위 및 전체 순위 목 데이터를 라이브 데이터 값으로 넣어주는 기능 구현 * design: RankActivity에 필요한 string resource 추가 * design: 내 순위 및 전체 순위를 보여주는 뷰 구현 * feat: 전체 순위를 띄워줄 리사이클러뷰 생성 및 구현 * feat: LiveData를 이용해 리사이클러뷰에 리스트 전달 * feat: 창 닫기 버튼 추가 구현 * refactor: Manifest 내의 rankActivity 위치 이동 * refactor: 컨벤션에 맞게 id 변경 * design: elevation을 활용해 그림자 추가 * refactor: dimens 적용 * refactor: 그림자 적용 * feat: 카메라로 찍은 사진을 뷰에 띄우고 Uri 추출기능 구현 (#120) * feat: 촬영한 사진을 이미지뷰에 보여주는 기능 구현 * feat: 촬영한 사진의 Uri 추출 기능 구현 * refactor: 권한 요청 로직 수정 및 함수 위치 변경 - 업로드 화면으로 이동 시 시스템 권한 요구 상자 팝업(카메라, 위치) - 거절한 권한에 대해 권한요청 다이얼로그 프래그먼트 팝업 * feat: 좌표 이미지를 클릭하여 좌표를 받아 보여주는 기능 구현 * feat: 닫기 버튼 추가 * feat: 3차 데모데이 뼈대 코드 추가 (#130) * refactor: AuthInterceptor에서 인증처리만 하도록 변경 * feat: PlayerException 추가 * feat: Player를 MemberId로 조회하는 기능 추가 * refactor: 로그인 된 PlayerId를 받는 ArgumentResolver 구현 * refactor: PlayerService 적용 refactor: Request DTO 와 Command DTO 분리 * feat: MyPageActivity 구현 (#121) * refactor: ERROR를 NONE으로네이밍 변경 * feat: 도메인 객체 생성 (미완) * feat: 도메인 객체 수정 및 추가 생성 * feat: 인터넷 권한 추가 * feat: 마이페이지의 아이템에 필요한 리사이클러뷰 구현 * feat: 마이페이지에 재사용이 여러번 될 가능성이 있는 뷰를 커스텀 뷰로 제작 * feat: 마이페이지 액티비티 생성 * style: 개행 * feat: 마이페이지 아이템의 두가지 경우의 레이아웃을 따로 제작 * feat: 레이아웃이 두개로 나눠짐에 따라 어댑터 수정중 * feat: 마이페이지 커스텀 아이템 레이아웃 수정 * feat: 마이페이지 커스텀 아이템 내부 리사이클러뷰 구현 방식 변경 (멀티 뷰홀더 적용) * feat: 마이페이지 뷰 구현 * feat: 도메인 모델을 UI모델로 변경할 매퍼 함수 생성 * design: mypage 레이아웃 디자인 변경 * feat: 뒤로가기 클릭리스너 추가 * remove: 중복된 객체 삭제 * refactor: view의 id 수정 * feat: Statistics 도메인 객체 수정으로 인해 자료형 변환 로직 추가 * fix: BaseEntity에 맞춘 data.sql 수정 (#133) * [BE] refactor: Pull Request 워크플로우 수정 (#134) * refactor: DTO들이 모두 record로 구현되도록 수정 (#136) … * [ALL] 버전 5 출시 release/v3.1 로 안드로이드 코드 머지 (#548) * chore: 안드로이드 프로젝트 폴더 생성 (#2) (#3) * feat: 안드로이드 프로젝트 초기 세팅 (#5) * chore: 안드로이드 프로젝트 폴더 생성 (#2) * feat: 안드로이드 프로젝트 초기 세팅 * chore: gitignore 수정 및 불필요한 파일 삭제 * feat: 프로젝트 초기 세팅 (#7) * fix: 초기 설정 삭제 (#10) * feat: 백엔드 프로젝트 초기 세팅 (#11) * feat: 프로젝트 초기 세팅 * chore: .DS_Store 파일 삭제 및 gitignore 추가 * chore: .DS_Store 파일 삭제 및 gitignore 추가 * chore: 패키지 구조 설정 (#12) * [BE] feat: 엔티티 설계 (#15) * chore: 프로퍼티 파일 수정 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Member 엔티티 생성 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Place 엔티티 생성 - Position 도메인 생성 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Game 엔티티 생성 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Position의 동등성 기능 추가 --------- Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: 초기 resource 파일 세팅 (#16) * feat: DTO 생성 (#18) * feat: 위치를 나타내는 Dto 생성 * feat: 목적지를 나타내는 Dto 생성 * chore: gitkeep 파일 삭제 * feat: Domain 설계 및 생성 (#21) * refactor: 좌표를 나타내는 Dto 이름 변경 * feat: 좌표를 저장하는 도메인 클래스 생성 * feat: 목적지를 저장하는 도메인 클래스 생성 * feat: 도메인 repository 인터페이스 생성 * feat: 네이버 맵을 화면에 띄우는 기능 구현 (#23) * feat: 네이버 맵을 사용하기 위한 의존성을 gradle에 추가 * feat: manifest에 네이버 맵을 사용하기 위한 메타 데이터 추가 * feat: 액티비티 네이밍 변경, 네이버 맵을 화면에 띄우는 기능 구현 * chore: .gitignore 수정 * chore: 네이버 지도 사용을 위해 gradle.properties에 제티파이어를 추가하여 버전 차이 문제를 해결 * feat: 회원 인증 기능 구현 (#26) * feat: 회원정보 추출 기능 구현 * feat: 회원 인증 어노테이션 커스텀 구현 * feat: 인터셉터 추가 * refactor: argumentResolver 리팩토링 * feat: 설정정보 인터셉터 추가 * refactor: 회원 정보 조회 예외처리 중복 수정 * feat: 위치 권한 요청 기능 구현 (#27) * chore: repository 패키지 위치 이동 * feat: 모험시작 액티비티 생성 - 필요한 위치권한 Manifest에 등록 - 위치권한 요청 * design: UI관련 resource 추가 * feat: 게임 시작 기능 액티비티 추가 및 권한 요청 기능 구현 * design: 문자열 strings 리소스화 * design: 배경 및 버튼 색상 변경 * feat: 네이버지도에서 현재 위치를 잡는 기능 구현 (#28) * feat: 위치 권한을 승인한 경우 모험 액티비티로 이동하는 기능 구현 * feat: 내 위치를 잡으면 트래킹하도록 기능 구현 * feat: isLocationButtonEnabled 활성화 구현 * feat: 장소 추천 기능 구현 (#29) * chore: 프로퍼티 파일 수정 * feat: 위치 기준으로 반경 거리내의 장소 추천 쿼리 작성 * feat: Game 엔티티 빈 생성자 추가 * refactor: 패키지명 수정 * chore: 더미 데이터 추가 * feat: Game 엔티티 생성 * feat: Place 서비스 계층 생성 feat: 장소 선정 로직 기능 구현 * feat: GameRepository 생성 * feat: Game 서비스 계층 생성 feat: 장소 선정 기능 구현 * feat: Place 응답 DTO 구현 * feat: Game 컨트롤러 계층 생성 * style: 코드 정렬 * feat: 목적지와 현재위치 사이 거리를 계산하여 사용자에게 보여주는 기능 구현 (#35) * feat: repository 목 구현체 생성 * feat: OnAdventureViewModel 생성 * refactor: 거리 반환값의 자료형을 Int로 수정 * feat: 목적지와 현재위치 사이 거리를 계산하여 사용자에게 보여주는 기능 구현 * feat: Coordinate를 받아 해당 위치에 좌표를 찍는 기능 구현 (#39) - 목적지를 임시로 상수처리 - 추후 목적지를 서버에서 받아 마커를 찍는 방식으로 수정 필요 * feat: 사진 버튼을 클릭하면 사진 다이얼로그를 띄우는 기능 구현 (#40) * design: close icon 추가 * feat: 화면에 관련된 유틸 파일과 메서드 생성 * design: OnAdventure 액티비티에서 사진을 보여주기 위한 다이얼로그 UI 구현 * feat: 목적지에 대한 사진을 띄워주는 DestinationPhotoDialog 구현 * refactor: LocationDialogFragment의 메서드를 DisplayUtil로 분리 * style: 코드 정렬 * feat: 생성시 액티비티로부터 사진을 받아오는 기능 구현 * design: 사진 아이콘 버튼 추가 * feat: 액티비티에서 사진 아이콘 버튼 클릭시 다이얼로그를 띄우는 로직 구현 * feat: 사진이 로딩중 문구 strings 리소스화 * feat: 뷰모델로부터 얻어온 사진을 넘기도록 로직 수정 * refactor: 다이얼로그 및 변수 네이밍 변경 * refactor: strings 리소스화 * refactor: 객체 네이밍 변경 * feat: 목적지에 도착 시 도착 버튼 활성화 기능 구현 (#41) * design: 비활성화 버튼 color resource 추가 * design: 버튼의 상태에 따라 버튼 UI가 변경 되는 selector 생성 * feat: 목적지 도달 시 모험 종료 버튼 활성화 기능 추가 * refactor: 기존에 있는 drawable 활용해 selector 생성 * refactor: 도착 버튼 string을 resource에 추가 * refactor: API 명세 변경으로 인한 기능 수정 (#43) * refactor: 조회 쿼리의 결과를 List로 받도록 수정 * feat: 인증 관련 예외 기능 추가 * feat: 게임 관련 예외 기능 추가 * feat: 장소 관련 예외 기능 추가 * feat: 회원 관련 예외 기능 추가 * feat: 수정된 API 명세에 맞춰 게임 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 게임 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 장소 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 회원 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 게임 서비스 로직 수정 * feat: 게임에 대한 응답 DTO 생성 * feat: 수정된 API 명세에 맞게 컨트롤러 수정 * feat: 수정된 API 명세에 맞게 컨트롤러 수정 * style: import문 최적화 * refactor: 기존 런타임 예외를 인증 커스텀 예외로 수정 * refactor: 사용하지 않은 메서드 삭제 * refactor: 상수 이름 변경 * refactor: final 키워드 추가 * refactor: @Transactional 어노테이션에 readOnly 속성 추가 * refactor: 패키지 수정 --------- Co-authored-by: kokodak * feat: 서버통신 초기세팅 (#44) * feat: Adventure 도메인 클래스 생성 * feat: Adventure 상태를 갖는 enum 클래스 생성 * feat: 기능 변경에 따른 repository 변경 * chore: 사진 다이얼로그 패키지 위치 변경 * feat: AdventureDto 클래스 생성 * feat: Dto와 domain 클래스간의 mapper 구현 * refactor: repository 이름 변경 * feat: repository 기능 변경으로 인한 mock repository 변경 * feat: retrofit service 인터페이스 생성 * feat: adventure ERROR 상태 클래스 추가 * feat: Repository 변경에 따른 ViewModel 변경 및 서버 통신 오류 처리 * feat: Retrofit 객체 생성 및 interceptor 구현 * chore: AdventureService 패키지 위치 변경 * feat: 목적지 도착 여부 확인 기능 구현 (#47) * feat: 좌표사이의 거리를 키로미터로 계산하는 로직 구현 * feat: 도착여부 판단 및 접근 권한 검증 기능 구현 * feat: 장소의 유효범위 여부 검증 구현 * feat: 게임 종료기능 api 구현 * refactor: 게임 관련 예외를 사용하도록 변경 * refactor: 인증 관련 예외 추가 및 적용 * style: final 키워드 추가 및 코드 정렬 * fix: 파라미터명 수정 * feat: 백엔드 ci workflows 초안 작성 (#49) * chore: step 이름 추가 (#50) * [BE] fix: 백엔드 ci workflows 초안 작성 (#51) * chore: step 이름 추가 * fix: default working directory 추가 * fix: working directory 상대경로로 변경 (#52) * chore: step 이름 추가 * fix: default working directory 추가 * fix: working directory 상대경로로 변경 * feat: 서버에 모험 시작을 요청하는 기능 구현 (#48) * refactor: AdventureRepository 수정 * feat: Coordinate 객체의 Domain to Dto 매핑 함수 생성 * feat: Result의 failure에서 사용할 나아가 팀만의 Throwable 생성 * feat: 서버통신이 성공적이지 않을 때에 대한 객체와 서버통신 코드를 단순화할 메서드 생성 * feat: AdventureRepository의 beginAdventure 함수 구현 * refactor: 코드 방식 변경 get() -> [] * feat: MockRepository의 beginAdventure 함수 구현 * refactor: 타입을 표현해줌 * feat: 실제 base url 등록 * feat: http 통신 허용 * fix: json 변환 과정 수정 * fix: TODO 주석처리 * feat: 코루틴 의존성 추가 * feat: 모험을 시작하는 서버통신 구현 * feat: 모험이 끝났을 때 서버에게 모험이 종료 됐음을 알려주는 기능 구현 (#53) * feat: 모험 종료 시 서버에게 데이터를 받아 올 Dto 생성 * feat: 모험 종료 시 서버에게 받아 온 Dto mapper 생성 * refactor: 데이터 반환 값 타입 변경 * feat: AdventureRepository의 endAdventure 구현 * feat: 모험 종료 시 서버와 통신해 현재 모험 상태를 받아온 후 상황에 맞게 분기 처리 해주는 기능 구현 * refactor: mock Repository의 endAdventure 함수 구현 * fix: onClick에서 사용된 함수에게 인자를 넣어 Databinding 오류 해결 * feat: 서버에서 목적지를 받아오는 기능 구현 (#54) * refactor: 게임 정보를 가져오는 서비스 수정 * feat: 서버에서 목적지를 받아오는 기능 구현 * fix: 목적지 도착 버튼 클릭 시 발생하는 오류 수정 (#56) * fix: RetrofitService Path 수정 * fix: Serializable 어노테이션 추가 * refactor: iteration 명칭 변경 및 타입 명시 제거 * feat: 안드로이드 프로젝트에 firebase 추가 (#75) * feat: 필요 없는 파일 삭제 잘못 올린 파일을 삭제합니다. * chore: gitignore 수정 (#78) * feat: 안드로이드 CI 자동화 (#77) * chore: ktlint를 위한 config 파일 추가 * chore: ci 자동화를 위한 yml 파일 추가 * style: ktlint에 걸린 코드 정렬 * chore: ci 자동화 json 파일 추가 * style: ktlint에 걸린 코드 정렬 * style: ktlint에 걸린 코드 정렬 * chore: ci 자동화 json 파일 추가 * style: ktlint에 걸린 코드 정렬 * style: ktlint에 걸린 코드 정렬 * chore: ci 자동화 파일 수정 * style: ktlint 규칙 변경에 따른 수정 * feat: 스플래시 화면에서 진행 중인 모험이 있는지 판단하고 분기 하는 기능 구현 (#58) * chore: apk 및 aab 추출을 위한 파일 * design: splash를 위한 스타일 생성 * feat: 레포지토리에 모험 상태를 통해 모험 목록을 받아오는 기능 추가 * feat: 모험 상태를 통해 모험목록을 받아오는 retrofit 인터페이스 작성 * feat: 모험 상태를 통해 모험 목록을 반환하는 레포지토리 기능 구현 * feat: 이전 액티비티로부터 OnAdventureActivity로 화면을 전환할때 필요한 인텐트를 반환하는 함수 작성 * feat: 스플래시 액티비티와 뷰모델(및 팩토리) 생성 - 스플래시에서 서버통신을 통해 현재 진행 중인 모험이 있는지 확인한다. - 현재 진행 중인 모험이 있다면 해당 모험과 함께 OnAdventureActivity로 이동한다. - 현재 진행 중인 게임이 없다면 BeginAdventureActivity로 이동한다. * feat: 화면간 데이터 이동을 위한 uiModel 생성 - gradle에 parcelize 플러그인 추가 - AdventureUiModel 및 Mapper 생성 - CoordinateUiModel 및 Mapper 생성 - DestinationUiModel 및 Mapper 생성 * feat: parcelable한 데이터를 인텐트로부터 받기 쉽게할 유틸 함수 작성 * feat: OnAdventureActivity가 열리는 두 가지 경우에 따라 모험을 지정 - 이미 모험이 진행 중이면 이전 화면으로부터 모험을 전달 받고 모험을 서버에 요청하지 않는다. - 진행 중인 모험이 없다면 서버로부터 모험을 요청한다. * refactor: OnAdventureActivity에서 Intent를 생성해주므로 해당 함수를 이용하도록 변경 * [AN] feat: registerForActivityResult 분기처리 기능 구현 (#72) * design: 대락적인 위치 권한만 허용됐을 시 보여줄 문구 string 리소스로 추가 * feat: Dialog 내에서 권한을 체크하여 대략적인 위치 권한이 있는 상태와 전혀 없는 상태를 구분하여 다른 문구를 보여주도록 구현 * feat: BeginAdventureActivity 권한 코드 수정 - 유저가 권한 요청을 허용 및 거절 했을 시 토스트 메시지로 즉각적인 피드백을 주도록 구현 - 함수 분리 - 다이얼로그 태그 상수화 * feat: BeginAdeventureActivity UI 변경사항 적용 (#71) * design: 랭크, 마이페이지, 업로드 아이콘 추가 * design: 기존의 background를 지정하고 tint로 색을 지정하는 방식은 elevation을 반영하지 못해 색이 있는 shape을 새로 생성함 * design: BeginAdventureActivity에서 사용될 style 생성 * design: BeginAdventureActivity xml 레이아웃 작성 * feat: AdventureResultActivity 구현 (#80) * design: 모험 결과 상태에 따른 스탬프 drawable 리소스 추가 * design: 모험 결과 페이지에 필요한 strings 리소스 추가 * feat: 모험 결과에 따라 다른 UI가 띄워지는 액티비티 구현 * fix: manifest 오류 수정 * feat: 3차 데모데이 엔티티 설계 (#84) * feat: BaseEntity 생성 * feat: Player 도메인 생성 * feat: Hint 도메인 생성 Co-authored-by: dooboocookie * feat: GameResult 도메인 생성 Co-authored-by: dooboocookie * style: import문 최적화 Co-authored-by: dooboocookie * feat: 스프링 부트 어플리케이션에 @EnableJpaAuditing 추가 Co-authored-by: dooboocookie * refactor: 게임 도메인 수정 Co-authored-by: dooboocookie * refactor: 장소 도메인 생성 Co-authored-by: dooboocookie * refactor: Score 도메인 생성 Co-authored-by: dooboocookie * refactor: Place에 BaseEntity 상속 추가 * refactor: Member에 BaseEntity 상속 추가 및 생성자 추가 --------- Co-authored-by: dooboocookie * feat: OnAdventureActivity UI 변경사항 적용 (#73) * design: OnAdventureActivity에서 사용하는 아이콘 추가 * rename: drawable 컨벤션 유지 * design: 색상 추가 * design: 원 형태의 백그라운드 추가 * design: 문구 변경 * feat: OnAdventureActivity UI 변경사항 적용 * feat: 서버로부터 받아온 목적지에 핀을 꽂는 기능 제거 * rename: 일관성을 위한 아이콘 이름 수정 * design: 하단 버튼 높이 통일 * design: 흰색 배경 drawable 생성 * design: 버튼 그림자 생성 * feat: 충돌 해결 * feat: 충돌 해결 * feat: 충돌해결 * [AN] feat: UploadActivity 구현 * chore: gitignore 수정 * design: 카메라, 좌표 아이콘 추가 * design: 출력 문구 추가 * design: 마진 사이즈 추가 * feat: UploadActivity 구현 * feat: UploadActivity의 인텐트를 가져오는 함수 구현 * chore: string.xml 변수명 변경 * refactor: 사진이 들어갈 이미지뷰와 카메라 아이콘을 분리 * feat: 카메라 권한 요청 기능 구현 (#92) * design: 카메라 권한 관련 아이콘 추가 * feat: 카메라 권한 추가 * feat: dataBinding 사용하도록 xml 변경 * feat: 카메라 위치권한을 요구하는 다이얼로그 생성 * feat: 카메라 권한이 없는 경우 권한 요청 다이얼로그를 띄우는 기능 구현 * chore: 레이아웃 id 컨벤션 유지 * refactor: 다이얼로그의 tag를 다이얼로그 클래스에 위치하도록 통일 * refactor: 매직넘버 상수화 * rename: drawable 파일명 변경 * feat: 명세서 기준으로 Dto들 생성 (#89) * feat: 명세서 기준으로 Dto들 생성 * feat: 변경된 API 명세에 맞춰 Dto 변경 * feat: 디바이스의 위치를 받아와 뷰에 보여주는 기능 구현 (#93) * feat: 디바이스의 위치를 받아와 뷰에 보여주는 기능 구현 * refactor: 좌표를 문자열로 반환하는 기능 함수분리 * feat: 도메인 모델 생성 (#91) * refactor: ERROR를 NONE으로네이밍 변경 * feat: 도메인 객체 생성 (미완) * feat: 도메인 객체 수정 및 추가 생성 * feat: 도메인 수정 * rename: 패키지명 수정 * feat: 통계 path 레트로핏 서비스 구현 #101 * feat: 서버에서 Rank 관련 데이터를 받아올 때 사용될 service 생성 (#100) * feat: 3차 데모데이용 Game Path 레트로핏 서비스 생성 (#102) * feat: 장소 path 레트로핏 서비스 구현 (#103) * feat: AdventureHistoryActivity 구현 (#106) * design: AdventureHistory 뷰에 필요한 string resource 추가 * design: AdventureHistory 뷰에 필요한 drawable resource 추가 * design: 리사이클러뷰에 들어갈 Item 레이아웃 생성 * feat: 모험 기록을 보여 주는 리사이클러뷰 어댑터 생성 * feat: AdventureHistory 액티비티 구현 * feat: AdventureHistoryActivity에 모험 기록을 보여줄 리사이클러뷰 구현 * feat: 뒤로가기 버튼 구현 * refactor: 함수 이름 변경 * refactor: 이름이 길어질 때 줄여쓰기가 되도록 기능 추가 * refactor: Mock 데이터 생성 방법 수정 * refactor: 불필요한 함수 인자 삭제 * feat: RankRepository 생성 (#109) * refactor: Service 명 수정 * feat: RankRepository Interface 구현 * feat: PlayerDto를 도메인 객체로 바꿔주는 도메인 mapper 생성 * feat: RankDto를 도메인 객체로 바꿔주는 도메인 mapper 생성 * feat: 서버와 Rank 데이터를 주고 받기 위해 팔요한 rank service 객체 생성 * feat: RankRepository 구현체 생성 * refactor: 함수 인자 표시 * feat: StatisticsRepository 생성 (#110) * rename: 파일명 수정 * feat: StatisticsRepository 인터페이스 생성 * feat: 서버와의 Statistics 관련 통신을 위한 service 객체 생성 * feat: StatisticsDto 객체를 도메인 객체로 바꿔주는 Mapper 생성 * feat: StatisticsRepository 구현체 생성 * refactor: 함수 인자 표시 * feat: 3차 데모데이 기획 변경에 맞는 AdventureRepository 설계 및 구현 (#111) * feat: 3차 데모데이 기획 변경에 맞는 AdventureRepository 설계 및 구현 * chore: 잘못 위치한 파일 위치 변경 * feat: PlaceRepository 생성 (#118) * feat: 장소 repository interface 생성 * feat: 서비스풀에 장소 서비스 추가 * feat: place mapper 생성 * feat: 장소 repository 구현체 생성 * refactor: 오류처리 변경에 따른 repository 코드 수정 * feat: 통계 path api 목서버 구현 (#116) * feat: 랭크 path api 목서버 구현 (#117) * feat: 랭크 path api 목서버 구현 * feat: 필요없는 변수 변환 로직 제거 * feat: RankActivity 구현 (#119) * feat: RankActivity 생성 * feat: RankActivity의 Intent를 생성해주는 함수 구현 * feat: 내 순위 및 전체 순위 목 데이터를 라이브 데이터 값으로 넣어주는 기능 구현 * design: RankActivity에 필요한 string resource 추가 * design: 내 순위 및 전체 순위를 보여주는 뷰 구현 * feat: 전체 순위를 띄워줄 리사이클러뷰 생성 및 구현 * feat: LiveData를 이용해 리사이클러뷰에 리스트 전달 * feat: 창 닫기 버튼 추가 구현 * refactor: Manifest 내의 rankActivity 위치 이동 * refactor: 컨벤션에 맞게 id 변경 * design: elevation을 활용해 그림자 추가 * refactor: dimens 적용 * refactor: 그림자 적용 * feat: 카메라로 찍은 사진을 뷰에 띄우고 Uri 추출기능 구현 (#120) * feat: 촬영한 사진을 이미지뷰에 보여주는 기능 구현 * feat: 촬영한 사진의 Uri 추출 기능 구현 * refactor: 권한 요청 로직 수정 및 함수 위치 변경 - 업로드 화면으로 이동 시 시스템 권한 요구 상자 팝업(카메라, 위치) - 거절한 권한에 대해 권한요청 다이얼로그 프래그먼트 팝업 * feat: 좌표 이미지를 클릭하여 좌표를 받아 보여주는 기능 구현 * feat: 닫기 버튼 추가 * feat: 3차 데모데이 뼈대 코드 추가 (#130) * refactor: AuthInterceptor에서 인증처리만 하도록 변경 * feat: PlayerException 추가 * feat: Player를 MemberId로 조회하는 기능 추가 * refactor: 로그인 된 PlayerId를 받는 ArgumentResolver 구현 * refactor: PlayerService 적용 refactor: Request DTO 와 Command DTO 분리 * feat: MyPageActivity 구현 (#121) * refactor: ERROR를 NONE으로네이밍 변경 * feat: 도메인 객체 생성 (미완) * feat: 도메인 객체 수정 및 추가 생성 * feat: 인터넷 권한 추가 * feat: 마이페이지의 아이템에 필요한 리사이클러뷰 구현 * feat: 마이페이지에 재사용이 여러번 될 가능성이 있는 뷰를 커스텀 뷰로 제작 * feat: 마이페이지 액티비티 생성 * style: 개행 * feat: 마이페이지 아이템의 두가지 경우의 레이아웃을 따로 제작 * feat: 레이아웃이 두개로 나눠짐에 따라 어댑터 수정중 * feat: 마이페이지 커스텀 아이템 레이아웃 수정 * feat: 마이페이지 커스텀 아이템 내부 리사이클러뷰 구현 방식 변경 (멀티 뷰홀더 적용) * feat: 마이페이지 뷰 구현 * feat: 도메인 모델을 UI모델로 변경할 매퍼 함수 생성 * design: mypage 레이아웃 디자인 변경 * feat: 뒤로가기 클릭리스너 추가 * remove: 중복된 객체 삭제 * refactor: view의 id 수정 * feat: Statistics 도메인 객체 수정으로 인해 자료형 변환 로직 추가 * fix: BaseEntity에 맞춘 data.sql 수정 (#133) * [BE] refactor: Pull Request 워크플로우 수정 (#134) * refactor: DTO들이 모두 record로 구현되도록 수정 (#136) * refactor: Pull Request 워크플로우 재수정 * feat: merge 워크 플로우 추가 (#137) * [BE] feat: merge 워크 플로우 추가 * [BE] refactor: merge 워크플로우 수정 * [BE] feat: 도커파일 생성 * [BE] refactor: 도커파일 이름 수정 * [BE] refactor: merge 워크플로우 재수정 * refactor: merge 워크 플로우 추가 (#139) * feat: merge 워크 플로우 추가 --------- Co-authored-by: zillionme <100172683+zillionme@users.noreply.github.com> Co-authored-by: dooboocookie <79090478+dooboocookie@users.noreply.github.com> * feat: 랭크 조회 기능 구현 (#94) * feat: 맴버 아이디로 플레이어 찾는 기능 구현 * feat: RankResponse dto 구현 * feat: RankResponse 정적팩토리 생성자 구현 * feat: 전체 랭크 조회 기능 구현 * feat: 나의 랭크 조회 기능 구현 * refactor: 요청 파라미터 예외 설정 * test: 테스트코드 추가 * refactor: 예외처리 로직 수정 * refactor: json 명세 수정으로 인한 dto 수정 * refactor: players 도메인을 삭제하고 Rank도메인으로 리팩토링 * refactor: 변수명 수정 * test: 테스트 오류 수정 * style: 디버깅 삭제 * feat: 랭크 뷰 기능 구현 및 서버 통신 구현 (#138) * remove: 필요없는 목 서버 삭제 * feat: 인자가 있는 ViewModel 생성을 위해 ViewModelFactory 생성 * feat: RankDto에 Serializable을 달아주어 직렬화가 가능하도록 구현 * refactor: 불필요한 null 검증 로직 제거 * feat: 서버와 통신해 전체 랭크와 내 랭크 정보를 받아온 후 사용자에게 보여주는 기능 구현 * feat: 서버 통신을 실패해 데이터를 불러오지 못했을 때 메시지를 띄운 후 창이 닫히도록 구현 * refactor: Retrofit Builder에 목서버 url로 갈아끼움 * refactor: 서버 통신 실패 시 에러 처리 로직 함수 분리 * feat: 시작 화면에서 랭크 버튼 클릭 시 랭크 화면으로 이동하도록 구현 * refactor: 함수 이름 변경 * refactor: 리사이클러뷰 애니메이터 설정 변경 * refactor: 내 등수 단위 표시 string 추가 * refactor: ktlint 적용 * refactor: 랭킹 관련 레트로핏 서비스의 path 변경 * feat: 게임 결과 뷰 서버 통신 및 기능 구현 (#143) * feat: gameId 값을 받아오는 intent * feat: 뷰모델에 인자로 레포지터리를 넘겨주기 위해 뷰모델 팩토리 생성 * refactor: RankDto에 Serializable을 달아주어 직렬화가 가능하도록 구현 * design: 게임 결과 화면에 필요한 string resource 추가 * refactor: 목 서버와의 연결을 위해 baseUrl 변경 * refactor: 랭크 API 통신을 위해 ViewModel에 RankRepository 인자 추가 * feat: 서버와 통신해 게임 결과를 받아온 후 사용자에게 보여주는 기능 구현 * feat: 서버와 통신해 내 랭크를 받아온 후 사용자에게 보여주는 기능 구현 * feat: 총 플레이 시간을 포매팅해서 보여주는 기능 구현 * feat: 메인으로 돌아가기 버튼을 누를 시 메인으로 돌아가게 하는 기능 구현 * refactor: timeFormatter의 패턴 상수화 처리 * refactor: 불필요한 Log 삭제 * design: color resource 추가 * refactor: 함수 분리 * refactor: 뷰 간격 조절 * feat: 서버에서 받아 온 imageUrl을 Glide를 사용해 이미지로 띄워주는 기능 구현 * design: 버튼 크기 조절 * feat: 모험 결과 DTO와 도메인 객체의 raisedRank 삭제 * feat: 랭크 변동 상황을 알려주는 뷰 삭제 * feat: 인자 변경에 따른 수정 사항 적용 * feat: 모험 기록 뷰 기능 구현 및 서버 통신 구현 (#151) * design: 모험 기록 뷰 디자인 변경 * design: 모험 기록 뷰 리사이클러뷰 아이템 디자인 변경 * refactor: 뷰 생성 위치 변경, 함수명 변경 * feat: 아이템에 사진 넣는 로직 추가 * feat: 뷰모델 팩토리 생성, 로컬 목데이터에서 가져오던 데이터를 서버로부터 가져오도록 변경 * feat: manifest exported 변경 * feat: 이미지 뷰 corner radius 적용 * design: 색상 변경 및 그림자 적용 * design: 마진값 변경 * [AN] feat: MyPage 기능 구현 (#146) * feat: 게임 결과 조회 기능 구현 (#152) * feat: 게임 아이디를 통해 게임결과를 조회한다 * feat: 결과 반환을 위한 responseDTO 생성 * refactor: 게임 결과를 위한 도메인 수정 * feat: 게임 결과 반환 기능 구현 완료 * style: 코드 컨벤션에 맞게 수정 * style: 코드 컨벤션에 맞게 수정 * refactor: 게임 도메인의 오류 리팩토링 * refactor: final 추가 * refactor: 게임 전체 결과 가져오는 로직 수정 * feat: 게임 종료 API 및 게임 조회 테스트 구현 (#147) * test: 게임 종료 기능 테스트 * feat: 게임 종료 기능 기본 구조 추가 * feat: 게임 종료 기능 구현 * test: 게임 점수 계산 기능 테스트 * feat: 게임 점수 계산 기능 구현 * test: 게임 점수 계산 테스트 수정 * test: 게임 종료 및 게임 결과 저장 서비스 테스트 * feat: 게임 종료 서비스 및 dto 구현 * test: 게임 종료 api 테스트 * feat: 게임 종료 api 구현 * test: 게임 종료 api 테스트 수정 * test: sql파일 수정 및 게임 종료 api 테스트 추가 * feat: 모험 결과 DTO와 도메인 객체의 raisedRank 삭제 * feat: 랭크 변동 상황을 알려주는 뷰 삭제 * feat: 인자 변경에 따른 수정 사항 적용 * test: 게임 종료 api 예외 처리 테스트 추가 * refactor: Game 클래스 필요없는 메서드 제거 및 리팩터링 * feat: 모험 기록 뷰 기능 구현 및 서버 통신 구현 (#151) * design: 모험 기록 뷰 디자인 변경 * design: 모험 기록 뷰 리사이클러뷰 아이템 디자인 변경 * refactor: 뷰 생성 위치 변경, 함수명 변경 * feat: 아이템에 사진 넣는 로직 추가 * feat: 뷰모델 팩토리 생성, 로컬 목데이터에서 가져오던 데이터를 서버로부터 가져오도록 변경 * feat: manifest exported 변경 * feat: 이미지 뷰 corner radius 적용 * design: 색상 변경 및 그림자 적용 * design: 마진값 변경 * [AN] feat: MyPage 기능 구현 (#146) * feat: 게임 결과 조회 기능 구현 (#152) * feat: 게임 아이디를 통해 게임결과를 조회한다 * feat: 결과 반환을 위한 responseDTO 생성 * refactor: 게임 결과를 위한 도메인 수정 * feat: 게임 결과 반환 기능 구현 완료 * style: 코드 컨벤션에 맞게 수정 * style: 코드 컨벤션에 맞게 수정 * refactor: 게임 도메인의 오류 리팩토링 * refactor: final 추가 * refactor: 게임 전체 결과 가져오는 로직 수정 * refactor: 테스트 fixture 클래스 생성 * refactor: 테스트 fixture 적용 * fix: 레포지토리 테스트 truncate.sql 추가 * fix: 서비스 테스트 트랜잭션 추가 * test: 게임 식별자로 게임 조회 테스트 추가 * chore: 식별자로 게임 조회 메서드명 변경 * chore: 머지 컨플릭트 해결 --------- Co-authored-by: hyunji1203 Co-authored-by: k_dragonm <78788847+briandr97@users.noreply.github.com> Co-authored-by: krrong Co-authored-by: chaewon121 <80631952+chaewon121@users.noreply.github.com> * feat: 장소 등록 api 구현 * feat: BaseEntity 생성 * feat: Player 도메인 생성 * feat: Hint 도메인 생성 Co-authored-by: dooboocookie * feat: GameResult 도메인 생성 Co-authored-by: dooboocookie * style: import문 최적화 Co-authored-by: dooboocookie * feat: 스프링 부트 어플리케이션에 @EnableJpaAuditing 추가 Co-authored-by: dooboocookie * refactor: 게임 도메인 수정 Co-authored-by: dooboocookie * refactor: 장소 도메인 생성 Co-authored-by: dooboocookie * refactor: Score 도메인 생성 Co-authored-by: dooboocookie * refactor: Place에 BaseEntity 상속 추가 * refactor: Member에 BaseEntity 상속 추가 및 생성자 추가 * test: 장소를 주가하는 기능 tdd test: 테스트에서 사용되는 값 fixture 생성 * feat: 장소 저장하는 기능 구현 * feat: 장소 저장하는 기능 구현 * feat: places 응답 DTO 추가 * test: 장소 생성 API E2E 테스트 추가 feat: 장소 생성 API 구현 * refactor: PlaceCheckService 도메인 서비스 생성 refactor: MultipartFileManager 파일 저장기 생성 * feat: 임시 커밋 * refactor: File 저장 경로 profile에서 변수로 관리하도록 변경 * feat: Place 전체 조회 기능 추가 - 정렬 기능 * feat: Place 단건 조회 기능 추가 * feat: Place 추천 서비스 도메인 서비스로 분리 * feat: Place 생성 서비스 로직 매개변수로 CreatePlaceCommand 받도록 수정 * refacotr: 파일 저장 경로 application.properties에서 받도록 수정 * test: Fixture 수정 및 테스트 수정 * test: 장소 추가 API 테스트 추가 test: 장소 추가 API 예외 테스트 추가 test: 아이디 장소 조회 API 테스트 추가 test: 장소 조회 API 테스트 추가 * test: 테스트 수정 * chore: 충돌 해결 --------- Co-authored-by: kokodak * chore: 안드로이드 CI workflow 수정 * feat: 힌트 생성 API 설계 및 구현 (#142) * feat: 위경도 좌표를 통해 방향을 계산하는 기능 구현 * feat: memberId 로 Member 를 찾는 기능 구현 * feat: PlayerService 생성 * feat: 힌트 생성에 대한 Command DTO 생성 * feat: 힌트 결과에 대한 DTO 생성 * feat: 힌트에 대한 Service 생성 * feat: 게임에서 힌트를 더 사용할 수 있는지에 대한 판단 기능 구현 * feat: 힌트 생성에 대한 Request DTO 생성 * feat: 힌트 생성에 대한 Command DTO 생성 * feat: 힌트 개수에 따른 생성 제약 조건 및 예외 추가 * feat: GameController 에 힌트 생성 API 로직 구현 * fix: 힌트 최대 사용 개수 수정 * refactor: 게임 최대 시도 횟수를 상수로 추출 * test: 로컬 테스트 환경 설정 * feat: cascade 조건 추가 * test: 더미데이터를 담은 테스트용 fixture 생성 * test: 힌트 생성 기능에 대한 테스트 작성 * chore: RestAssured 의존성 추가 * fix: Game 에서의 cascade 적용 철회 및 테스트 일부 수정 * test: 힌트 생성 API 테스트 코드 작성 * style: 코드 정렬 * feat: 특정 게임의 힌트 단건 조회 API 설계 및 구현 (#157) * feat: 힌트 조회 Command DTO 생성 * feat: 힌트 관련 예외 추가 * refactor: MemberFixture 에서 매직넘버를 상수로 추출 * feat: 힌트 id를 통해 힌트를 조회하는 기능 구현 * feat: 힌트 id를 통한 힌트 조회 API 구현 refactor: HintResponse 구조 수정 remove: DirectionResponse 삭제 * chore: 병합 충돌 해결 * style: 코드 정렬 * feat: 인게임 화면 기능 및 서버통신 구현 (#149) * feat: OnAdventure의 기능목록 작성 * feat: 분리된 Factory 클래스 삭제. ViewModle의 동반객체로 이동 * feat: 기능 개발중.. 임시 커밋 * feat: 라이브데이터를 상황에 맞게 커스텀 하려고 시도중 * feat: 도메인이 추가 및 변경됨에 따라 UiModel과 Mapper를 생성 * feat: Place 도메인 기능 추가 * feat: 인게임 화면에서 필요한 상태 및 로직들을 뷰모델에 작성 * feat: 네이버맵에 대한 코드로 인해 액티비티가 너무 길어져 액티비티 코드를 줄이기 위해 분리를 시도중 * style: 아이콘 추가 * feat: 목서버 base url 적용 * feat: 라이브데이터로부터 옵저버가 처음 한번만 notify를 받을 수 있는 라이브데이터 생성 * design: 아이콘 추가 * feat: Positive 버튼과 Negative 버튼이 존재하는 다이얼로그를 재사용할 수 있도록 생성 및 포기하기, 힌트 사용하기 다이얼로그 빌더 함수 생성 * feat: OnAdventureActivity에서 네이버맵 관련 작업을 분리한 코드 작성 - 힌트 마커 추가 - 목적지 마커 추가 - 네이버 로고 위치 조정 - 나침반 위치 조정 - 내 위치 버튼 위치 조정 * feat: OnAdventureViewmodel 재구현 * feat: Dto에 빠진 Serializable 어노테이션 추가 * feat: 뷰모델 변경으로 인해 데이터바인딩 수정 * design: string resources 추가 * feat: OnAdventureActivity 기능 구현 - 오류 처리 - 서버 통신(목서버) - 다이얼로그 띄우기 * feat: adventureRepository 변경으로 인한 수정 * feat: 뷰모델 팩토리 위치 변경 * feat: 도메인 변경으로 인한 코드 수정 * style: 매니페스트 정리 * refactor: NaagaAlertDialog 개선. 버튼 클릭 이벤트를 다이얼로그 생성시 무조건 받도록 수정함 * feat: AdventureResultActivity를 생성하는 인텐트를 받아오는 방식 변경 및 adventureId를 함께 넘겨줌 * chore: 백엔드 CD 워크플로우 수정 --------- Co-authored-by: zillionme <100172683+zillionme@users.noreply.github.com> * feat: 점진적 리팩토링이 완료됨에 따라 파일 정리 (#156) * refactor: 기존에 사용하던 Adventure 도메인 객체와 AdventureRepository가 완전히 대체되었으므로 삭제하고 새로 생성한 객체들의 임시 네이밍을 변경 * docs: 기능 구현이 완료되었으므로 기능 목록을 제거한다. * refactor: 도메인의 점진적 리팩토링이 완료됨에 따라 UiModel과 Mapper 또한 사용되지 않는 것들을 삭제하고 임시 네이밍을 변경했습니다. * refactor: 점진적 리팩토링이 완료됨에 따라 사용되지 않는 dto들을 삭제하고 패키지 구조를 변경 * refactor: dto와 도메인이 변경됨에 따라 Mapper가 변경됨 * refactor: 서비스 인터페이스와 서비스 풀에서 더 이상 사용하지 않는 파일 삭제 및 dto 변경으로 인한 변경 * refactor: 점진적 리팩토링이 완료됨에 따라 사용하지 않는 레포지토리 구현체 삭제 * rename: repository 네이밍 변경으로 인한 수정 * refactor: 도메인 변경으로 인한 스플래시 변경 및 기능 개선 * rename: 도메인 변경으로 인한 변경 * rename: adventureRepository와 그 구현체 네이밍 변경으로 인한 수정 * feat: 통계 조회 기능 구현 (#159) * feat: Statistic 반환dto 생성 * feat: Statistic 도메인 생성 및 계산로직 구현 * feat: 나의 통계 조회 기능 구현 완료 * fix: 시간계산 오류 수정 * test: @Sql조건 수정 * refactor: 총 플레이 시간과 게임 시간 값 수정 * fix: 인터셉터 패턴 추가 (#161) * feat: 게임 시작 화면 기능 구현 (#162) * design: BeginAdventureActivity에 필요한 string resource 추가 * refactor: 이동할 뷰에게 getIntent 함수를 이용해 intent 생성 * fix: Splash 화면에서 바로 인게임 화면으로 넘어가는 오류 수정 * feat: 메뉴를 누르면 해당 화면으로 이동하도록 구현 * refactor: 게임 결과 화면이 자신의 Intent를 생성하도록 수정 * refactor: ktlint 적용 * feat: 게임 생성 로직 수정 (#166) * fix: 잘못된 인덱스 로직 수정 * feat: Location 헤더로부터 id를 추출하는 기능 구현 * refactor: 매직넘버를 상수로 대체 * feat: 3차 데모데이 API 명세에 맞추어 응답 DTO 필드 추가 * test: 게임 생성 API 테스트 작성 * chore: 서브 모듈 설정 추가 * feat: firebase crashlytic 초기 환경 설정 (#170) * feat: FirebaseAnalytics 생성 및 로그 삽입을 담당할 객체 생성 및 상수 모음 파일 생성 (#171) * fix: application 파일 복구 (#174) * chore: 더미 데이터 추가 (#176) * feat: API 수정으로 인한 변경사항 적용 (#177) * feat: 명세서 변경으로 인해 dto 변경 * feat: 도메인 객체의 타입 변경 * feat: 받아올 값의 타입과 보여줄 뷰의 형태 변화를 반영한 코드 수정 * design: 제약 변경, 보여줄 데이터의 단위 추가 * feat: 목데이터를 실제 값으로 변경 * feat: 인텐트 값을 받아오는 것의 예외 상황에 대한 처리 * refactor: RankReponse 수정 (#179) * refactor: 변수명 수정 * refactor: 변수명 수정 * feat: baseUrl 변경 및 감추기와 그에 따른 yml 파일 변경 (#182) * feat: baseUrl이 노출되지 않도록 하며 github secret으로부터 가져올 수 있도록 yml 파일 수정 * feat: local.properties로부터 baseUrl을 가져올 수 있도록 변경 * feat: baseUrl을 BuildConfig로부터 가져올 수 있도록 변경 * ci 파일 1차 수정 * ci 파일 2차 수정 * ci 파일 3차 수정 * ci 파일 4차 수정 * refactor: 쿼리와 uri 수정 (#184) * refactor: 변수명 수정 * refactor: 변수명 수정 * refactor: 변수명 수정 * fix: uri 쿼리파라미터 오류 수정 * feat: 업로드 뷰 기능 구현 (#181) * feat: 제목, 설명을 입력받는 기능 구현 * feat: 촬영한 사진의 uri를 뷰모델에 저장 * feat: 모든 정보가 입력되지 않은 경우 전송하지 못하도록 하는 기능 구현 * refactor: 함수명 수정 * feat: 좌표 확장함수 생성 및 전송 기능 수정 - 필요한 정보가 하나라도 입력되지 않은 경우 정보를 입력해달라는 토스트 메시지 출력 - ViewModel에 좌표를 전달하고, 뷰에 좌표를 출력하기 위해 원하는 형태의 text로 변환하는 확장함수 생성 * feat: post 시 필요한 데이터를 파트로 분리 * feat: ViewModel 생성에 필용한 팩토리 추가 * feat: place 등록 기능 구현 * feat: viewModel 생성방법 변경 및 등록 버튼 리스너 연결 * fix: GET /games 쿼리 스트링 없어도 되도록 수정 (#187) * fix: 게임 전체 조회 기능 수정 * fix: 게임 전체 조회 기능 재수정 * fix: 랭크 전체조회 쿼리 파라미터 조건 수정 (#191) * fix: 장소데이터 추가 및 인터셉터 설정 변경 * refactor: 컨트롤러 요청 수정 (#193) * fix: POST /games/{gameId}/hints 쿼리 스트링 없어도 되도록 수정 (#195) * fix: 힌트 생성 api * fix: 힌트 생성 api 재수정 * feat: 게임 종료 시, 플레이어 점수 덧셈 기능 추가 (#198) * feat: 게임 종료 시, 플레이어 점수 덧셈 기능 추가 * refactor: 게임 결과 거리 조회 수정 * feat: Firebase Analytics 버튼 클릭 로그 추가 (#183) * feat: view id를 가져오기 위한 확장함수 추가 * feat: BeginAdventureActivity firebase용 버튼 로그 추가 * feat: LocationPermissionDialog firebase용 버튼 로그 추가 * refactor: 함수명 및 함수위치 통일 * feat: AdventureResultActivity firebase용 버튼 로그 추가 * feat: MyPageActivity firebase용 버튼 로그 추가 * feat: OnAdventureActivity firebase용 버튼 로그 추가 * refactor: 함수명 통일 * feat: UploadActivity firebase용 버튼 로그 추가 * feat: CameraPermissionDialog firebase용 버튼 로그 추가 * feat: xml에 있는 onClick 함수 삭제 및 firebase 버튼 로그 추가 * [BE] chore: spring profile에 대한 yml 파일 수정 * chore: yml 파일 수정 * chore: submodule 수정 * fix: @Value 어노테이션 삭제 * fix: 서버 통신 수정 (#196) * feat: NaagaThrowable을 수정하면서 data layer에서 400 / 500 / onFailure 세가지만 판단 * feat: 변경된 명세에 따라 AdventureStatusDto 변경 * feat: OnAdventureActivity에서 에러 로그를 볼 수 있도록 추가 * feat: OnAdventureActivity에서 도착 실패시 다시 시도하라는 토스트 발생 * feat: 다른 라이브 데이터를 받아서 한번만 호출할 수 있도록 효율적으로 변경 - 기존에는 DiposableLiveData를 만들고 이 데이터에 setValue까지 직접 해줘야했는데 이제는 다른 라이브데이터를 받아서 DisposableLiveData까지 setValue해주지 않아도 된다. * feat: 기존 게임을 불러올 경우 기존의 힌트를 찍어주는 로직 작성 * rename: 매개변수명 변경 --------- Co-authored-by: hyunji <83613106+hyunji1203@users.noreply.github.com> * refactor: dev 서버 환경 구축 (#236) * chore: submodule url 프로토콜 수정 * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * chore: update submodule * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * chore: update submodule * chore: update submodule * chore: MySql 의존성 추가 * chore: update submodule * Update backend_dev_merge_workflow.yml * Update backend_dev_merge_workflow.yml * chore: update submodule --------- Co-authored-by: kokodakadokok <45879491+kokodak@users.noreply.github.com> Co-authored-by: kokodak * fix: 깃허브 액션 워크플로우 수정 (#239) * feat: 소셜 로그인 기능 구현 (#235) * design: LoginActivty에 필요한 drawable source 추가 * design: LoginActivty에 필요한 string source 추가 * feat: 소셜 로그인을 위한 gradle 추가 * feat: 난독화 시 카카오 SDK가 포함되지 않도록 규칙 설정 * feat: 카카오 로그인 API key 숨김 처리 * feat: 인터넷 사용 권한 허용 * feat: 카카오 로그인 기능을 위한 Redirect URI 설정 추가 * feat: Kakao SDK를 초기화하는 application 구현 * feat: Kakao 로그인 기능 Util 구현 * design: LoginActivity 뷰 구현 * feat: 게임 상태가 진행 중이 아닐 때 Splash 화면에서 로그인 화면으로 이동하도록 구현 * feat: 상태바 색상 변경 * feat: 로그인 기능 구현 * feat: 사용자의 카카오 계정 닉네임을 마이페이지에 보여주는 기능 구현 * feat: 서버와 통신해 토큰을 얻어올 때 필요한 Dto, Domain 객체 생성 * feat: Dto, Domain 변환 mapper 추가 * feat: 서버와 통신하여 로그인 인증을 해주는 retrofit service 구현 * feat: 로그인 인증을 통해 토큰을 가져와주는 레포지토리 구현 * feat: 서버에게 받은 토큰을 저장하는 SharedPreference 구현 * feat: 서버에게 토큰을 받아와 로컬 저장소에 저장하는 기능 구현 * feat: 카카오 API KEY 감추기에 따른 yml 파일 수정 * fix: yml 파일 오류 수정 * fix: yml 파일 오류 수정 * fix: yml 파일 오류 수정 * fix: yml 파일 오류 수정 * refactor: ktlint 적용 * refactor: yml 파일 코드 정리 * refactor: 암호화 처리 되는 EncryptedSharedPreferences로 변경 * feat: retrofit Header에 서버에서 받아온 토큰 넣어주기 구현 * refactor: 카카오 토큰을 함수 인자로 받아오도록 수정 * rename: preference가 사용된 파일명을 datasource로 변경 * refactor: 함수 인자명 변경 * chore: 오류 코드 정리 및 예외 핸들러 보완 * chore: 오류 코드 문서와 통일 * refactor: 에러코드 문서화에 맞춘 코드 수정 * refactor: 요청 바디에 대한 입력 오류 예외 핸들러 추가 * fix: 원격 저장소와의 코드 변경 수정 * Update backend_dev_merge_workflow.yml * hotfix: workflow 긴급 수정 * hotfix: yml 파일 삭제 * fix: 게임 종료 실패 시, 남은 도전 횟수 줄지 않는 문제 해결 * chore: 서브모듈 추가 * 게임 종료 특정 예외 롤백 예외 적용 * fix: 도착 실패시, 시도 횟수 롤백 문제 수정 * test: 테스트 추가 * chore: workflow 수정 * chore: workflow 수정 --------- Co-authored-by: zillionme * feat: 자동 로그인 및 로그인 로직 수정 (#241) * feat: AuthInterceptor 만드는 중 * feat: 닉네임은 서버에서 내려주는 정보이므로 직접 가져올 필요가 없다. 로직 삭제 * rename: 카카오라는 플랫폼에 종속적이지 않은 인증정보 저장소이므로 네이밍 변경 * chore: NaagaApplication은 특정 뷰에 종속된 것이 아닌 어플리케이션 전체를 관장하는 객체이므로 패키지 변경 * feat: Application의 서브클래스 수정 및 해당 위치에서 AuthDataSource 생성 * rename: Preference 네이밍 변경 * feat: 도메인에서 엑세스 토큰과 리프레시 토큰에 대한 내용은 필요가 없다고 생각되어 삭제 * feat: preference에 refresh 로직 추가 * feat: AuthRepository 수정, 데이터 레이어에서 토큰을 저장할 수 있도록 변경 * feat: 주석 추가 및 고차함수를 통해 콜백에서 발급되는 토큰을 받아감 * rename: AuthService의 함수명 변경 * refactor: object에서 class로 변경 * refactor: DefaultAuthRepository에서 dataSource를 외부에서 주입받도록 변경 * refactor: 토큰 가져오는 방식이 변경됨 * feat: 카카오 로그인 방식에 문제가 있어 변경함 * feat: AuthInterceptor 완성 * feat: 예외처리 (#243) * feat: 데이터 레이어에서 사용할 Custom Throwable 클래스 생성 * feat: 통신 오류시 DataThrowable을 사용하는 코드 스니펫 작성 * feat: RankRepository의 서버 통신을 DataThrowable을 사용하는 통신으로 변경 * feat: 예상하는 예외 발생 시 토스트메시지로 보여주는 기능 구현 * refactor: sort, order를 도메인 Enum 클래스를 사용하도록 변경 * feat: PlaceRepository의 서버 통신을 DataThrowable을 사용하는 통신으로 변경 * feat: StatisticsRepository의 서버 통신을 DataThrowable을 사용하는 통신으로 변경 * feat: upload 기능 서버 통신 연결 해제 * refactor: 점진적 리팩토링 종료 및 불필요한 코드 삭제 * feat: http 응답코드 500번대, body가 null일 때 반환할 에러 추가 * feat: 통신 오류시 DataThrowable을 사용하는 코드 스니펫에 예외 핸들링 추가 * fix: 잘못된 파라미터 수정 * feat: 클라이언트에서 사용하는 hintThrowable 추가 * feat: AdventureRepository의 서버 통신을 DataThrowable을 사용하는 통신으로 변경 * feat: 장소등록 페이지로 이동하지 못하도록 구현 * style: 불필요한 개행 삭제 * refactor: 뷰모델 코드 통일 및 핸들링할 예외 수정 * refactor: 예외 발생 시 보여주는 방법 변경 * refactor: ViewModelProvider의 factory를 ViewModel의 동반객체로 이동 * refactor: 사용하지 않는 예외 클래스 삭제 * refactor: 인증관련 에러 삭제 * refactor: 에러 코드 변경 * feat: 소셜 로그인 기능과 인터셉터 인가 처리 및 아규먼트 리졸버 기능 추가 * feat: OAuth 연습 * feat: OAuth 연습2 * chore: 연습 코드 삭제 * feat: JWT 생성 로직 * feat: AccessToken과 RefreshToken 담고있는 AuthTokens 생성 * feat: 카카오 토큰으로 카카오로부터 유저 정보 받아오는 요청 로직 추가 * feat: 인증 정보 조회에 대한 서비스 로직 추가 * feat: 로그인 관련 요청 추가 * feat: JWT에서 멤버 ID 추출하는 기능 추가 * feat: 인터셉터에서 Authorization 헤더에서 토큰 추출해서 memberId 조회하는 기능 추가 * feat: 멤버 회원가입 시, 플레이어 함께 생성하도록 추가 chore: 네이밍 변경 Co-authored-by: chaewon121 * refactor: Member에 Password 삭제 test: Basic 헤더에서 Bearer + 토큰으로 변경 Co-authored-by: chaewon121 * chore: 패키지 구조 변경 Co-authored-by: chaewon121 * test: AuthInterceptor 테스트 추가 Co-authored-by: chaewon121 * test: AuthArgumentResolver 테스트 추가 Co-authored-by: chaewon121 * test: AuthController 테스트 추가 Co-authored-by: chaewon121 * test: AuthService 테스트 추가 Co-authored-by: chaewon121 * chore: 필요없는 프로필 삭제 Co-authored-by: chaewon121 * feat: 서브모듈 추가 Co-authored-by: chaewon121 * feat: 예외 처리 추가 Co-authored-by: chaewon121 * remove: 테스트 프로필 삭제 Co-authored-by: chaewon121 * chore: 스타일 수정 * test: pull 후 테스트 통과되도록 수정 Co-authored-by: chaewon121 * feat: 난독화를 위해 모든 Dto 필드에 SerialName을 추가 (#245) * fix: AuthInfo에 기본 생성자 추가 * fix: 서브모듈 업데이트 * feat: 앱 아이콘 설정 (#253) * fix: 메인으로 돌아갈 시 해당 액티비티가 사라지도록 수정 (#255) * feat: 사용자가 GPS 기능을 껐을 때 이를 인지하고 키도록 유도하는 기능 구현 (#258) * feat: 장치 구성 변경 대응 (#250) * feat: 화면을 세로모드로 고정 * feat: 다크모드를 사용해도 다크테마가 나오지 않도록 변경 * feat: 난독화 방지를 위한 ProGuard 수정 (#259) * refactor: 좌표 간 거리를 M 단위로 변경 및 힌트/시도횟수 변경 * refactor: 좌표간 거리를 m 단위로 변경 * refactor: 힌트 최대 사용 개수와 최대 시도 횟수 변경 * fix: 서브모듈 최신화 * feat: Firebase Analytics 서버 통신 에러 로그 추가 (#260) * refactor: 게임 종료 타입에 따른 점수 계산 기능 수정 * refactor: 메서드 명 변경 * refactor: 게임 시작 위치와 목적지의 직선 거리 구하는 기능 추가 * refactor: 게임 종료 타입에 따른 점수 계산 기능 수정 * refactor: 게임 결과에 따른 점수 계산 기능 수정 * refactor: gameScore 관련 패키지 네이밍 변경 * refactor: enum을 클래스의 상수로 빼놓은 것 수정 * refactor: gamescore 도메인에 스프링 의존성 제거 * refactor: 스코어 정책 못 찾을 때 예외 발생하도록 변경 feat: InternalException과 Exception에 대한 핸들러 추가 * chore: 스타일 수정 --------- Co-authored-by: dooboocookie * feat: 로깅 기능 추가 (#268) * feat: 이어하기 기능 추가 (#263) * feat: 이어하기 기능 구현 * feat: 뒤로가기 버튼을 2초내에 두 번 눌려야 종료되도록 기능 구현 * feat: splash를 거치면 login 액티비티로 이동하도록 수정 * feat: splash에서 adventure를 받아온 경우 BeginAdventureActivity까지 전달 - 이를 통해 이어하기가 가능하도록 기능 구현 * feat: 진행중인 게임이 있는 경우 이어하기가 표시되도록 변경 * feat: 게임결과 화면에서 뒤로가기 버튼 클릭 시 BeginAdventureActivity로 이동하도록 구현 * refactor: 버전에 따른 분기처리 함수에 Compat suffix 추가 * refactor: 문자열 strings.xml로 이동 * refactor: 사진 저장 경로 수정 (#269) * refactor: 이미지 저장하는 경로와 URL 경로 수정 * chore: 서브모듈 업데이트 * chore: 프로덕트 서버 배포 * chore: prod 서버 배포 * chore: prod 서버 배포 * fix: OnAdventureActivity 수정 (#265) * chore: lottie 의존성 추가 * design: 로티 애니메이션과 뷰 추가 * feat: 로딩 기능 추가 * feat: 뷰모델 불필요한 로직 정리 * feat: 중복 값에는 갱신되지 않는 라이브데이터 생성 * feat: 로티를 지도 위로 띄우기 위해 elevation을 적용 * feat: 로티 배경 흐린 색으로 수정 * design: string 리소스 추가 * feat: 힌트 잔여횟수 표시하도록 변경, 정답 도전 잔여 시도 횟수 표기, 토스트에서 스낵바를 띄우도록 변경, 목적지가 없을 시 종료 * design: 불필요한 + 버튼 삭제 * design: margin값 변경 * feat: snackbar를 toast로 변경 * feat: 로그인 시 사용자의 토큰이 로그에 보여지지 않도록 수정 (#271) * feat: 스플래시에서 받아온 게임을 넘겨주는 기능 삭제 (#274) * refactor: 로그 경로 변경 * chore: 서브모듈 수정 * fix: 잘못된 로직 수정 (#276) * feat: 스플래시에서 받아온 게임을 넘겨주는 기능 삭제 * fix: 잘못된 로직 수정 * feat: 시작 액티비티 변경 * feat: BeginAdventureActivity에서 진행중인 게임이 있는지 판단하는 기능 구현 (#277) * design: 로딩을 위한 스켈레톤 UI 생성 * feat: 진행중인 상태의 게임을 받아오고 로딩하는 과정을 추가 * feat: 작업중 * rename: 로티 파일 이름 변경 * design: 스켈레톤 뷰 지우고 로티 뷰 추가 * feat: 로티 로딩뷰로 수정 * style: 로그 삭제 * feat: 뷰 진행 플로우 변경 * refactor: 직접 만든 로직을 이미 존재하는 코틀린 api로 대체 * fix: 에러 수정 * fix: 사진 저장 시 1번 회원으로만 저장되는 오류 수정 * fix: 사진 저장 시 1번 회원으로만 저장되는 오류 수정 * chore: 서브모듈 업데이트 * chore: 서브모듈 업데이트 * chore: 추천 범위 500km로 수정 * test: 테스트 fixture 및 builder 추가 및 적용 * fix: 잘못된 거리 계산 수정 * feat: 테스트 Builder 패턴 적용 및 Fixture 생성 remove: 기존의 Fixture 파일 삭제 * test: 테스트 Builder 적용 및 기존의 cascade 옵션 삭제 * fix: application.yml 수정 * chore: 리커시브 컴페리전 이그노어 필드 추가 --------- Co-authored-by: dooboocookie * feat: Refresh Token 구현 및 자동 로그인 API, 회원 탈퇴 API, 로그아웃 API 구현 * test: 액세스 토큰 재발급 e2e 테스트 작성 * fix: 로그 환경셜정 변경 * feat: 액세스 토큰 재발급 기능 추가 * refactor: 액세스 토큰 재발급 기능 리팩터링 * refactor: 최초 액세스 토큰 발급 시 AuthToken 영속화 * chore: 임시 커밋 * test: 일부 테스트 수정 및 삭제 * feat: 아규먼트 리졸버 변경 및 추가 * feat: 소셜 로그인 연결 끊기 기능 추가 * fix: 아규먼트 리졸버 스프링 빈 등록 * refactor: 기본 설정파일 수정 * chore: 서브모듈 업데이트 * refactor: 멤버, 플레이어 삭제 필드 추가 * feat: 멤버, 플레이어 삭제 기능 추가 * feat: 토큰 삭제 기능 추가 * feat: AuthToken에 멤버 필드 추가 * feat: 로그아웃 API 추가 * chore: 패키지 구조 변경 * test: 회원탈퇴 로그아웃 E2E 테스트 추가 * chore: 서브모듈 업데이트 * refactor: 소프트 딜리트 @SqlDelete로 수정 refactor: cascade 옵션 PERSIST로 수정 test: 회원탈퇴 로그아웃 서비스, 컨트롤러 테스트스 작성 * chore: 충돌 해결 * chore: 서브모듈 업데이트 * chore: 충돌 해결 --------- Co-authored-by: zillionme * test: 작성되지 않은 테스트 코드 추가 * fix: 잘못된 거리 계산 수정 * feat: 테스트 Builder 패턴 적용 및 Fixture 생성 remove: 기존의 Fixture 파일 삭제 * test: 테스트 Builder 적용 및 기존의 cascade 옵션 삭제 * test: 없는 예외 테스트 추가 * test: StatisticTest 와 gameServiceTest 추가 * Update backend_dev_pr_workflow.yml * fix: Thread.sleep 추가 * Update GameControllerTest.java * Update GameControllerTest.java * Update backend_dev_pr_workflow.yml * Update backend_dev_pr_workflow.yml * Update backend_dev_pr_workflow.yml * Update GameControllerTest.java * Update backend_dev_pr_workflow.yml * Update backend_dev_pr_workflow.yml * test: 테스트 fixture 및 builder 추가 및 적용 * fix: 잘못된 거리 계산 수정 * feat: 테스트 Builder 패턴 적용 및 Fixture 생성 remove: 기존의 Fixture 파일 삭제 * test: 테스트 Builder 적용 및 기존의 cascade 옵션 삭제 * fix: application.yml 수정 * chore: 리커시브 컴페리전 이그노어 필드 추가 --------- Co-authored-by: dooboocookie * feat: Refresh Token 구현 및 자동 로그인 API, 회원 탈퇴 API, 로그아웃 API 구현 * test: 액세스 토큰 재발급 e2e 테스트 작성 * fix: 로그 환경셜정 변경 * feat: 액세스 토큰 재발급 기능 추가 * refactor: 액세스 토큰 재발급 기능 리팩터링 * refactor: 최초 액세스 토큰 발급 시 AuthToken 영속화 * chore: 임시 커밋 * test: 일부 테스트 수정 및 삭제 * feat: 아규먼트 리졸버 변경 및 추가 * feat: 소셜 로그인 연결 끊기 기능 추가 * fix: 아규먼트 리졸버 스프링 빈 등록 * refactor: 기본 설정파일 수정 * chore: 서브모듈 업데이트 * refactor: 멤버, 플레이어 삭제 필드 추가 * feat: 멤버, 플레이어 삭제 기능 추가 * feat: 토큰 삭제 기능 추가 * feat: AuthToken에 멤버 필드 추가 * feat: 로그아웃 API 추가 * chore: 패키지 구조 변경 * test: 회원탈퇴 로그아웃 E2E 테스트 추가 * chore: 서브모듈 업데이트 * refactor: 소프트 딜리트 @SqlDelete로 수정 refactor: cascade 옵션 PERSIST로 수정 test: 회원탈퇴 로그아웃 서비스, 컨트롤러 테스트스 작성 * chore: 충돌 해결 * chore: 서브모듈 업데이트 * chore: 충돌 해결 --------- Co-authored-by: zillionme * chore: 충돌 해결 --------- Co-authored-by: kokodak Co-authored-by: kokodakadokok <45879491+kokodak@users.noreply.github.com> Co-authored-by: dooboocookie Co-authored-by: dooboocookie <79090478+dooboocookie@users.noreply.github.com> Co-authored-by: zillionme * feat: 버전 변경 (#290) * feat: 로깅하기 (#291) * 임시저장 * 임시저장 * feat: 환경 설정별 로깅 추가 * refactor: 로그 파일 및 warn, error 로그 메시지 수정 * refactor: db 로그 출력 분리 * refactor: db 로그 레벨 수정 * chore: 서브모듈 업데이트 * chore: 워크 플로우 수정 * feat: 장소 업로드 기능 구현 (#301) * refactor: Part를 PartMap으로 변경 * feat: 업로드 화면으로 이동하는 기능 구현 * feat: 정보를 서버로 전송하는 기능 구현 - 필요한 정보를 RequestBody 형태로 만들고 Map에 저장하여 전송하는 방식 * feat: 정보를 성공, 실패했을 때의 로직 구현 * feat: 원하는 예외만 핸들링 하도록 구현 * feat: 잡은 예외에 토스트로 알맞는 문구를 띄워주는 기능 구현 * fix: 자료형 변경 * refactor: 문자열 string.xml 로 추출 * refactor: toRequestBody 변수 삭제 * refactor: key값 companion object에 저장 * fix: 위치관련 버그 수정 (#302) * feat: 업로드 화면으로 들어간 시점에 위치를 받아오는 기능 구현 * feat: 업로드 화면으로 이동하는 기능 구현 * feat: 위치 로딩을 기다리도록 하기 위한 로딩 로티 추가 * feat: 위치를 받아오고 저장할 때까지 로딩로티를 보여주는 기능 구현 * refactor: branch 변경 (#311) * refactor: 네트워크 작업 코루틴으로 변경 (#312) * refactor: Service함수 suspend로 변경 * feat: 값을 반환하거나 예외를 던지는 Response 확장함수 구현 * refactor: 반환 값 Response, suspend 적용 * refactor: 코루틴 적용 * refactor: ViewModel이 Application을 참조하지 않도록 변경 (#307) * Delete .idea directory * chore: 전체 gitignore 지정 (#320) * refactor: Login 뷰에서 진행하는 네트워크 작업 코루틴으로 변경 (#328) * feat: service와 repository에 suspend 추가 * refactor: repository 내 코루틴 사용 * refactor: repository 생성 시 Dispatcher 전해주도록 수정 * refactor: 코루틴 사용 * refactor: 불필요한 인자 제거 * refactor: 불필요한 로그 제거 * refactor: 불필요한 import 제거 * refactor: my page뷰에서 진행하는 네트워크 작업 코루틴으로 변경 (#323) * refactor: suspend 함수로 수정 및 반환 값을 Response로 수정 * refactor: DefaultStatisticsRepository의 네트워크 작업을 Response의 확장함수로 선언한 getValueOrThrow를 사용하도록 변경 * refactor: DefaultStatisticsRepository에서 하는 네트워크 작업을 코루틴을 사용하도록 변경 * refactor: suspend 함수로 수정 및 반환 값을 Response로 수정 * refactor: PlaceRepository에서 하는 네트워크 작업을 Response의 확장함수로 선언한 getValueOrThrow를 사용하도록 변경 * refactor: PlaceRepository에서 하는 네트워크 작업을 코루틴을 사용하도록 변경 * refactor: PlaceRepository 변경사항 적용 * style: ktlint 적용 * style: ktlint 적용 * feat: Setting 뷰 구현 (#331) * design: Setting 페이지 이동 버튼 생성 * feat: Setting 뷰 구현 * feat: 설정으로 이동하는 기능 구현 * feat: 뒤로가기 기능 추가 * feat: manifest에 activity 추가 * fix: History 뷰의 리사이클러뷰 image 오류 문제 해결 (#317) * fix: History 뷰dml 리사이클러뷰 image 오류 문제 해결 * design: 뒤로가기 버튼 위치 변경 * refactor: Adventure 도메인에 해당하는 네트워크 작업 코루틴으로 변경 (#315) * refactor: AdventureService의 함수들에 suspend 키워드 추가 * refactor: AdventureRepository의 함수들을 callback 구조에서 coroutine을 통한 반환값을 뱉는 형태로 변경 * refactor: AdventureRepository 변경에 따른ViewModel 변경 * refactor: 에러 상수화 (리뷰 반영) * feat: 장소 업로드 시 로딩 창이 뜨는 기능 구현 (#308) * feat: SingleLiveData 추가 * feat: 업로드 상태를 3가지로 관리하는 enum 클래스 생성 * feat: 전송이 완료될 때까지 로딩 로티가 보이는 기능 구현 * refactor: 전송 이벤트의 변경을 ViewModel에서만 관리하도록 변경 * refactor: 업로드 상태를 뷰모델에서 관리하도록 변경 * refactor: 뷰의 visibility 관리를 함수로 추출 * fix: 마이페이지 글자 깨지는 오류 수정 (#333) * chore: 전체 gitignore 지정 * fix: 마이페이지 글자 크기 계산 로직 오류 수정 * feat: AdventureHistoryViewModel 테스트 추가 (#340) * feat: ViewModelTest를 위한 Dependency 추가 * feat: LiveData 테스트를 위한 Class 추가 * test: 내 게임 결과 목록이 잘 불러와지는 지 확인 하는 뷰모델 테스트 추가 * style: ktlint 체크 * refactor: fake 객체 위치 변경 * feat: 회원 탈퇴 기능 구현 (#335) * feat: 서버와 회원 탈퇴 통신을 해주는 service 추가 * feat: 카카오 sdk의 unlink 메서드 추가 * feat: 회원 탈퇴 기능 추기 * feat: 회원탈퇴 버튼 클릭 시 회원 탈퇴가 되도록 하는 기능 구현 * feat: Service의 API 주소 수정 * refactor: Service의 반환 값 수정 * feat: 로그 수정 * refactor: ktlint 수정 * refactor: 메서드 반환 값이 non-nullable 하도록 수정 * refactor: 변수명 변경 * refactor: 에러 코드 상수화 * refactor: 회원 탈퇴 repository 메서드 내 runCatching 삭제 * feat: 회원 탈퇴 후 로그인 창으로 이동 시 백 스택에 쌓인 뷰를 리셋해주는 기능 구현 * feat: 회원 탈퇴 다이얼로그 생성 * feat: RankViewModel 테스트 추가 (#337) * feat: ViewModelTest를 위한 Dependency 추가 * feat: LiveData 테스트를 위한 Class 추가 * feat: 내 랭킹을 조회해오는 메서드 테스트 추가 * feat: 전체 랭킹을 조회 해오는 메서드 테스트 추가 * feat: 로그아웃 기능 구현 (#341) * feat: 로그아웃 요청 및 처리 로직 추가 * feat: DELETE 요청인 경우 body가 null이어도 에러를 반환하지 않도록 구현 * feat: 로그아웃 기능 버튼에 연결 * style: 로그아웃 성공시 출력할 문구 추가 * feat: 로그인 상태, 에러를 관리하는 라이브데이터 추가 * feat: 뷰모델 데이터 구독 및 적절한 처리 로직 구현 * chore: 사용하지 않는 파일 삭제 - Call의 확장함수 삭제 * feat: EncryptedSharedPreferences에 저장된 Access, Refresh 토큰 삭제 * feat: 로그아웃 클릭 시 다이얼로그창이 뜨는 기능 구현 * feat: 로그아웃 성공 후 뒤로가기 클릭 시 이전 액티비티가 나오지 않도록 기능 구현 * refactor: 문구 수정 * refactor: 코드 통일 * refactor: return 삭제 * feat: AdventureResultViewModel 테스트 추가 (#338) * feat: ViewModelTest를 위한 Dependency 추가 * feat: LiveData 테스트를 위한 Class 추가 * test: 성공한 게임 결과가 잘 불러와지는 지 확인 하는 뷰모델 테스트 추가 * test: 실패한 게임 결과가 잘 불러와지는 지 확인 하는 뷰모델 테스트 추가 * test: 내 랭킹 결과가 잘 불러와지는 지 확인 하는 뷰모델 테스트 추가 * style: ktlint 체크 * style: ktlint 체크 * style: ktlint 체크 * refactor: 리포지터리에 의존성 주입 라이브러리 적용 (#349) * feat: Hilt 의존성 추가 * feat: by viewModels 를 사용하기 위해 의존성 추가 * refactor: Hilt를 사용하여 의존성 주입 자동화 * refactor: 불필요한 로깅 삭제 * refactor: datasource 의존성 주입 라이브러리 사용 (#352) * refactor: retrofit 의존성 주입 라이브러리 적용 (#353) * feat: DataSource Module 추가 * feat: Service Module 추가 * refactor: Repository에 의존성 주입을 자동화하기 위해 수정 * refactor: Repository에 Service 주입 자동화 * refactor: lint check * feat: 자동로그인 기능 구현 및 스플래시 분리 (#346) * chore: 전체 gitignore 지정 * feat: AuthInterceptor에서 소셜 로그인은 제외하는 로직 추가, Bearer prefix를 빼먹어서 붙임 * feat: bearer를 붙인 토큰을 반환하도록 변경 * feat: 서버 통신에 필요한 dto 생성 및 refresh api 요청 함수 작성 * feat: 토큰 refresh 요청을 위한 레포지토리 로직 작성 * design: splash가 분리되면서 splash layout design 변경 * feat: 스플래시에서 토큰을 리프레시하고 다음 화면을 정하는 분기처리 로직 추가 * feat: 스플래시 액티비티를 따로 분리함 * feat: AuthRepository에 refresh 기능 선언 추가 * fix: 마이페이지 글자 크기 계산 로직 오류 수정 * style: 로그 삭제 * feat: response의 바디를 한번 확인하면 다시 사용할 수 없는 (closed 이슈)를 해결 * feat: 스플래시 로직을 수정하여 토큰 여부에 따라 화면을 분기 * feat: 로그인 액티비티 시작하는 intent flag 수정 * feat: Interceptor 로직 수정 * feat: 토큰 확인용 api 변경 및 에러로깅 추가 * feat: 사용하지 않는 변수 삭제 * feat: UploadViewModel 테스트 추가 (#343) * feat: ViewModelTest를 위한 Dependency 추가 * feat: LiveData 테스트를 위한 Class 추가 * feat: Robolectric 추가 * test: UploadViewModel test 추가 * chore: 오타 삭제 * refactor: 양방향 데이터 바인딩을 통해 뷰모델에서 안드로이드 의존성 제거 * refactor: lint 적용 * refactor: 필요없는 코드 삭제 * refactor: 전송을 위한 데이터가 다 채워졌는지 검사를 뷰모델에서 진행하도록 변경 * test: 안드로이드 의존성 없이 테스트 진행 * test: 뷰모델 테스트 진행 * test: 테스트를 위한 의존성 추가 * test: 필요하지 않은 구문 삭제 * refactor: 디자인 수정을 위한 공통 요소 추가 (#378) * style: 메인 색상 추가 * style: 메인 글꼴 추가 - 던파 비트비트체 ver2 * style: 프로젝트 전체 색상 변경 * style: 아이콘 추가 * refactor: 폰트명 변경 * refactor: rect_main 삭제, 테마 배경색을 color로 지정 * fix: OkHttpClient의 interceptor를 AuthInterceptor로 변경 (#375) * Refactor/#391 모험 기록 뷰 디자인 변경 (#396) * design: color resource 추가 * design: 성공, 실패를 보여주는 라벨 추가 * design: 뷰 제목 변경을 위해 strings resource 변경 * design: drawable resource 이름변경으로 인한 코드 수정 * design: 폰트 변경 * design: color resource 이름 변경 * feat: 앱 강제 업데이트 기능 구현 (#400) * feat: firebase-config 의존성 추가 * feat: 확장함수 패키지 생성, 이동 및 추가 * feat: 확인 다이얼로그 추가 - 강제 업데이트를 위해 외부가 클릭되어도 다이얼로그가 꺼지지 않도록 구현 * feat: 강제 업데이트 기능 구현 * refactor: 함수명 변경 * refactor: text gravity 수정 * refactor: 다이얼로그 title 글씨 크기 수정 * refactor: 다이얼로그 패키지 이동 * refactor: 로그인 뷰 디자인 변경 (#399) * design: 빌딩과 별 drawable 추가 * design: strings resource 변경 * design: 로그인 디자인 변경 * refactor: 불필요한 상태바 설정 코드 삭제 * refactor: 업로드 뷰 디자인 변경 (#381) * refactor: 업로드 뷰 디자인 변경 * refactor: 사용하지 않는 변수 삭제 * refactor: AppCompatButton 사용해서 배경색 지정하도록 변경 * refactor: editText에 hint 추가 * refactor: ktlint * refactor: 버튼 배경 변경 * refactor: editText 밑줄 삭제 * refactor: editText marginTop 수정 * refactor: 이미지뷰 marginTop 수정 * fix: 버튼 id 수정 * refactor: 사용하지 않는 함수 삭제 * refactor: 설정 뷰 디자인 변경 (#397) * design: 폰트 적용 * design: strings resource 추가 * design: 빌딩과 별 drawable 추가 * design: 백그라운드에 빌딩과 별 이미지 추가 * refactor: strings resource 띄어쓰기 수정 * refactor: my page 뷰 디자인 변경 (#395) * refactor: 통계 뷰 변경, 리사이클러뷰 사용 * refactor: 패키지 구조 변경 * refactor: 리사이클러뷰 반영 * refactor: 다른이름의 같은 속성의 파일을 하나로 사용하도록 변경 * refactor: 아이템마다 배경이 다르게 지정되도록 변경 * refactor: StatisticsModel 생성 코드를 StatisticsModel 내부로 이동 * refactor: String 상수화 * refactor: 내가 추가한 장소 뷰 디자인 수정 * refactor: 마진 수정 * refactor: 내가 추가한 장소 커스텀 뷰 수정 - 뷰타입에 따라 분리하지 않음 - 리사이클러뷰에서 뷰홀더를 하나로 사용 * refactor: 리사이클러뷰 가로 스크롤로 변경 * refactor: 글씨 크기, 마진 변경 * feat: 장소를 추가한 적 없는 유저에게는 다른 뷰가 보이도록 함 * refactor: 마진 수정 * refactor: ktlint * refactor: drawable 변경 * refactor: 아이콘 변경 * refactor: apply 적용 * refactor: marginTop 추가 * refactor: 모험 결과 뷰 디자인 변경 (#402) * design: 성공, 실패를 나타내주는 라벨 drawable 생성 * design: main blue 색을 이용한 그라데이션 배경 resource 추가 * design: 버튼 drawable resource 추가 * design: 모험 결과 디자인 변경 * refactor: string 한글로 변경 * refactor: margin 변경 * refactor: drawable 이름 변경 * refactor: 게임 시작 뷰 디자인 변경 (#408) * chore: 전체 gitignore 지정 * feat: 버튼 이미지 추가 * feat: BeginActivity에서 자주 쓰이는 Text style 생성 * feat: BeginActivity 뷰 구현 중 * feat: button drawable을 png에서 vector asset으로 변경 및 네이밍 변경 * feat: BeginAdventureActivity 뷰 레이아웃 변경 - setting 버튼 추가 - 빌딩 이미지 화면 사이즈에 맞춤 - 기타 마진 및 패딩 변경 * feat: BeginAdventureActivity 변경된 뷰에 따라 클릭리스너 연결 코드 변경 * feat: 다이얼로그 버튼 배경 변경 * feat: 임시로 설정해놓은 visibility 원상복구 * feat: 사용하지 않는 resource 삭제 * feat: bg_yellow_button drawable 변경 * feat: 사용하지 않는 파일 삭제 * feat: 버튼 백그라운드 적용 * feat: 버튼 백그라운드 적용 * feat: 업로드 화면에서 뒤로가기 기능 구현 (#413) * feat: 게임 입장 시 사진이 먼저 뜨는 기능 구현 (#407) * refactor: 버튼 디자인 일관성 있도록 변경 (#417) * refactor: 버튼 drawable 추가 * refactor: 버튼 background 변경 * refactor: 버튼 background 변경 * refactor: 버튼 background 변경 * refactor: 버튼 background 변경 * refactor: 게임 시작 뷰 디자인 변경 (#408) * chore: 전체 gitignore 지정 * feat: 버튼 이미지 추가 * feat: BeginActivity에서 자주 쓰이는 Text style 생성 * feat: BeginActivity 뷰 구현 중 * feat: button drawable을 png에서 vector asset으로 변경 및 네이밍 변경 * feat: BeginAdventureActivity 뷰 레이아웃 변경 - setting 버튼 추가 - 빌딩 이미지 화면 사이즈에 맞춤 - 기타 마진 및 패딩 변경 * feat: BeginAdventureActivity 변경된 뷰에 따라 클릭리스너 연결 코드 변경 * feat: 다이얼로그 버튼 배경 변경 * feat: 임시로 설정해놓은 visibility 원상복구 * feat: 사용하지 않는 resource 삭제 * feat: bg_yellow_button drawable 변경 * feat: 사용하지 않는 파일 삭제 * feat: 버튼 백그라운드 적용 * feat: 버튼 백그라운드 적용 * feat: 업로드 화면에서 뒤로가기 기능 구현 (#413) * feat: 게임 입장 시 사진이 먼저 뜨는 기능 구현 (#407) * refactor: 불필요한 속성 제거 * refactor: 불필요한 속성 제거 * refactor: guideline 추가해 뷰 배치 --------- Co-authored-by: k_dragonm <78788847+briandr97@users.noreply.github.com> Co-authored-by: krrong * refactor: 스플래시 디자인 변경 (#416) * refactor: 뷰 id 변경 * refactor: 안드로이드 12에서 나오는 스플래시가 보이지 않는 것처럼 구현 * refactor: 불필요한 코드 삭제 * refactor: warning 제거 애노테이션 추가 * refactor: 불필요한 파일 삭제 * refactor: 기본 스플래시를 사용하도록 변경 * refactor: 스플래시 액티비티 디자인 변경 * refactor: 아이콘 변경 * refactor: 인게임 뷰 디자인 변경 (#418) * chore: 전체 gitignore 지정 * feat: 목적지와의 남은 거리를 나타내는 텍스트 리디자인 * feat: 아이콘 생성 * feat: strings resource화 * feat: 인게임 뷰 리디자인 적용 * feat: 폴라로이드 다이얼로그 디자인 변경 * feat: NaagaAlertDialog의 positive 버튼과 negative 버튼의 위치 변경 및 색상 변경 * feat: 버튼 백그라운드 이미지 적용 * feat: 로티 visibility 원상복구 * feat: 로딩시 거리가 null로 보여지는 것을 0으로 변경 * feat: 버튼 마진값 조절 * feat: 사용하지 않는 아이콘 삭제 * refactor: NaagaAlertDialog와 ConfirmDialog 통일 (#421) * chore: 전체 gitignore 지정 * feat: NaagaAlertDialog에서 Cancelable 여부를 정할 수 있도록 변경 * feat: ConfirmDialog를 삭제하고 AlertDialog로 대체 * feat: 함수 네이밍 변경 및 사용하지 않는 함수 삭제 * chore: 다이얼로그를 한 패키지에 모음 * feat: 사용되지 않는 다이얼로그의 layout 삭제 * refactor: 장소 등록 api 수정 (#369) * refactor: 장소 등록을 검수할 수 있도록 검수중으로 등록한다 * refactor: 변경된 API 명세 반영 * refactor: string 변경 * feat: 장소등록 성공시 토스트 메시지를 띄워줌 * refactor: 인게임 버튼 drawable resource 변경 (#424) * chore: 전체 gitignore 지정 * feat: 버튼의 배경 resource를 변경 * feat: 하단 버튼들의 margin값 변경 * refactor: permission dialog 통일 (#426) * refactor: 다이얼로그 패키지 이동 * refactor: 다이얼로그 패키지 이동 * refactor: 다이얼로그 폰트 변경 * refactor: 사용하지 않는 파일 삭제 * refactor: string 정리 * refactor: 함수 분리 * feat: 문의하기 기능 구현 (#427) * feat: strings resource 추가 * feat: 문의하기를 누르면 나아가 공식 계정으로 이메일이 보내 지는 기능 구현 * refactor: 이메일 제목 strings에 추가 * feat: 버전코드 및 버전이름 수정 (#431) * hotfix: 액세스 토큰 리프레시 및 자동 로그인 로직 수정 (#438) * [ALL] 버전 1 출시 main 브랜치 머지 (#299) * chore: 안드로이드 프로젝트 폴더 생성 (#2) (#3) * feat: 안드로이드 프로젝트 초기 세팅 (#5) * chore: 안드로이드 프로젝트 폴더 생성 (#2) * feat: 안드로이드 프로젝트 초기 세팅 * chore: gitignore 수정 및 불필요한 파일 삭제 * feat: 프로젝트 초기 세팅 (#7) * fix: 초기 설정 삭제 (#10) * feat: 백엔드 프로젝트 초기 세팅 (#11) * feat: 프로젝트 초기 세팅 * chore: .DS_Store 파일 삭제 및 gitignore 추가 * chore: .DS_Store 파일 삭제 및 gitignore 추가 * chore: 패키지 구조 설정 (#12) * [BE] feat: 엔티티 설계 (#15) * chore: 프로퍼티 파일 수정 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Member 엔티티 생성 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Place 엔티티 생성 - Position 도메인 생성 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Game 엔티티 생성 Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: Position의 동등성 기능 추가 --------- Co-authored-by: dooboocookie Co-authored-by: chaewon121 Co-authored-by: zillionme * feat: 초기 resource 파일 세팅 (#16) * feat: DTO 생성 (#18) * feat: 위치를 나타내는 Dto 생성 * feat: 목적지를 나타내는 Dto 생성 * chore: gitkeep 파일 삭제 * feat: Domain 설계 및 생성 (#21) * refactor: 좌표를 나타내는 Dto 이름 변경 * feat: 좌표를 저장하는 도메인 클래스 생성 * feat: 목적지를 저장하는 도메인 클래스 생성 * feat: 도메인 repository 인터페이스 생성 * feat: 네이버 맵을 화면에 띄우는 기능 구현 (#23) * feat: 네이버 맵을 사용하기 위한 의존성을 gradle에 추가 * feat: manifest에 네이버 맵을 사용하기 위한 메타 데이터 추가 * feat: 액티비티 네이밍 변경, 네이버 맵을 화면에 띄우는 기능 구현 * chore: .gitignore 수정 * chore: 네이버 지도 사용을 위해 gradle.properties에 제티파이어를 추가하여 버전 차이 문제를 해결 * feat: 회원 인증 기능 구현 (#26) * feat: 회원정보 추출 기능 구현 * feat: 회원 인증 어노테이션 커스텀 구현 * feat: 인터셉터 추가 * refactor: argumentResolver 리팩토링 * feat: 설정정보 인터셉터 추가 * refactor: 회원 정보 조회 예외처리 중복 수정 * feat: 위치 권한 요청 기능 구현 (#27) * chore: repository 패키지 위치 이동 * feat: 모험시작 액티비티 생성 - 필요한 위치권한 Manifest에 등록 - 위치권한 요청 * design: UI관련 resource 추가 * feat: 게임 시작 기능 액티비티 추가 및 권한 요청 기능 구현 * design: 문자열 strings 리소스화 * design: 배경 및 버튼 색상 변경 * feat: 네이버지도에서 현재 위치를 잡는 기능 구현 (#28) * feat: 위치 권한을 승인한 경우 모험 액티비티로 이동하는 기능 구현 * feat: 내 위치를 잡으면 트래킹하도록 기능 구현 * feat: isLocationButtonEnabled 활성화 구현 * feat: 장소 추천 기능 구현 (#29) * chore: 프로퍼티 파일 수정 * feat: 위치 기준으로 반경 거리내의 장소 추천 쿼리 작성 * feat: Game 엔티티 빈 생성자 추가 * refactor: 패키지명 수정 * chore: 더미 데이터 추가 * feat: Game 엔티티 생성 * feat: Place 서비스 계층 생성 feat: 장소 선정 로직 기능 구현 * feat: GameRepository 생성 * feat: Game 서비스 계층 생성 feat: 장소 선정 기능 구현 * feat: Place 응답 DTO 구현 * feat: Game 컨트롤러 계층 생성 * style: 코드 정렬 * feat: 목적지와 현재위치 사이 거리를 계산하여 사용자에게 보여주는 기능 구현 (#35) * feat: repository 목 구현체 생성 * feat: OnAdventureViewModel 생성 * refactor: 거리 반환값의 자료형을 Int로 수정 * feat: 목적지와 현재위치 사이 거리를 계산하여 사용자에게 보여주는 기능 구현 * feat: Coordinate를 받아 해당 위치에 좌표를 찍는 기능 구현 (#39) - 목적지를 임시로 상수처리 - 추후 목적지를 서버에서 받아 마커를 찍는 방식으로 수정 필요 * feat: 사진 버튼을 클릭하면 사진 다이얼로그를 띄우는 기능 구현 (#40) * design: close icon 추가 * feat: 화면에 관련된 유틸 파일과 메서드 생성 * design: OnAdventure 액티비티에서 사진을 보여주기 위한 다이얼로그 UI 구현 * feat: 목적지에 대한 사진을 띄워주는 DestinationPhotoDialog 구현 * refactor: LocationDialogFragment의 메서드를 DisplayUtil로 분리 * style: 코드 정렬 * feat: 생성시 액티비티로부터 사진을 받아오는 기능 구현 * design: 사진 아이콘 버튼 추가 * feat: 액티비티에서 사진 아이콘 버튼 클릭시 다이얼로그를 띄우는 로직 구현 * feat: 사진이 로딩중 문구 strings 리소스화 * feat: 뷰모델로부터 얻어온 사진을 넘기도록 로직 수정 * refactor: 다이얼로그 및 변수 네이밍 변경 * refactor: strings 리소스화 * refactor: 객체 네이밍 변경 * feat: 목적지에 도착 시 도착 버튼 활성화 기능 구현 (#41) * design: 비활성화 버튼 color resource 추가 * design: 버튼의 상태에 따라 버튼 UI가 변경 되는 selector 생성 * feat: 목적지 도달 시 모험 종료 버튼 활성화 기능 추가 * refactor: 기존에 있는 drawable 활용해 selector 생성 * refactor: 도착 버튼 string을 resource에 추가 * refactor: API 명세 변경으로 인한 기능 수정 (#43) * refactor: 조회 쿼리의 결과를 List로 받도록 수정 * feat: 인증 관련 예외 기능 추가 * feat: 게임 관련 예외 기능 추가 * feat: 장소 관련 예외 기능 추가 * feat: 회원 관련 예외 기능 추가 * feat: 수정된 API 명세에 맞춰 게임 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 게임 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 장소 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 회원 서비스 로직 수정 * feat: 수정된 API 명세에 맞춰 게임 서비스 로직 수정 * feat: 게임에 대한 응답 DTO 생성 * feat: 수정된 API 명세에 맞게 컨트롤러 수정 * feat: 수정된 API 명세에 맞게 컨트롤러 수정 * style: import문 최적화 * refactor: 기존 런타임 예외를 인증 커스텀 예외로 수정 * refactor: 사용하지 않은 메서드 삭제 * refactor: 상수 이름 변경 * refactor: final 키워드 추가 * refactor: @Transactional 어노테이션에 readOnly 속성 추가 * refactor: 패키지 수정 --------- Co-authored-by: kokodak * feat: 서버통신 초기세팅 (#44) * feat: Adventure 도메인 클래스 생성 * feat: Adventure 상태를 갖는 enum 클래스 생성 * feat: 기능 변경에 따른 repository 변경 * chore: 사진 다이얼로그 패키지 위치 변경 * feat: AdventureDto 클래스 생성 * feat: Dto와 domain 클래스간의 mapper 구현 * refactor: repository 이름 변경 * feat: repository 기능 변경으로 인한 mock repository 변경 * feat: retrofit service 인터페이스 생성 * feat: adventure ERROR 상태 클래스 추가 * feat: Repository 변경에 따른 ViewModel 변경 및 서버 통신 오류 처리 * feat: Retrofit 객체 생성 및 interceptor 구현 * chore: AdventureService 패키지 위치 변경 * feat: 목적지 도착 여부 확인 기능 구현 (#47) * feat: 좌표사이의 거리를 키로미터로 계산하는 로직 구현 * feat: 도착여부 판단 및 접근 권한 검증 기능 구현 * feat: 장소의 유효범위 여부 검증 구현 * feat: 게임 종료기능 api 구현 * refactor: 게임 관련 예외를 사용하도록 변경 * refactor: 인증 관련 예외 추가 및 적용 * style: final 키워드 추가 및 코드 정렬 * fix: 파라미터명 수정 * feat: 백엔드 ci workflows 초안 작성 (#49) * chore: step 이름 추가 (#50) * [BE] fix: 백엔드 ci workflows 초안 작성 (#51) * chore: step 이름 추가 * fix: default working directory 추가 * fix: working directory 상대경로로 변경 (#52) * chore: step 이름 추가 * fix: default working directory 추가 * fix: working directory 상대경로로 변경 * feat: 서버에 모험 시작을 요청하는 기능 구현 (#48) * refactor: AdventureRepository 수정 * feat: Coordinate 객체의 Domain to Dto 매핑 함수 생성 * feat: Result의 failure에서 사용할 나아가 팀만의 Throwable 생성 * feat: 서버통신이 성공적이지 않을 때에 대한 객체와 서버통신 코드를 단순화할 메서드 생성 * feat: AdventureRepository의 beginAdventure 함수 구현 * refactor: 코드 방식 변경 get() -> [] * feat: MockRepository의 beginAdventure 함수 구현 * refactor: 타입을 표현해줌 * feat: 실제 base url 등록 * feat: http 통신 허용 * fix: json 변환 과정 수정 * fix: TODO 주석처리 * feat: 코루틴 의존성 추가 * feat: 모험을 시작하는 서버통신 구현 * feat: 모험이 끝났을 때 서버에게 모험이 종료 됐음을 알려주는 기능 구현 (#53) * feat: 모험 종료 시 서버에게 데이터를 받아 올 Dto 생성 * feat: 모험 종료 시 서버에게 받아 온 Dto mapper 생성 * refactor: 데이터 반환 값 타입 변경 * feat: AdventureRepository의 endAdventure 구현 * feat: 모험 종료 시 서버와 통신해 현재 모험 상태를 받아온 후 상황에 맞게 분기 처리 해주는 기능 구현 * refactor: mock Repository의 endAdventure 함수 구현 * fix: onClick에서 사용된 함수에게 인자를 넣어 Databinding 오류 해결 * feat: 서버에서 목적지를 받아오는 기능 구현 (#54) * refactor: 게임 정보를 가져오는 서비스 수정 * feat: 서버에서 목적지를 받아오는 기능 구현 * fix: 목적지 도착 버튼 클릭 시 발생하는 오류 수정 (#56) * fix: RetrofitService Path 수정 * fix: Serializable 어노테이션 추가 * refactor: iteration 명칭 변경 및 타입 명시 제거 * feat: 안드로이드 프로젝트에 firebase 추가 (#75) * feat: 필요 없는 파일 삭제 잘못 올린 파일을 삭제합니다. * chore: gitignore 수정 (#78) * feat: 안드로이드 CI 자동화 (#77) * chore: ktlint를 위한 config 파일 추가 * chore: ci 자동화를 위한 yml 파일 추가 * style: ktlint에 걸린 코드 정렬 * chore: ci 자동화 json 파일 추가 * style: ktlint에 걸린 코드 정렬 * style: ktlint에 걸린 코드 정렬 * chore: ci 자동화 json 파일 추가 * style: ktlint에 걸린 코드 정렬 * style: ktlint에 걸린 코드 정렬 * chore: ci 자동화 파일 수정 * style: ktlint 규칙 변경에 따른 수정 * feat: 스플래시 화면에서 진행 중인 모험이 있는지 판단하고 분기 하는 기능 구현 (#58) * chore: apk 및 aab 추출을 위한 파일 * design: splash를 위한 스타일 생성 * feat: 레포지토리에 모험 상태를 통해 모험 목록을 받아오는 기능 추가 * feat: 모험 상태를 통해 모험목록을 받아오는 retrofit 인터페이스 작성 * feat: 모험 상태를 통해 모험 목록을 반환하는 레포지토리 기능 구현 * feat: 이전 액티비티로부터 OnAdventureActivity로 화면을 전환할때 필요한 인텐트를 반환하는 함수 작성 * feat: 스플래시 액티비티와 뷰모델(및 팩토리) 생성 - 스플래시에서 서버통신을 통해 현재 진행 중인 모험이 있는지 확인한다. - 현재 진행 중인 모험이 있다면 해당 모험과 함께 OnAdventureActivity로 이동한다. - 현재 진행 중인 게임이 없다면 BeginAdventureActivity로 이동한다. * feat: 화면간 데이터 이동을 위한 uiModel 생성 - gradle에 parcelize 플러그인 추가 - AdventureUiModel 및 Mapper 생성 - CoordinateUiModel 및 Mapper 생성 - DestinationUiModel 및 Mapper 생성 * feat: parcelable한 데이터를 인텐트로부터 받기 쉽게할 유틸 함수 작성 * feat: OnAdventureActivity가 열리는 두 가지 경우에 따라 모험을 지정 - 이미 모험이 진행 중이면 이전 화면으로부터 모험을 전달 받고 모험을 서버에 요청하지 않는다. - 진행 중인 모험이 없다면 서버로부터 모험을 요청한다. * refactor: OnAdventureActivity에서 Intent를 생성해주므로 해당 함수를 이용하도록 변경 * [AN] feat: registerForActivityResult 분기처리 기능 구현 (#72) * design: 대락적인 위치 권한만 허용됐을 시 보여줄 문구 string 리소스로 추가 * feat: Dialog 내에서 권한을 체크하여 대략적인 위치 권한이 있는 상태와 전혀 없는 상태를 구분하여 다른 문구를 보여주도록 구현 * feat: BeginAdventureActivity 권한 코드 수정 - 유저가 권한 요청을 허용 및 거절 했을 시 토스트 메시지로 즉각적인 피드백을 주도록 구현 - 함수 분리 - 다이얼로그 태그 상수화 * feat: BeginAdeventureActivity UI 변경사항 적용 (#71) * design: 랭크, 마이페이지, 업로드 아이콘 추가 * design: 기존의 background를 지정하고 tint로 색을 지정하는 방식은 elevation을 반영하지 못해 색이 있는 shape을 새로 생성함 * design: BeginAdventureActivity에서 사용될 style 생성 * design: BeginAdventureActivity xml 레이아웃 작성 * feat: AdventureResultActivity 구현 (#80) * design: 모험 결과 상태에 따른 스탬프 drawable 리소스 추가 * design: 모험 결과 페이지에 필요한 strings 리소스 추가 * feat: 모험 결과에 따라 다른 UI가 띄워지는 액티비티 구현 * fix: manifest 오류 수정 * feat: 3차 데모데이 엔티티 설계 (#84) * feat: BaseEntity 생성 * feat: Player 도메인 생성 * feat: Hint 도메인 생성 Co-authored-by: dooboocookie * feat: GameResult 도메인 생성 Co-authored-by: dooboocookie * style: import문 최적화 Co-authored-by: dooboocookie * feat: 스프링 부트 어플리케이션에 @EnableJpaAuditing 추가 Co-authored-by: dooboocookie * refactor: 게임 도메인 수정 Co-authored-by: dooboocookie * refactor: 장소 도메인 생성 Co-authored-by: dooboocookie * refactor: Score 도메인 생성 Co-authored-by: dooboocookie * refactor: Place에 BaseEntity 상속 추가 * refactor: Member에 BaseEntity 상속 추가 및 생성자 추가 --------- Co-authored-by: dooboocookie * feat: OnAdventureActivity UI 변경사항 적용 (#73) * design: OnAdventureActivity에서 사용하는 아이콘 추가 * rename: drawable 컨벤션 유지 * design: 색상 추가 * design: 원 형태의 백그라운드 추가 * design: 문구 변경 * feat: OnAdventureActivity UI 변경사항 적용 * feat: 서버로부터 받아온 목적지에 핀을 꽂는 기능 제거 * rename: 일관성을 위한 아이콘 이름 수정 * design: 하단 버튼 높이 통일 * design: 흰색 배경 drawable 생성 * design: 버튼 그림자 생성 * feat: 충돌 해결 * feat: 충돌 해결 * feat: 충돌해결 * [AN] feat: UploadActivity 구현 * chore: gitignore 수정 * design: 카메라, 좌표 아이콘 추가 * design: 출력 문구 추가 * design: 마진 사이즈 추가 * feat: UploadActivity 구현 * feat: UploadActivity의 인텐트를 가져오는 함수 구현 * chore: string.xml 변수명 변경 * refactor: 사진이 들어갈 이미지뷰와 카메라 아이콘을 분리 * feat: 카메라 권한 요청 기능 구현 (#92) * design: 카메라 권한 관련 아이콘 추가 * feat: 카메라 권한 추가 * feat: dataBinding 사용하도록 xml 변경 * feat: 카메라 위치권한을 요구하는 다이얼로그 생성 * feat: 카메라 권한이 없는 경우 권한 요청 다이얼로그를 띄우는 기능 구현 * chore: 레이아웃 id 컨벤션 유지 * refactor: 다이얼로그의 tag를 다이얼로그 클래스에 위치하도록 통일 * refactor: 매직넘버 상수화 * rename: drawable 파일명 변경 * feat: 명세서 기준으로 Dto들 생성 (#89) * feat: 명세서 기준으로 Dto들 생성 * feat: 변경된 API 명세에 맞춰 Dto 변경 * feat: 디바이스의 위치를 받아와 뷰에 보여주는 기능 구현 (#93) * feat: 디바이스의 위치를 받아와 뷰에 보여주는 기능 구현 * refactor: 좌표를 문자열로 반환하는 기능 함수분리 * feat: 도메인 모델 생성 (#91) * refactor: ERROR를 NONE으로네이밍 변경 * feat: 도메인 객체 생성 (미완) * feat: 도메인 객체 수정 및 추가 생성 * feat: 도메인 수정 * rename: 패키지명 수정 * feat: 통계 path 레트로핏 서비스 구현 #101 * feat: 서버에서 Rank 관련 데이터를 받아올 때 사용될 service 생성 (#100) * feat: 3차 데모데이용 Game Path 레트로핏 서비스 생성 (#102) * feat: 장소 path 레트로핏 서비스 구현 (#103) * feat: AdventureHistoryActivity 구현 (#106) * design: AdventureHistory 뷰에 필요한 string resource 추가 * design: AdventureHistory 뷰에 필요한 drawable resource 추가 * design: 리사이클러뷰에 들어갈 Item 레이아웃 생성 * feat: 모험 기록을 보여 주는 리사이클러뷰 어댑터 생성 * feat: AdventureHistory 액티비티 구현 * feat: AdventureHistoryActivity에 모험 기록을 보여줄 리사이클러뷰 구현 * feat: 뒤로가기 버튼 구현 * refactor: 함수 이름 변경 * refactor: 이름이 길어질 때 줄여쓰기가 되도록 기능 추가 * refactor: Mock 데이터 생성 방법 수정 * refactor: 불필요한 함수 인자 삭제 * feat: RankRepository 생성 (#109) * refactor: Service 명 수정 * feat: RankRepository Interface 구현 * feat: PlayerDto를 도메인 객체로 바꿔주는 도메인 mapper 생성 * feat: RankDto를 도메인 객체로 바꿔주는 도메인 mapper 생성 … --------- Co-authored-by: dooboocookie <79090478+dooboocookie@users.noreply.github.com> Co-authored-by: krrong Co-authored-by: hyunji <83613106+hyunji1203@users.noreply.github.com> Co-authored-by: zillionme <100172683+zillionme@users.noreply.github.com> Co-authored-by: chaewon121 <80631952+chaewon121@users.noreply.github.com> Co-authored-by: hyunji1203 Co-authored-by: kokodak Co-authored-by: kokodakadokok <45879491+kokodak@users.noreply.github.com> Co-authored-by: zillionme Co-authored-by: chaewon121 Co-authored-by: kokodak Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: dooboocookie --- android/app/src/main/AndroidManifest.xml | 6 +- .../java/com/now/naaga/NaagaApplication.kt | 6 - .../data/remote/retrofit/AuthInterceptor.kt | 2 +- .../AdventureDetailActivity.kt | 4 +- .../AdventureResultActivity.kt | 8 +- .../AdventureResultViewModel.kt | 5 - .../adventureresult/PreferenceView.kt | 27 +- .../beginadventure/BeginAdventureActivity.kt | 4 +- .../naaga/presentation/custom/GameButton.kt | 153 ++++++++++ .../presentation/custom/GameButtonColor.kt | 33 +++ .../onadventure/OnAdventureActivity.kt | 12 +- .../onadventure/OnAdventureViewModel.kt | 15 +- .../presentation/upload/UploadActivity.kt | 223 ++++++++------ .../presentation/upload/UploadViewModel.kt | 6 +- .../java/com/now/naaga/util/BitmapBuilder.kt | 79 +++++ .../com/now/naaga/util/extension/ViewExt.kt | 15 +- .../res/color/selector_main_gray_purple.xml | 5 - .../main/res/drawable/rect_radius_small.xml | 8 +- .../drawable/rect_red_white_radius_small.xml | 6 - .../res/layout/activity_adventure_detail.xml | 5 +- .../res/layout/activity_adventure_result.xml | 27 +- .../res/layout/activity_begin_adventure.xml | 39 +-- .../src/main/res/layout/activity_my_page.xml | 8 +- .../main/res/layout/activity_on_adventure.xml | 8 +- .../src/main/res/layout/activity_upload.xml | 9 +- .../main/res/layout/custom_mypage_grid.xml | 2 +- .../res/layout/custom_mypage_grid_empty.xml | 4 +- .../src/main/res/layout/dialog_polaroid.xml | 4 +- .../main/res/layout/dialog_read_letter.xml | 7 +- .../main/res/layout/dialog_send_letter.xml | 9 +- .../app/src/main/res/layout/item_history.xml | 8 +- .../app/src/main/res/layout/item_letter.xml | 9 +- android/app/src/main/res/layout/item_rank.xml | 2 +- .../app/src/main/res/values-night/colors.xml | 36 +++ .../app/src/main/res/values-night/themes.xml | 9 +- android/app/src/main/res/values/attrs.xml | 8 + android/app/src/main/res/values/colors.xml | 35 ++- android/app/src/main/res/values/strings.xml | 5 + android/app/src/main/res/values/themes.xml | 2 +- .../java/com/now/naaga/UploadViewModelTest.kt | 5 + android/gradlew.bat | 178 +++++------ backend/build.gradle | 1 + backend/gradlew.bat | 184 ++++++------ .../jwt/AuthTokenGenerator.java | 4 +- .../now/naaga/common/config/WebConfig.java | 8 + .../exception/ControllerExceptionHandler.java | 16 +- .../naaga/game/application/GameService.java | 2 +- .../letter/application/LetterFindService.java | 26 -- .../letter/application/LetterService.java | 101 +++++-- .../WriteLetterLogCreateService.java | 8 - .../letterlog/ReadLetterLogService.java | 52 ---- .../letterlog/WriteLetterLogService.java | 54 ---- .../letterlog/dto/LetterByGameCommand.java | 13 - .../letterlog/dto/LetterLogCreateCommand.java | 7 - .../dto/WriteLetterLogCreateCommand.java | 4 - .../domain/letterlog/LetterLogType.java | 25 ++ .../domain/letterlog/ReadLetterLog.java | 1 - .../letter/exception/LetterExceptionType.java | 5 + .../letter/presentation/LetterController.java | 58 ++-- .../presentation/LetterLogController.java | 72 ----- .../naaga/letter/presentation/LogType.java | 8 - .../converter/LetterLogTypeConverter.java | 12 + .../dto/FindLetterLogByGameCommand.java | 16 + .../presentation/dto/LetterRequest.java | 4 +- .../letterlog/ReadLetterLogRepository.java | 4 + .../like/application/PlaceLikeService.java | 6 +- .../place/domain/PlaceRecommendService.java | 5 +- .../place/repository/PlaceRepository.java | 11 +- .../naaga/common/fixture/PositionFixture.java | 3 + .../game/application/GameServiceTest.java | 42 ++- .../letter/application/LetterServiceTest.java | 269 ++++++++++++----- .../letterlog/ReadLetterLogServiceTest.java | 119 -------- .../presentation/LetterControllerTest.java | 279 ++++++++++++++++-- .../presentation/LetterLogControllerTest.java | 266 ----------------- .../place/application/PlaceServiceTest.java | 68 +++++ .../naaga/place/service/PlaceServiceTest.java | 90 ------ 76 files changed, 1564 insertions(+), 1315 deletions(-) create mode 100644 android/app/src/main/java/com/now/naaga/presentation/custom/GameButton.kt create mode 100644 android/app/src/main/java/com/now/naaga/presentation/custom/GameButtonColor.kt create mode 100644 android/app/src/main/java/com/now/naaga/util/BitmapBuilder.kt delete mode 100644 android/app/src/main/res/color/selector_main_gray_purple.xml delete mode 100644 android/app/src/main/res/drawable/rect_red_white_radius_small.xml create mode 100644 android/app/src/main/res/values-night/colors.xml delete mode 100644 backend/src/main/java/com/now/naaga/letter/application/LetterFindService.java delete mode 100644 backend/src/main/java/com/now/naaga/letter/application/WriteLetterLogCreateService.java delete mode 100644 backend/src/main/java/com/now/naaga/letter/application/letterlog/ReadLetterLogService.java delete mode 100644 backend/src/main/java/com/now/naaga/letter/application/letterlog/WriteLetterLogService.java delete mode 100644 backend/src/main/java/com/now/naaga/letter/application/letterlog/dto/LetterByGameCommand.java delete mode 100644 backend/src/main/java/com/now/naaga/letter/application/letterlog/dto/LetterLogCreateCommand.java delete mode 100644 backend/src/main/java/com/now/naaga/letter/application/letterlog/dto/WriteLetterLogCreateCommand.java create mode 100644 backend/src/main/java/com/now/naaga/letter/domain/letterlog/LetterLogType.java delete mode 100644 backend/src/main/java/com/now/naaga/letter/presentation/LetterLogController.java delete mode 100644 backend/src/main/java/com/now/naaga/letter/presentation/LogType.java create mode 100644 backend/src/main/java/com/now/naaga/letter/presentation/converter/LetterLogTypeConverter.java create mode 100644 backend/src/main/java/com/now/naaga/letter/presentation/dto/FindLetterLogByGameCommand.java delete mode 100644 backend/src/test/java/com/now/naaga/letter/application/letterlog/ReadLetterLogServiceTest.java delete mode 100644 backend/src/test/java/com/now/naaga/letter/presentation/LetterLogControllerTest.java delete mode 100644 backend/src/test/java/com/now/naaga/place/service/PlaceServiceTest.java diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 798fb8e3a..db51f9120 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -5,8 +5,12 @@ - + when (throwable.code) { - DataThrowable.NETWORK_THROWABLE_CODE -> { showToast(getString(R.string.network_error_message)) } + DataThrowable.NETWORK_THROWABLE_CODE -> showToast(getString(R.string.network_error_message)) } } viewModel.preference.observe(this) { - binding.customAdventureResultPreference.updatePreference(it.state) - binding.customAdventureResultPreference.likeCount = it.likeCount.value + binding.customAdventureResultPreference.updatePreference(it) } } @@ -102,7 +101,7 @@ class AdventureResultActivity : AppCompatActivity(), AnalyticsDelegate by Defaul finish() } - binding.customAdventureResultPreference.setPreferenceClickListener { + binding.customAdventureResultPreference.setPreferenceClickListener(CLICK_INTERVAL_TIME) { viewModel.changePreference(it) } } @@ -110,6 +109,7 @@ class AdventureResultActivity : AppCompatActivity(), AnalyticsDelegate by Defaul companion object { private const val GAME_ID = "GAME_ID" private const val MESSAGE_IN_RESULT_TYPE_NONE = "네트워크에 문제가 생겼습니다." + private const val CLICK_INTERVAL_TIME = 500L fun getIntentWithGameId(context: Context, gameId: Long): Intent { return Intent(context, AdventureResultActivity::class.java).apply { diff --git a/android/app/src/main/java/com/now/naaga/presentation/adventureresult/AdventureResultViewModel.kt b/android/app/src/main/java/com/now/naaga/presentation/adventureresult/AdventureResultViewModel.kt index ceb9ce1f7..d0b6c4df3 100644 --- a/android/app/src/main/java/com/now/naaga/presentation/adventureresult/AdventureResultViewModel.kt +++ b/android/app/src/main/java/com/now/naaga/presentation/adventureresult/AdventureResultViewModel.kt @@ -97,11 +97,6 @@ class AdventureResultViewModel @Inject constructor( requireNotNull(adventureResult.value) { "adventureResult가 null입니다." }.destination.id.toInt(), requireNotNull(preference.value) { "preference가 null입니다." }.state, ) - }.onSuccess { - // post 응답이 성공적으로 왔는데 내가 보낸 것과 다른게 온 경우. 즉 말이 안되는 경우 - if (preference.value?.state != it) { - _preference.value = Preference(state = it) - } }.onFailure { _preference.value = preference.value?.revert() setThrowable(it) diff --git a/android/app/src/main/java/com/now/naaga/presentation/adventureresult/PreferenceView.kt b/android/app/src/main/java/com/now/naaga/presentation/adventureresult/PreferenceView.kt index 3a34f0f77..6a6c95414 100644 --- a/android/app/src/main/java/com/now/naaga/presentation/adventureresult/PreferenceView.kt +++ b/android/app/src/main/java/com/now/naaga/presentation/adventureresult/PreferenceView.kt @@ -5,6 +5,7 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.View import androidx.constraintlayout.widget.ConstraintLayout +import com.now.domain.model.Preference import com.now.domain.model.PreferenceState import com.now.naaga.R import com.now.naaga.databinding.CustomPreferenceViewBinding @@ -13,10 +14,12 @@ class PreferenceView(context: Context, attrs: AttributeSet? = null) : Constraint private val binding: CustomPreferenceViewBinding private val layoutInflater = LayoutInflater.from(this.context) private var preferenceClickListener: PreferenceClickListener? = null - var likeCount: Int = 0 + private var lastClickTime = 0L + private var clickIntervalTime = 0L + private var myPreference: Preference = Preference() set(value) { field = value - binding.tvPreferenceLikeCount.text = value.toString() + binding.tvPreferenceLikeCount.text = value.likeCount.value.toString() } init { @@ -37,10 +40,18 @@ class PreferenceView(context: Context, attrs: AttributeSet? = null) : Constraint private fun setClickListeners() { binding.ivPreferenceLike.setOnClickListener { - preferenceClickListener?.onClick(PreferenceState.LIKE) + singleClick(PreferenceState.LIKE) } binding.ivPreferenceDislike.setOnClickListener { - preferenceClickListener?.onClick(PreferenceState.DISLIKE) + singleClick(PreferenceState.DISLIKE) + } + } + + private fun singleClick(state: PreferenceState) { + val current = System.currentTimeMillis() + if (current - lastClickTime > clickIntervalTime) { + lastClickTime = current + preferenceClickListener?.onClick(state) } } @@ -55,12 +66,14 @@ class PreferenceView(context: Context, attrs: AttributeSet? = null) : Constraint binding.tvPreferenceLikeCount.visibility = setVisibility(isLikeCountVisible) } - fun setPreferenceClickListener(listener: PreferenceClickListener) { + fun setPreferenceClickListener(clickIntervalTime: Long = 0, listener: PreferenceClickListener) { + this.clickIntervalTime = clickIntervalTime preferenceClickListener = listener } - fun updatePreference(preferenceState: PreferenceState) { - when (preferenceState) { + fun updatePreference(preference: Preference) { + myPreference = preference + when (preference.state) { PreferenceState.LIKE -> { binding.ivPreferenceLike.isSelected = true binding.ivPreferenceDislike.isSelected = false diff --git a/android/app/src/main/java/com/now/naaga/presentation/beginadventure/BeginAdventureActivity.kt b/android/app/src/main/java/com/now/naaga/presentation/beginadventure/BeginAdventureActivity.kt index e1987b1d5..38ed14097 100644 --- a/android/app/src/main/java/com/now/naaga/presentation/beginadventure/BeginAdventureActivity.kt +++ b/android/app/src/main/java/com/now/naaga/presentation/beginadventure/BeginAdventureActivity.kt @@ -27,7 +27,7 @@ import com.now.naaga.presentation.onadventure.OnAdventureActivity import com.now.naaga.presentation.setting.SettingActivity import com.now.naaga.presentation.upload.UploadActivity import com.now.naaga.util.extension.openSetting -import com.now.naaga.util.extension.showSnackbarWithEvent +import com.now.naaga.util.extension.showShortSnackbarWithEvent import com.now.naaga.util.extension.showToast import dagger.hilt.android.AndroidEntryPoint @@ -116,7 +116,7 @@ class BeginAdventureActivity : AppCompatActivity(), AnalyticsDelegate by Default } private fun showPermissionSnackbar() { - binding.root.showSnackbarWithEvent( + binding.root.showShortSnackbarWithEvent( message = getString(R.string.snackbar_location_message), actionTitle = getString(R.string.snackbar_action_title), action = { openSetting() }, diff --git a/android/app/src/main/java/com/now/naaga/presentation/custom/GameButton.kt b/android/app/src/main/java/com/now/naaga/presentation/custom/GameButton.kt new file mode 100644 index 000000000..6e1636774 --- /dev/null +++ b/android/app/src/main/java/com/now/naaga/presentation/custom/GameButton.kt @@ -0,0 +1,153 @@ +package com.now.naaga.presentation.custom + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.Paint +import android.graphics.Point +import android.graphics.RectF +import android.util.AttributeSet +import android.view.MotionEvent +import androidx.annotation.ColorInt +import androidx.appcompat.widget.AppCompatButton +import androidx.core.content.ContextCompat +import com.now.naaga.R + +class GameButton(context: Context, attrs: AttributeSet? = null) : AppCompatButton(context, attrs) { + private val radius: Float + private var isClicked: Boolean = false + private var clickAction: OnClickListener? = null + + @ColorInt + private val mainColor: Int + + @ColorInt + val firstShadowColor: Int + + @ColorInt + val middleColor: Int + + @ColorInt + val secondShadowColor: Int + + @ColorInt + private val bottomColor: Int + + init { + context.theme.obtainStyledAttributes( + attrs, + R.styleable.GameButton, + 0, + 0, + ).apply { + radius = getDimensionPixelSize(R.styleable.GameButton_radius, 0).toFloat() + val gameButtonColor = GameButtonColor.getColor(getInteger(R.styleable.GameButton_buttonColor, 0)) + mainColor = ContextCompat.getColor(context, gameButtonColor.mainColor) + firstShadowColor = ContextCompat.getColor(context, gameButtonColor.firstShadowColor) + middleColor = ContextCompat.getColor(context, gameButtonColor.middleColor) + secondShadowColor = ContextCompat.getColor(context, gameButtonColor.secondShadowColor) + bottomColor = ContextCompat.getColor(context, gameButtonColor.bottomColor) + recycle() + } + } + + private fun getPaint(color: Int) = Paint().apply { + this.color = color + } + + private val ripplePaint = Paint().apply { + this.color = ContextCompat.getColor(this@GameButton.context, R.color.custom_button_ripple) + } + + override fun onDraw(canvas: Canvas) { + setBackgroundColor(Color.TRANSPARENT) + drawButton(canvas) + if (isClicked) drawRipple(canvas) + super.onDraw(canvas) + } + + override fun onTouchEvent(event: MotionEvent): Boolean { + when (event.action) { + MotionEvent.ACTION_DOWN -> { + isClicked = true + invalidate() + } + + MotionEvent.ACTION_UP -> { + isClicked = false + invalidate() + if (isClickInsideButton(Point(event.x.toInt(), event.y.toInt()))) { + clickAction?.onClick(this) + } + } + } + return true + } + + override fun setOnClickListener(l: OnClickListener?) { + clickAction = l + } + + private fun isClickInsideButton(point: Point): Boolean { + val isXInside = point.x in 0..this.width + val isYInside = point.y in 0..this.height + return isXInside && isYInside + } + + private fun drawRipple(canvas: Canvas) { + canvas.drawRoundRect(getBottomRect(), radius, radius, ripplePaint) + } + + private fun drawButton(canvas: Canvas) { + with(canvas) { + drawRoundRect(getBottomRect(), radius, radius, getPaint(bottomColor)) + drawRoundRect(getSecondShadowRect(), radius, radius, getPaint(secondShadowColor)) + drawRoundRect(getMiddleRect(), radius, radius, getPaint(middleColor)) + drawRoundRect(getFirstShadowRect(), radius, radius, getPaint(firstShadowColor)) + drawRoundRect(getMainRect(), radius, radius, getPaint(mainColor)) + } + } + + // 161 x 84 (0,0) + private fun getBottomRect(): RectF { + return RectF(0f, 0f, width.toFloat(), height.toFloat()) + } + + // 160 x 79 (0,0) + private fun getSecondShadowRect(): RectF { + return RectF(0f, 0f, width.toFloat(), (height * 0.94).toFloat()) + } + + // 158 x 77 (1,1) + private fun getMiddleRect(): RectF { + val middleWidth = (width * 0.987).toFloat() + val middleHeight = (height * 0.916).toFloat() + val start = (width * 0.006).toFloat() + val end = start + middleWidth + val top = (height * 0.01).toFloat() + val bottom = top + middleHeight + return RectF(start, top, end, bottom) + } + + // 155 x 72 (2,2) + private fun getFirstShadowRect(): RectF { + val width = (this.width * 0.96).toFloat() + val height = (this.height * 0.86).toFloat() + val start = (this.width * 0.018).toFloat() + val end = start + width + val top = (this.height * 0.02).toFloat() + val bottom = top + height + return RectF(start, top, end, bottom) + } + + // 154 x 70 (2,2) + private fun getMainRect(): RectF { + val width = (this.width * 0.96).toFloat() + val height = (this.height * 0.83).toFloat() + val start = (this.width * 0.018).toFloat() + val end = start + width + val top = (this.height * 0.02).toFloat() + val bottom = top + height + return RectF(start, top, end, bottom) + } +} diff --git a/android/app/src/main/java/com/now/naaga/presentation/custom/GameButtonColor.kt b/android/app/src/main/java/com/now/naaga/presentation/custom/GameButtonColor.kt new file mode 100644 index 000000000..16368bd2f --- /dev/null +++ b/android/app/src/main/java/com/now/naaga/presentation/custom/GameButtonColor.kt @@ -0,0 +1,33 @@ +package com.now.naaga.presentation.custom + +import androidx.annotation.ColorRes +import com.now.naaga.R + +enum class GameButtonColor( + @ColorRes val mainColor: Int, + @ColorRes val firstShadowColor: Int, + @ColorRes val middleColor: Int, + @ColorRes val secondShadowColor: Int, + @ColorRes val bottomColor: Int, +) { + YELLOW( + R.color.custom_button_yellow_main, + R.color.custom_button_yellow_first_shadow, + R.color.custom_button_yellow_middle, + R.color.custom_button_yellow_second_shadow, + R.color.custom_button_yellow_bottom, + ), + BLUE( + R.color.custom_button_blue_main, + R.color.custom_button_blue_first_shadow, + R.color.custom_button_blue_middle, + R.color.custom_button_blue_second_shadow, + R.color.custom_button_blue_bottom, + ), ; + + companion object { + fun getColor(ordinal: Int): GameButtonColor { + return values().find { it.ordinal == ordinal } ?: YELLOW + } + } +} diff --git a/android/app/src/main/java/com/now/naaga/presentation/onadventure/OnAdventureActivity.kt b/android/app/src/main/java/com/now/naaga/presentation/onadventure/OnAdventureActivity.kt index 95acee13e..401c6beda 100644 --- a/android/app/src/main/java/com/now/naaga/presentation/onadventure/OnAdventureActivity.kt +++ b/android/app/src/main/java/com/now/naaga/presentation/onadventure/OnAdventureActivity.kt @@ -103,7 +103,7 @@ class OnAdventureActivity : viewModel.endAdventure() } binding.ivSendLetter.setOnClickListener { - LetterSendDialog(viewModel::sendLetter).show(supportFragmentManager, LetterSendDialog.TAG) + LetterSendDialog(::registerLetter).show(supportFragmentManager, LetterSendDialog.TAG) } } @@ -145,7 +145,7 @@ class OnAdventureActivity : OnAdventureViewModel.NOT_ARRIVED -> { val remainingTryCount: Int = viewModel.adventure.value?.remainingTryCount?.toInt() ?: 0 - shortSnackbar(getString(R.string.onAdventure_retry, remainingTryCount)) + showToast(getString(R.string.onAdventure_retry, remainingTryCount)) } OnAdventureViewModel.TRY_COUNT_OVER -> showToast(getString(R.string.onAdventure_try_count_over)) @@ -203,6 +203,14 @@ class OnAdventureActivity : } } + private fun registerLetter(message: String) { + if (message.isNotEmpty()) { + viewModel.sendLetter(message) + } else { + showToast(getString(R.string.send_letter_dialog_warning)) + } + } + private fun showGiveUpDialog() { val fragment: Fragment? = supportFragmentManager.findFragmentByTag(GIVE_UP) if (fragment == null) { diff --git a/android/app/src/main/java/com/now/naaga/presentation/onadventure/OnAdventureViewModel.kt b/android/app/src/main/java/com/now/naaga/presentation/onadventure/OnAdventureViewModel.kt index a35f4ffc9..f902c648f 100644 --- a/android/app/src/main/java/com/now/naaga/presentation/onadventure/OnAdventureViewModel.kt +++ b/android/app/src/main/java/com/now/naaga/presentation/onadventure/OnAdventureViewModel.kt @@ -144,12 +144,18 @@ class OnAdventureViewModel @Inject constructor( private fun handleGameThrowable(throwable: GameThrowable) { when (throwable.code) { - TRY_COUNT_OVER -> _adventure.value = adventure.value?.copy(adventureStatus = AdventureStatus.DONE) + TRY_COUNT_OVER -> { + _adventure.value = adventure.value?.copy(adventureStatus = AdventureStatus.DONE) + _throwable.value = throwable + } NOT_ARRIVED -> { val currentRemainingTryCount = adventure.value?.remainingTryCount ?: return _adventure.value = adventure.value?.copy(remainingTryCount = currentRemainingTryCount - 1) + _throwable.value = throwable + } + else -> { + _throwable.value = throwable } - else -> { _throwable.value = throwable } } } @@ -172,14 +178,15 @@ class OnAdventureViewModel @Inject constructor( }.onSuccess { _isSendLetterSuccess.value = true }.onFailure { + setThrowable(it) } } } private fun setThrowable(throwable: Throwable) { when (throwable) { - is IOException -> { _throwable.value = DataThrowable.NetworkThrowable() } - is GameThrowable -> { handleGameThrowable(throwable) } + is IOException -> _throwable.value = DataThrowable.NetworkThrowable() + is GameThrowable -> handleGameThrowable(throwable) is UniversalThrowable -> _throwable.value = throwable } } diff --git a/android/app/src/main/java/com/now/naaga/presentation/upload/UploadActivity.kt b/android/app/src/main/java/com/now/naaga/presentation/upload/UploadActivity.kt index 5ac5a77f1..395eb2a68 100644 --- a/android/app/src/main/java/com/now/naaga/presentation/upload/UploadActivity.kt +++ b/android/app/src/main/java/com/now/naaga/presentation/upload/UploadActivity.kt @@ -6,12 +6,12 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.graphics.Bitmap -import android.graphics.BitmapFactory import android.location.Location import android.net.Uri import android.os.Build import android.os.Bundle import android.provider.MediaStore +import android.provider.Settings import android.view.View import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels @@ -20,6 +20,7 @@ import com.google.android.gms.location.LocationServices import com.google.android.gms.tasks.CancellationToken import com.google.android.gms.tasks.CancellationTokenSource import com.google.android.gms.tasks.OnTokenCanceledListener +import com.google.android.material.snackbar.Snackbar import com.now.domain.model.Coordinate import com.now.naaga.R import com.now.naaga.data.firebase.analytics.AnalyticsDelegate @@ -27,7 +28,7 @@ import com.now.naaga.data.firebase.analytics.DefaultAnalyticsDelegate import com.now.naaga.data.firebase.analytics.UPLOAD_OPEN_CAMERA import com.now.naaga.data.throwable.DataThrowable import com.now.naaga.databinding.ActivityUploadBinding -import com.now.naaga.presentation.upload.UploadViewModel.Companion.FILE_EMPTY +import com.now.naaga.util.BitmapBuilder import com.now.naaga.util.extension.openSetting import com.now.naaga.util.extension.showSnackbarWithEvent import com.now.naaga.util.extension.showToast @@ -40,43 +41,57 @@ import java.time.LocalDateTime class UploadActivity : AppCompatActivity(), AnalyticsDelegate by DefaultAnalyticsDelegate() { private lateinit var binding: ActivityUploadBinding private val viewModel: UploadViewModel by viewModels() - - private val cameraLauncher = registerForActivityResult( - ActivityResultContracts.TakePicturePreview(), - ) { bitmap -> - if (bitmap != null) { - setImage(bitmap) + private var imageUri: Uri? = null + private val cameraLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { success -> + if (!success) return@registerForActivityResult + if (imageUri == null) { + showToast(getString(R.string.upload_image_orientation_error)) + return@registerForActivityResult } + setImage(requireNotNull(imageUri) { "imageUri가 null입니다" }) } - private val requestPermissionLauncher = registerForActivityResult( - ActivityResultContracts.RequestMultiplePermissions(), - ) { permission: Map -> + private val storagePermissionLauncher = + registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> + val isGranted: Boolean = permissions.values.all { it } + if (!isGranted) { + showStoragePermissionSnackBar() + return@registerForActivityResult + } + openCamera() + } - val keys = permission.entries.map { it.key } - val isStorageRequest = storagePermissions.any { keys.contains(it) } - if (isStorageRequest) { - if (permission.entries.map { it.value }.contains(false)) { - showPermissionSnackbar(getString(R.string.snackbar_storage_message)) - } else { - openCamera() + private val locationPermissionLauncher = + registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> + val isGranted: Boolean = permissions.values.all { it } + if (!isGranted) { + showLocationPermissionSnackBar() + return@registerForActivityResult } - return@registerForActivityResult + setCoordinate() } - showPermissionSnackbar(getString(R.string.snackbar_location_message)) + + private val isStoragePermissionGranted: Boolean + get() = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { + storagePermissionsBelow28.all { checkSelfPermission(it) == PackageManager.PERMISSION_GRANTED } + } else { + true + } + + private val locationSettingLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + setCoordinate() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - binding = ActivityUploadBinding.inflate(layoutInflater) setContentView(binding.root) initViewModel() subscribe() - registerAnalytics(this.lifecycle) - setCoordinate() setClickListeners() + locationPermissionLauncher.launch(locationPermissions) + registerAnalytics(this.lifecycle) } private fun initViewModel() { @@ -115,29 +130,88 @@ class UploadActivity : AppCompatActivity(), AnalyticsDelegate by DefaultAnalytic } } + private fun setClickListeners() { + binding.ivUploadCameraIcon.setOnClickListener { + logClickEvent(getViewEntryName(it), UPLOAD_OPEN_CAMERA) + openCameraWithPermission() + } + binding.ivUploadPhoto.setOnClickListener { + logClickEvent(getViewEntryName(it), UPLOAD_OPEN_CAMERA) + openCameraWithPermission() + } + binding.ivUploadBack.setOnClickListener { + finish() + } + binding.btnUploadSubmit.setOnClickListener { + if (isFormValid().not()) { + showToast(getString(R.string.upload_error_insufficient_info_message)) + } else { + viewModel.postPlace() + } + } + } + private fun changeVisibility(view: View, status: Int) { view.visibility = status } - private fun showPermissionSnackbar(message: String) { + private fun showStoragePermissionSnackBar() { binding.root.showSnackbarWithEvent( - message = message, + message = getString(R.string.snackbar_storage_message), actionTitle = getString(R.string.snackbar_action_title), + length = Snackbar.LENGTH_LONG, action = { openSetting() }, ) } + private fun showLocationPermissionSnackBar() { + binding.root.showSnackbarWithEvent( + message = getString(R.string.snackbar_location_message), + actionTitle = getString(R.string.snackbar_action_title), + length = Snackbar.LENGTH_INDEFINITE, + action = { + val appDetailsIntent = getSettingIntent() + locationSettingLauncher.launch(appDetailsIntent) + }, + ) + } + + private fun getSettingIntent() = Intent( + Settings.ACTION_APPLICATION_DETAILS_SETTINGS, + Uri.parse("package:$packageName"), + ).addCategory(Intent.CATEGORY_DEFAULT) + + private fun setImage(uri: Uri) { + binding.ivUploadCameraIcon.visibility = View.GONE + val bitmap = getBitmap(uri) + binding.ivUploadPhoto.setImageBitmap(bitmap) + val file = saveFile(bitmap) + viewModel.setFile(file) + } + + private fun getBitmap(uri: Uri) = BitmapBuilder(uri, contentResolver) + .addScaling(RESIZE) + .setProperRotate() + .build() + + private fun saveFile(bitmap: Bitmap): File { + val tempFile = File.createTempFile(System.currentTimeMillis().toString(), ".jpeg", cacheDir) + FileOutputStream(tempFile).use { + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it) + } + return tempFile + } + private fun setCoordinate() { - if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { - val fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) - fusedLocationClient.getCurrentLocation(PRIORITY_HIGH_ACCURACY, createCancellationToken()) - .addOnSuccessListener { location -> - location.let { viewModel.setCoordinate(getCoordinate(location)) } - } - .addOnFailureListener { } - } else { - requestPermissionLauncher.launch(locationPermissions) + if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) { + showLocationPermissionSnackBar() + return } + val fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) + fusedLocationClient.getCurrentLocation(PRIORITY_HIGH_ACCURACY, createCancellationToken()) + .addOnSuccessListener { location -> + location.let { viewModel.setCoordinate(getCoordinate(location)) } + }.addOnFailureListener { } } private fun createCancellationToken(): CancellationToken { @@ -163,72 +237,28 @@ class UploadActivity : AppCompatActivity(), AnalyticsDelegate by DefaultAnalytic return (number * 10_000).toLong().toDouble() / 10_000 } - private fun setClickListeners() { - binding.ivUploadCameraIcon.setOnClickListener { - logClickEvent(getViewEntryName(it), UPLOAD_OPEN_CAMERA) - requestStoragePermission() - } - binding.ivUploadPhoto.setOnClickListener { - logClickEvent(getViewEntryName(it), UPLOAD_OPEN_CAMERA) - requestStoragePermission() - } - binding.ivUploadBack.setOnClickListener { - finish() - } - binding.btnUploadSubmit.setOnClickListener { - if (isFormValid().not()) { - showToast(getString(R.string.upload_error_insufficient_info_message)) - } else { - viewModel.postPlace() - } + private fun openCameraWithPermission() { + if (!isStoragePermissionGranted) { + storagePermissionLauncher.launch(storagePermissionsBelow28) + return } - } - - private fun requestStoragePermission() { - val permissionToRequest = storagePermissions.toMutableList() - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - return openCamera() - } - - requestPermissionLauncher.launch(permissionToRequest.toTypedArray()) + openCamera() } private fun openCamera() { - cameraLauncher.launch(null) - } - - private fun setImage(bitmap: Bitmap) { - binding.ivUploadCameraIcon.visibility = View.GONE - binding.ivUploadPhoto.setImageBitmap(bitmap) - val uri = getImageUri(bitmap) ?: Uri.EMPTY - val file = makeImageFile(uri) - viewModel.setFile(file) - } - - private fun makeImageFile(uri: Uri): File { - val bitmap = contentResolver.openInputStream(uri).use { - BitmapFactory.decodeStream(it) + imageUri = createImageUri().getOrElse { + Snackbar.make(binding.root, getString(R.string.upload_retry), Snackbar.LENGTH_SHORT).show() + return } - val tempFile = File.createTempFile("image", ".jpeg", cacheDir) ?: FILE_EMPTY - - FileOutputStream(tempFile).use { - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it) - } - return tempFile + cameraLauncher.launch(imageUri) } - private fun getImageUri(bitmap: Bitmap): Uri? { - val resolver = applicationContext.contentResolver - resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) - ?.let { imageUri -> - val outputStream = resolver.openOutputStream(imageUri) - outputStream?.use { stream -> - bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream) - } - return imageUri - } - return null + private fun createImageUri(): Result { + val imageUri: Uri = contentResolver.insert( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + contentValues, + ) ?: return Result.failure(IllegalStateException("이미지 uri를 가져오지 못했습니다.")) + return Result.success(imageUri) } private fun isFormValid(): Boolean { @@ -236,7 +266,10 @@ class UploadActivity : AppCompatActivity(), AnalyticsDelegate by DefaultAnalytic } companion object { - private val storagePermissions = arrayOf( + private const val PRIORITY_HIGH_ACCURACY = 100 + private const val RESIZE = 500 + private val storagePermissionsBelow28 = arrayOf( + Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, ) @@ -250,8 +283,6 @@ class UploadActivity : AppCompatActivity(), AnalyticsDelegate by DefaultAnalytic put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") } - const val PRIORITY_HIGH_ACCURACY = 100 - fun getIntent(context: Context): Intent { return Intent(context, UploadActivity::class.java) } diff --git a/android/app/src/main/java/com/now/naaga/presentation/upload/UploadViewModel.kt b/android/app/src/main/java/com/now/naaga/presentation/upload/UploadViewModel.kt index 17efad611..94d3f29d7 100644 --- a/android/app/src/main/java/com/now/naaga/presentation/upload/UploadViewModel.kt +++ b/android/app/src/main/java/com/now/naaga/presentation/upload/UploadViewModel.kt @@ -21,7 +21,7 @@ import javax.inject.Inject class UploadViewModel @Inject constructor( private val placeRepository: PlaceRepository, ) : ViewModel() { - private var file = FILE_EMPTY + private var file: File? = null val name = MutableLiveData() @@ -43,7 +43,7 @@ class UploadViewModel @Inject constructor( } fun isFormValid(): Boolean { - return (file != FILE_EMPTY) && (_coordinate.value != null) && (name.value != null) + return (file != null) && (_coordinate.value != null) && (name.value != null) } fun postPlace() { @@ -55,7 +55,7 @@ class UploadViewModel @Inject constructor( name = name.value.toString(), description = "", coordinate = coordinate, - file = file, + file = file!!, ) }.onSuccess { _successUpload.setValue(UploadStatus.SUCCESS) diff --git a/android/app/src/main/java/com/now/naaga/util/BitmapBuilder.kt b/android/app/src/main/java/com/now/naaga/util/BitmapBuilder.kt new file mode 100644 index 000000000..dbe8508ec --- /dev/null +++ b/android/app/src/main/java/com/now/naaga/util/BitmapBuilder.kt @@ -0,0 +1,79 @@ +package com.now.naaga.util + +import android.content.ContentResolver +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.BitmapFactory.Options +import android.graphics.Matrix +import android.net.Uri +import androidx.exifinterface.media.ExifInterface + +class BitmapBuilder( + private val imageUri: Uri, + private val contentResolver: ContentResolver, +) { + private var sampleSize: Int = 1 + private var isProperRotate: Boolean = false + + fun addScaling(resize: Int): BitmapBuilder { + val options = BitmapFactory.Options() + BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri), null, options) + + var width = options.outWidth + var height = options.outHeight + var sampleSize = 1 + while (true) { + if (width / 2 < resize || height / 2 < resize) break + width /= 2 + height /= 2 + sampleSize *= 2 + } + + this.sampleSize = sampleSize + + return this + } + + fun setProperRotate(): BitmapBuilder { + isProperRotate = true + return this + } + + fun build(): Bitmap { + val bitmap = getBitmapFromUri(Options().apply { inSampleSize = sampleSize }) + if (isProperRotate) { + return getRotatedBitmap(bitmap) + } + return bitmap + } + + private fun getBitmapFromUri(option: Options?): Bitmap { + return BitmapFactory.decodeStream( + contentResolver.openInputStream(imageUri), + null, + option, + ) ?: throw IllegalStateException("비트맵 생성에 실패했습니다.") + } + + private fun getRotatedBitmap(bitmap: Bitmap): Bitmap { + val orientation = getImageOrientation() + if (orientation == 0) return bitmap + + val matrix = Matrix() + matrix.setRotate(orientation.toFloat(), (bitmap.width / 2).toFloat(), (bitmap.height / 2).toFloat()) + return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true) + } + + private fun getImageOrientation(): Int { + val inputStream = requireNotNull(contentResolver.openInputStream(imageUri)) { "Uri로 InputStream을 여는데 실패했습니다." } + val exif = ExifInterface(inputStream) + val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1) + + return when (orientation) { + ExifInterface.ORIENTATION_ROTATE_90 -> 90 + ExifInterface.ORIENTATION_ROTATE_180 -> 180 + ExifInterface.ORIENTATION_ROTATE_270 -> 270 + else -> 0 + } + } +} diff --git a/android/app/src/main/java/com/now/naaga/util/extension/ViewExt.kt b/android/app/src/main/java/com/now/naaga/util/extension/ViewExt.kt index bf9dcf4ca..808c712df 100644 --- a/android/app/src/main/java/com/now/naaga/util/extension/ViewExt.kt +++ b/android/app/src/main/java/com/now/naaga/util/extension/ViewExt.kt @@ -4,13 +4,20 @@ import android.view.View import com.google.android.material.snackbar.BaseTransientBottomBar.ANIMATION_MODE_SLIDE import com.google.android.material.snackbar.Snackbar -fun View.showSnackbar(message: String) { - Snackbar.make(this, message, Snackbar.LENGTH_SHORT).setAnimationMode(ANIMATION_MODE_SLIDE).show() +fun View.showShortSnackbarWithEvent(message: String, actionTitle: String, action: () -> Unit) { + Snackbar.make(this, message, Snackbar.LENGTH_SHORT) + .setAction(actionTitle) { + action() + }.setAnimationMode(ANIMATION_MODE_SLIDE).show() } -fun View.showSnackbarWithEvent(message: String, actionTitle: String, action: () -> Unit) { - Snackbar.make(this, message, Snackbar.LENGTH_SHORT) +fun View.showSnackbarWithEvent(message: String, actionTitle: String, length: Int, action: () -> Unit) { + Snackbar.make(this, message, length) .setAction(actionTitle) { action() }.setAnimationMode(ANIMATION_MODE_SLIDE).show() } + +fun View.showSnackbar(message: String) { + Snackbar.make(this, message, Snackbar.LENGTH_SHORT).setAnimationMode(ANIMATION_MODE_SLIDE).show() +} diff --git a/android/app/src/main/res/color/selector_main_gray_purple.xml b/android/app/src/main/res/color/selector_main_gray_purple.xml deleted file mode 100644 index 8cfae0a47..000000000 --- a/android/app/src/main/res/color/selector_main_gray_purple.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/drawable/rect_radius_small.xml b/android/app/src/main/res/drawable/rect_radius_small.xml index c3ca54021..dadcaab82 100644 --- a/android/app/src/main/res/drawable/rect_radius_small.xml +++ b/android/app/src/main/res/drawable/rect_radius_small.xml @@ -1,5 +1,5 @@ - - - + + + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/rect_red_white_radius_small.xml b/android/app/src/main/res/drawable/rect_red_white_radius_small.xml deleted file mode 100644 index 959ac4a2c..000000000 --- a/android/app/src/main/res/drawable/rect_red_white_radius_small.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/android/app/src/main/res/layout/activity_adventure_detail.xml b/android/app/src/main/res/layout/activity_adventure_detail.xml index 6eb8d23c2..ff4b33fa7 100644 --- a/android/app/src/main/res/layout/activity_adventure_detail.xml +++ b/android/app/src/main/res/layout/activity_adventure_detail.xml @@ -54,7 +54,10 @@ android:layout_height="wrap_content" android:layout_marginHorizontal="4dp" android:layout_marginTop="@dimen/space_default_medium" - android:background="@drawable/rect_red_white_radius_small" + android:background="@drawable/rect_radius_small" + android:backgroundTint="@color/secondary" + app:tabTextColor="@color/on_secondary" + app:tabSelectedTextColor="@color/on_primary" app:layout_constraintBottom_toTopOf="@id/vp_adventure_detail" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/android/app/src/main/res/layout/activity_adventure_result.xml b/android/app/src/main/res/layout/activity_adventure_result.xml index 4a4ed4a69..b150e82df 100644 --- a/android/app/src/main/res/layout/activity_adventure_result.xml +++ b/android/app/src/main/res/layout/activity_adventure_result.xml @@ -81,7 +81,7 @@ android:layout_marginHorizontal="32dp" android:layout_marginTop="16dp" android:background="@drawable/rect_radius_small" - android:backgroundTint="@color/white" + android:backgroundTint="@color/primary" android:orientation="vertical" android:paddingHorizontal="24dp" android:paddingVertical="16dp" @@ -101,7 +101,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/adventureResult_time_description" - android:textColor="@color/main_gray" + android:textColor="@color/on_secondary" android:textSize="20sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -131,6 +131,7 @@ android:id="@+id/divider" android:layout_width="match_parent" android:layout_height="2dp" + android:backgroundTint="@color/on_primary" android:background="?android:attr/listDivider" /> + android:backgroundTint="@color/on_primary" /> + android:background="?android:attr/listDivider" + android:backgroundTint="@color/on_primary" /> - - + app:layout_constraintStart_toStartOf="parent" + tools:text="모험 시작" /> - - - - + android:paddingBottom="20dp" + android:visibility="@{viewModel.isNearby() ? View.VISIBLE : View.GONE}" + app:radius="8dp" + app:buttonColor="yellow" /> diff --git a/android/app/src/main/res/layout/activity_upload.xml b/android/app/src/main/res/layout/activity_upload.xml index ab5a7ada0..7058e7f08 100644 --- a/android/app/src/main/res/layout/activity_upload.xml +++ b/android/app/src/main/res/layout/activity_upload.xml @@ -61,7 +61,7 @@ android:layout_height="300dp" android:layout_marginTop="@dimen/space_default_large" android:background="@drawable/rect_radius_small" - android:backgroundTint="@color/white" + android:backgroundTint="@color/primary" android:scaleType="centerCrop" app:layout_constraintBottom_toTopOf="@id/tv_upload_title" app:layout_constraintEnd_toEndOf="parent" @@ -117,19 +117,20 @@ android:textSize="24sp" app:layout_constraintEnd_toEndOf="@id/v_upload_divide_line_1" app:layout_constraintStart_toStartOf="@id/v_upload_divide_line_1" - app:layout_constraintTop_toBottomOf="@id/tv_upload_title"/> + app:layout_constraintTop_toBottomOf="@id/tv_upload_title" /> - diff --git a/android/app/src/main/res/layout/custom_mypage_grid.xml b/android/app/src/main/res/layout/custom_mypage_grid.xml index c6367edb2..eb2f4e72c 100644 --- a/android/app/src/main/res/layout/custom_mypage_grid.xml +++ b/android/app/src/main/res/layout/custom_mypage_grid.xml @@ -14,7 +14,7 @@ android:layout_marginStart="18dp" android:layout_marginTop="10dp" android:text="@string/mypage_place_title" - android:textColor="@color/black" + android:textColor="@color/on_primary" android:textSize="20sp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> diff --git a/android/app/src/main/res/layout/custom_mypage_grid_empty.xml b/android/app/src/main/res/layout/custom_mypage_grid_empty.xml index 3c01f51f6..e2e48cabb 100644 --- a/android/app/src/main/res/layout/custom_mypage_grid_empty.xml +++ b/android/app/src/main/res/layout/custom_mypage_grid_empty.xml @@ -18,7 +18,7 @@ android:layout_marginStart="18dp" android:layout_marginTop="10dp" android:text="@string/mypage_place_title" - android:textColor="@color/black" + android:textColor="@color/on_primary" android:textSize="20sp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> @@ -31,7 +31,7 @@ android:paddingTop="@dimen/space_default_medium" android:paddingBottom="@dimen/space_default_large" android:text="@string/mypage_empty_description" - android:textColor="@color/main_gray" + android:textColor="@color/on_secondary" android:textSize="16sp" app:layout_constraintTop_toBottomOf="@id/tv_mypage_empty_item_title" /> diff --git a/android/app/src/main/res/layout/dialog_polaroid.xml b/android/app/src/main/res/layout/dialog_polaroid.xml index ebe4e3d22..a274afbcd 100644 --- a/android/app/src/main/res/layout/dialog_polaroid.xml +++ b/android/app/src/main/res/layout/dialog_polaroid.xml @@ -11,7 +11,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/rect_radius_large" - android:backgroundTint="@color/red_white"> + android:backgroundTint="@color/secondary"> + android:background="@drawable/rect_radius_small" + android:backgroundTint="@color/secondary"> + android:background="@drawable/rect_radius_small" + android:backgroundTint="@color/secondary"> @@ -39,7 +39,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="4dp" - android:textColor="@color/black" + android:textColor="@color/on_primary" android:textSize="16sp" android:ellipsize="end" android:maxLines="1" @@ -68,7 +68,7 @@ android:layout_height="wrap_content" android:layout_marginEnd="12dp" android:layout_marginBottom="12dp" - android:textColor="@color/main_gray" + android:textColor="@color/on_secondary" android:textSize="12sp" android:text="@{adventureResult.beginTime.toLocalDate().toString()}" app:layout_constraintBottom_toBottomOf="parent" diff --git a/android/app/src/main/res/layout/item_letter.xml b/android/app/src/main/res/layout/item_letter.xml index 6e2801156..244899d7a 100644 --- a/android/app/src/main/res/layout/item_letter.xml +++ b/android/app/src/main/res/layout/item_letter.xml @@ -12,7 +12,8 @@ android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/space_default_large" android:layout_marginTop="@dimen/space_default_medium" - android:background="@drawable/rect_red_white_radius_small"> + android:background="@drawable/rect_radius_small" + android:backgroundTint="@color/secondary" > + + + #FF000000 + #FFFFFFFF + #BDBDBD + #80989898 + + #0B0726 + #F6BF0C + #10C1FD + #E93394 + + + #232036 + #413E54 + #CCCCCC + #FFFFFFFF + + + + #4D000000 + + #FFD50C + #E3A40A + #FFB70A + #FFEE9F + #B68A21 + + + #1BCCFF + #009DDE + #0CB4F9 + #AFEDFF + #0D3A85 + diff --git a/android/app/src/main/res/values-night/themes.xml b/android/app/src/main/res/values-night/themes.xml index 2577d80c9..ed0efa736 100644 --- a/android/app/src/main/res/values-night/themes.xml +++ b/android/app/src/main/res/values-night/themes.xml @@ -2,13 +2,16 @@ - \ No newline at end of file + diff --git a/android/app/src/main/res/values/attrs.xml b/android/app/src/main/res/values/attrs.xml index 586569140..9cf31cffc 100644 --- a/android/app/src/main/res/values/attrs.xml +++ b/android/app/src/main/res/values/attrs.xml @@ -5,4 +5,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml index 4d0ba9299..6ed756c11 100644 --- a/android/app/src/main/res/values/colors.xml +++ b/android/app/src/main/res/values/colors.xml @@ -1,25 +1,36 @@ - #ff0000 + #FF000000 #FFFFFFFF - #D4A5E4 - #E3C6ED - #F6EBF9 - #FFA5E4DB #BDBDBD - #616161 #80989898 - #E4A5A5 - - #0D0C4A - #E9D1F1 - - #EAE0E0 #0B0726 #F6BF0C #10C1FD #E93394 + + #FFFFFFFF + #EAE0E0 + #616161 + #FF000000 + + + + #4D000000 + + #FFD50C + #E3A40A + #FFB70A + #FFEE9F + #B68A21 + + + #1BCCFF + #009DDE + #0CB4F9 + #AFEDFF + #0D3A85 diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 24a77863a..de53b92e0 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -62,6 +62,9 @@ 사진을 저장하는데 문제가 생겼어요! 다시 시도해주세요! 전송에 실패했어요! 다시 시도해주세요! 모든 정보를 입력해주세요. + 사진 가져오기에 실패했습니다 + 실패했습니다. 사진을 세로로 찍어보세요! + 다시 시도해 주세요! 모험 기록 @@ -146,9 +149,11 @@ 이 곳에 내용을 작성해주세요! + 내용을 1자 이상 입력해주세요! 전송하기 문제가 발생했어요. 다시 시도해주세요! + diff --git a/android/app/src/main/res/values/themes.xml b/android/app/src/main/res/values/themes.xml index f36421ca7..7fe43a01e 100644 --- a/android/app/src/main/res/values/themes.xml +++ b/android/app/src/main/res/values/themes.xml @@ -1,6 +1,6 @@ -