Skip to content

Commit

Permalink
Merge branch 'develop' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
ldh019 committed Dec 8, 2022
2 parents a3cf6bb + c5a2099 commit 115a9f4
Show file tree
Hide file tree
Showing 75 changed files with 1,536 additions and 919 deletions.
125 changes: 117 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,127 @@
# 니차내차
**너와 나의 차량공유 플랫폼, 니차내차**
<p align="center">
<a href="https://hits.seeyoufarm.com">
<img src="https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fboostcampwm-2022%2Fandroid01-UCMC&count_bg=%236A94FF&title_bg=%232E2E2E&title=hits&edge_flat=false" />
</a>
<img src="https://img.shields.io/github/issues-pr-closed/boostcampwm-2022/android01-UCMC"/>
<img src="https://img.shields.io/github/commit-activity/w/boostcampwm-2022/android01-UCMC">
<br><br>
<img src="https://user-images.githubusercontent.com/54929665/206071312-4a92b0bb-efa6-416b-9efd-708b09cdfa12.png"/>
</p>

## 🚗 프로젝트 소개
<br>

<!-- ## 주요 기능 -->
## 🚗 너와 나의 차량 공유 플랫폼, 니차내차

**안녕하세요!** **저희는** **니차내차를 개발한** **팀 GTA입니다** 😎

지금 바로 **내 주변에 있는 차**를 빌릴 수 있어요!

**상대방과 대화**를 통해 차 대여를 문의해요!

렌트카가 부담스럽다면? **니차내차**를 이용해볼까요?

### 📚 문서
[GTA의 Wiki](https://github.com/boostcampwm-2022/android01-UCMC/wiki) 바로가기

[GTA의 프로젝트 소개](https://www.notion.so/boostcamp-wm/Android01-GTA-187240d621664d468243c57fb4387e75) 바로가기

<br>

## 🛠 기술 스택
### 개발 환경
<img src="https://img.shields.io/badge/Android-Android Marshmallow (API23)-lightgreen?logo=Android" > <img src="https://img.shields.io/badge/Kotlin-1.7.1-orange?logo=Kotlin" >

### 라이브러리
<img src="https://img.shields.io/badge/Navigation-2.5.3-lightgreen?logo=Android" > <img src="https://img.shields.io/badge/ViewPager2-1.0.0-lightgreen?logo=Android"> <img src="https://img.shields.io/badge/Pager3-3.1.1-lightgreen?logo=Android"> <img src="https://img.shields.io/badge/Kotlin Coroutine-1.6.4-orange?logo=Kotlin" > <img src="https://img.shields.io/badge/Flow-orange?logo=Kotlin" > <img src="https://img.shields.io/badge/Authentication-blue?logo=Firebase" > <img src="https://img.shields.io/badge/Cloud Firestore-blue?logo=Firebase" > <img src="https://img.shields.io/badge/Cloud Functions-blue?logo=Firebase" > <img src="https://img.shields.io/badge/Cloud Message-blue?logo=Firebase" > <img src="https://img.shields.io/badge/Github Action-222222?logo=GithubActions" > <img src="https://img.shields.io/badge/Hilt-2.44.0-lightgreen?logo=Android" > <img src="https://img.shields.io/badge/Glide-4.14.2-lightgreen" > <img src="https://img.shields.io/badge/Naver Map SDK-3.16.0-2db400?logo=Naver" > <img src="https://img.shields.io/badge/Kakao Local API-222222?logo=Kakao" > <img src="https://img.shields.io/badge/StreamChat-5.11.0-blue" > <img src="https://img.shields.io/badge/Retrofit-2.9.0-48b983" > <img src="https://img.shields.io/badge/Timber-5.0.1-986500" > <img src="https://img.shields.io/badge/ktlint-0.47.1-ff4081" >

<br>

## 👨‍👩‍👧‍👦 멤버 소개
| [김민성](https://www.github.com/minseonglove) | [이동훈](https://www.github.com/ldh019) | [진주영](https://www.github.com/juyoung0520) | [최현지](https://www.github.com/hyunji99Choi) |
| :-----: | :-----: | :-----: | :-----: |
| K006 | K034 | K053 | K058 |

## 🛠 기술 스택

## 📚 프로젝트 위키
[바로가기](https://www.github.com/boostcampwm-2022/android01-UCMC/wiki)
<br>

## 🏗️ 아키텍처

<img src="https://user-images.githubusercontent.com/54929665/206073770-22db87a8-a78a-4d2d-96fe-f45d9f7e138a.png" width=100%/><img src="https://user-images.githubusercontent.com/54929665/206073716-4ae3d9ba-9b47-4911-802e-750c279c4095.png" width=100%/>

<br>

## 📱 구성 화면

- ### 구글 계정으로 니차내차를 시작하세요!

<p align="center">
<img src="https://user-images.githubusercontent.com/54929665/206095483-92994375-24d7-4321-a056-2c45d5f35985.png" width=30%> <img src="https://user-images.githubusercontent.com/54929665/206094139-00ebcd13-5731-4ed7-8b50-957ac8a43976.jpg" width=30%>
<img src="https://user-images.githubusercontent.com/54929665/206094691-d549769f-f231-4d43-b983-8c49053571fd.jpg" width=30%>
</p>

<br>

- ### 지도에서 원하는 차를 찾을 수 있어요!

<p align="center">
<img src="https://user-images.githubusercontent.com/54929665/206090685-a4fedb7d-a584-4653-a4bd-278e0ae0239f.jpg" width=30%> <img src="https://user-images.githubusercontent.com/54929665/206096470-37a3eb10-eb12-4808-a886-da37bdfe0c61.png" width=30%>
<img src="https://user-images.githubusercontent.com/54929665/206090737-73800da2-eef9-4835-af1a-0518fcddb3b3.jpg" width=30%>
</p>

<br>

- ### 원하는 차를 대여할 수 있어요! 수락될 수도 있지만 거절될 수도 있어요~

<p align="center">
<img src="https://user-images.githubusercontent.com/54929665/206104307-299e4957-383e-48ce-867d-06fd2d906322.jpg" width=30%> <img src="https://user-images.githubusercontent.com/54929665/206108275-a6b95afd-eb1e-41ca-aa55-5e15522d3b61.jpg" width=30%>
<img src="https://user-images.githubusercontent.com/54929665/206097418-7f5ad623-fa58-4a57-bf12-7d2335796001.jpg" width=30%>
</p>

<br>

- ### 내 차를 등록하고 상세 정보를 수정할 수 있어요!

<p align="center">
<img src="https://user-images.githubusercontent.com/54929665/206100589-946faa9c-c71f-4d52-962b-183da47025c4.jpg" width=30%> <img src="https://user-images.githubusercontent.com/54929665/206097658-548d4302-5c23-48ca-8eac-84f465761397.jpg" width=30%>
<img src="https://user-images.githubusercontent.com/54929665/206100643-05f25c3f-e557-4eaf-b261-315567d790ed.jpg" width=30%>
</p>
<p align="center">
<img src="https://user-images.githubusercontent.com/54929665/206100426-5663386b-bd1b-41e4-8c28-24edb3e249e2.jpg" width=30%> <img src="https://user-images.githubusercontent.com/54929665/206099998-4a5c29fa-cc2d-430d-9519-a019ca1b8d3f.jpg" width=30%>
<img src="https://user-images.githubusercontent.com/54929665/206100003-488d06de-6e90-47bc-bf88-4f2779774182.jpg" width=30%>
</p>

<br>

- ### 차를 반납하면 감사인사를 작성해요!

<p align="center">
<img src="https://user-images.githubusercontent.com/54929665/206098346-b16430f6-42f6-4807-bc93-ed509f812388.jpg" width=30%> <img src="https://user-images.githubusercontent.com/54929665/206098249-6d1f1ce1-4664-48a2-b3af-552a035ded61.jpg" width=30%>
<img src="https://user-images.githubusercontent.com/54929665/206098257-6d30a3e7-2566-465c-8d84-02e8d2cd1a89.jpg" width=30%>
</p>

<br>

- ### 니차내차 기록을 확인해요!

<p align="center">
<img src="https://user-images.githubusercontent.com/54929665/206101980-8342deb3-4d61-48c0-9548-3311f8ac9c94.jpg" width=30%> <img src="https://user-images.githubusercontent.com/59998983/206105920-a4fee38b-4ef2-4ccd-9aec-96a5c2cac38f.png" width=30%>
<img src="https://user-images.githubusercontent.com/54929665/206102016-e7b72b4a-4b10-49b6-8654-f03e590cfb02.jpg" width=30%>
</p>

<br>

- ### 차주와 이야기를 나눠요!

<p align="center">
<img src="https://user-images.githubusercontent.com/54929665/206101094-16050755-06f8-4b0d-b55d-9205d145342a.jpg" width=30%> <img src="https://user-images.githubusercontent.com/54929665/206101099-6eb92baf-c7d4-42d3-812d-28fafcb9cf95.jpg" width=30%>
</p>

<br>

- ### 내 정보를 수정해요!

<p align="center">
<img src="https://user-images.githubusercontent.com/54929665/206106848-ae435665-2c98-44e6-8981-378271b774e4.jpg" width=30%> <img src="https://user-images.githubusercontent.com/54929665/206106875-e35ef0f4-72c3-4891-a927-adcb28709333.jpg" width=30%>
</p>

[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fboostcampwm-2022%2Fandroid01-UCMC&count_bg=%236A94FF&title_bg=%232E2E2E&title=hits&edge_flat=false)](https://hits.seeyoufarm.com)
<br>
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ buildscript {
classpath(Dependencies.Classpaths.NAVIGATION)
classpath(Dependencies.Classpaths.HILT)
classpath(Dependencies.Classpaths.CRASHLYTICS)
classpath(Dependencies.Classpaths.JUNIT5)
}
}

Expand Down
2 changes: 1 addition & 1 deletion buildSrc/src/main/java/com/gta/buildsrc/Configuration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ object Configuration {
const val minSdk = 23
const val targetSdk = 33
const val versionCode = 1
const val versionName = "0.1.0"
const val versionName = "0.2.0"
}
33 changes: 25 additions & 8 deletions buildSrc/src/main/java/com/gta/buildsrc/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ object Dependencies {
const val LOGGING_INTERCEPTER = "5.0.0-alpha.6"

// Test
const val JUNIT = "4.13.2"
const val JUNIT_EXT = "1.1.4"
const val JUNIT5_PLUGIN = "1.8.2.1"
const val JUNIT5 = "5.8.2"
const val ESPRESSO_CORE = "3.5.0"
const val MOCKITO = "4.9.0"
const val MOCKITO_KOTLIN = "4.1.0"

// Github open Library
const val INDICATOR = "4.3"
Expand All @@ -65,6 +67,8 @@ object Dependencies {
const val HILT = "com.google.dagger:hilt-android-gradle-plugin:${Versions.HILT}"
const val CRASHLYTICS =
"com.google.firebase:firebase-crashlytics-gradle:${Versions.CRASHLYTICS}"
const val JUNIT5 =
"de.mannodermaus.gradle.plugins:android-junit5:${Versions.JUNIT5_PLUGIN}"
}

object Libraries {
Expand Down Expand Up @@ -186,10 +190,6 @@ object Dependencies {
object Paging {
const val PAGING = "androidx.paging:paging-runtime:${Versions.PAGING}"
const val KTX = "androidx.paging:paging-common:${Versions.PAGING}"

fun getAll(): ArrayList<String> {
return arrayListOf(PAGING, KTX)
}
}

const val INDICATOR = "com.tbuonomo:dotsindicator:${Versions.INDICATOR}"
Expand All @@ -213,8 +213,11 @@ object Dependencies {
const val INJECT = "javax.inject:javax.inject:${Versions.INJECT}"

object Test {
const val EXT = "androidx.test.ext:junit:${Versions.JUNIT_EXT}"
const val JUNIT = "junit:junit:${Versions.JUNIT}"
const val JUNIT5_API = "org.junit.jupiter:junit-jupiter-api:${Versions.JUNIT5}"
const val JUNIT5_ENGINE = "org.junit.jupiter:junit-jupiter-engine:${Versions.JUNIT5}"
const val MOCKITO = "org.mockito:mockito-inline:${Versions.MOCKITO}"
const val MOCKITO_KOTLIN = "org.mockito.kotlin:mockito-kotlin:${Versions.MOCKITO_KOTLIN}"
const val MOCKITO_JUPITER = "org.mockito:mockito-junit-jupiter:${Versions.MOCKITO}"
}

object AndroidTest {
Expand Down Expand Up @@ -246,6 +249,14 @@ object Dependencies {
add(Paging.PAGING)
}

val dataTestLibraries = arrayListOf<String>().apply {
add(Test.MOCKITO)
add(Test.MOCKITO_KOTLIN)
add(Test.MOCKITO_JUPITER)
add(Test.JUNIT5_API)
add(Test.JUNIT5_ENGINE)
}

val dataKaptLibraries = arrayListOf<String>().apply {
add(Hilt.COMPILER)
add(Room.COMPILER)
Expand Down Expand Up @@ -310,6 +321,12 @@ fun DependencyHandler.testImplementation(list: List<String>) {
}
}

fun DependencyHandler.testRuntimeOnly(list: List<String>) {
list.forEach { dependency ->
add("testRuntimeOnly", dependency)
}
}

fun DependencyHandler.classpath(list: List<String>) {
list.forEach { dependency ->
add("classpath", dependency)
Expand Down
6 changes: 5 additions & 1 deletion data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {
id("com.google.gms.google-services")
kotlin("kapt")
id("dagger.hilt.android.plugin")
id("de.mannodermaus.android-junit5")
}

android {
Expand Down Expand Up @@ -38,6 +39,9 @@ android {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
testOptions {
unitTests.isReturnDefaultValues = true
}
}

dependencies {
Expand All @@ -48,5 +52,5 @@ dependencies {
implementation(Dependencies.Libraries.dataLibraries)
kapt(Dependencies.Libraries.dataKaptLibraries)

testImplementation(Dependencies.Libraries.Test.JUNIT)
testImplementation(Dependencies.Libraries.dataTestLibraries)
}
4 changes: 2 additions & 2 deletions data/src/main/java/com/gta/data/model/Car.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ data class Car(
val pinkSlip: PinkSlip = PinkSlip(),
val images: List<String> = emptyList(),
val price: Int = 10000,
val location: String = "동훈이 집",
val location: String = "정보 없음",
val coordinate: Coordinate = Coordinate(),
val rentState: String = RentState.UNAVAILABLE.string,
val comment: String = "차였어요",
val comment: String = "정보 없음",
val availableDate: AvailableDate = AvailableDate(),
val ownerId: String = "정보 없음"
)
Expand Down
39 changes: 27 additions & 12 deletions data/src/main/java/com/gta/data/repository/CarRepositoryImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,18 @@ import com.gta.domain.model.RentState
import com.gta.domain.model.SimpleCar
import com.gta.domain.model.UCMCResult
import com.gta.domain.model.UpdateCar
import com.gta.domain.model.UpdateFailException
import com.gta.domain.model.UserNotFoundException
import com.gta.domain.model.UserProfile
import com.gta.domain.repository.CarRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject

class CarRepositoryImpl @Inject constructor(
Expand Down Expand Up @@ -145,17 +149,24 @@ class CarRepositoryImpl @Inject constructor(
}
}

override fun setCarImagesStorage(carId: String, images: List<String>): Flow<List<String>> =
override fun setCarImagesStorage(
carId: String,
images: List<String>
): Flow<List<UCMCResult<String>>> =
callbackFlow {
val imageUri = mutableListOf<String>()
images.forEach { img ->
val image = Uri.parse(img)
val name = image.path?.substringAfterLast("/") ?: ""
storageDataSource.uploadPicture(
"car/$carId/${System.currentTimeMillis()}$name",
img
).first()?.let { uri ->
imageUri.add(uri)
val imageUri = mutableListOf<UCMCResult<String>>()
withContext(Dispatchers.IO) {
images.forEach { img ->
launch {
val image = Uri.parse(img)
val name = image.path?.substringAfterLast("/") ?: ""
storageDataSource.uploadPicture(
"car/$carId/${System.currentTimeMillis()}$name",
img
).first()?.let { uri ->
imageUri.add(UCMCResult.Success(uri))
} ?: imageUri.add(UCMCResult.Error(UpdateFailException()))
}
}
}
trySend(imageUri)
Expand All @@ -164,8 +175,12 @@ class CarRepositoryImpl @Inject constructor(

override fun deleteImagesStorage(images: List<String>): Flow<Boolean> = callbackFlow {
val result = mutableListOf<Boolean>()
images.forEach { img ->
result.add(storageDataSource.deletePicture(img).first())
withContext(Dispatchers.IO) {
images.forEach { img ->
launch {
result.add(storageDataSource.deletePicture(img).first())
}
}
}
trySend(!result.contains(false))
awaitClose()
Expand Down
27 changes: 12 additions & 15 deletions data/src/main/java/com/gta/data/repository/LoginRepositoryImpl.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.gta.data.repository

import android.content.res.Resources.NotFoundException
import com.gta.data.source.LoginDataSource
import com.gta.data.source.MessageTokenDataSource
import com.gta.data.source.UserDataSource
import com.gta.domain.model.LoginResult
import com.gta.domain.model.FirestoreException
import com.gta.domain.model.UCMCResult
import com.gta.domain.repository.LoginRepository
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.first
import javax.inject.Inject

Expand All @@ -16,27 +15,25 @@ class LoginRepositoryImpl @Inject constructor(
private val loginDataSource: LoginDataSource,
private val messageTokenDataSource: MessageTokenDataSource
) : LoginRepository {
override fun checkCurrentUser(
override suspend fun checkCurrentUser(
uid: String
): Flow<LoginResult> = callbackFlow {
): UCMCResult<Unit> {
val userInfo = userDataSource.getUser(uid).first()
if (userInfo != null) {
trySend(LoginResult.SUCCESS)
return if (userInfo != null) {
UCMCResult.Success(Unit)
} else {
trySend(LoginResult.NEWUSER)
UCMCResult.Error(NotFoundException())
}
awaitClose()
}

override fun signUp(uid: String) = callbackFlow {
override suspend fun signUp(uid: String): UCMCResult<Unit> {
val messageToken = messageTokenDataSource.getMessageToken().first()
val created = loginDataSource.createUser(uid, messageToken).first()
if (created) {
trySend(LoginResult.SUCCESS)
return if (created) {
UCMCResult.Success(Unit)
} else {
trySend(LoginResult.FAILURE)
UCMCResult.Error(FirestoreException())
}
awaitClose()
}

override suspend fun updateUserMessageToken(uid: String): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class NotificationRepositoryImpl @Inject constructor(
suspend fun getNotificationInfoDetailItem(notifyInfo: NotificationInfo): NotificationInfo {
val reservation = reservationDataSource.getReservation(notifyInfo.reservationId).first()
val from = notifyInfo.fromId
val car = reservation?.carId ?: "-"
val car = reservation?.carId ?: "정보 없음"

withContext(Dispatchers.IO) {
launch {
Expand Down
Loading

0 comments on commit 115a9f4

Please sign in to comment.