-
Notifications
You must be signed in to change notification settings - Fork 71
[쇼핑 주문 1, 2 단계] 채넛 미션 제출합니다. #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 60 commits
9491751
6fd0c59
0242a92
a1e32f3
93c5625
1d527b6
949faca
68942a7
c424b03
55bcfad
8360a5a
efc862f
964322c
03de383
090d259
a5afd94
f3ba211
cc27cf6
469378d
45c2a2e
f724ce7
23d7203
2798f71
5b4fed6
ff43839
c25bee9
8e37ee4
8ff681d
b4f8717
0259668
f595b15
826ead7
3b66582
bed9198
5372d4e
7a9be3c
25aa63e
3e16618
027b436
630c09a
9056075
99aca11
3d3e024
58fe555
ebf8407
4e4ce8a
ae28f7e
ea1e189
8fc3280
b32877d
5be76b0
66da204
83d6b87
5e31972
4fa0980
7a433be
e7c544a
0e2624c
ad24a87
87d5ddf
081c4a1
d5b4e12
f0c976a
3f5bf71
c7d6ae2
3fecd89
8973ede
b2fe948
5beb5ce
1a40367
a6e7876
07ce825
380a7e6
e37bf98
2439382
ef42285
07c800d
0c5b01e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,17 @@ | ||
# android-shopping-order | ||
# android-shopping-order | ||
|
||
### 1단계 기능 목록 | ||
|
||
- [x] 데이터가 로딩되기 전 상태에서는 스켈레톤 UI를 노출한다. | ||
- [x] 서버를 연동한다. | ||
- [x] 사용자 인증 정보를 저장한다. | ||
|
||
### 2단계 기능 목록 | ||
|
||
- [x] 장바구니 화면에서 특정 상품만 골라 주문하기 버튼을 누를 수 있다. | ||
- [x] 별도의 화면에서 상품 추천 알고리즘으로 사용자에게 적절한 상품을 추천해준다. (쿠팡 UX 참고) | ||
- [x] 상품 추천 알고리즘은 최근 본 상품 카테고리를 기반으로 최대 10개 노출한다. | ||
- [x] 예를 들어 가장 최근에 본 상품이 fashion 카테고리라면, fashion 상품 10개 노출 | ||
- [x] 해당 카테고리 상품이 10개 미만이라면 해당하는 개수만큼만 노출 | ||
- [x] 장바구니에 이미 추가된 상품이라면 미노출 | ||
- [x] 추천된 상품을 해당 화면에서 바로 추가하여 같이 주문할 수 있다. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
import java.util.Properties | ||
|
||
plugins { | ||
alias(libs.plugins.android.application) | ||
alias(libs.plugins.android.junit5) | ||
alias(libs.plugins.kotlin.android) | ||
id("kotlin-kapt") | ||
alias(libs.plugins.serialization) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Gson, Moshi 와 같은 라이브러리들과 어떤 차이점이 있을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 좋습니다 👍 |
||
} | ||
|
||
android { | ||
|
@@ -43,8 +46,20 @@ android { | |
excludes += "win32-x86*/**" | ||
} | ||
} | ||
defaultConfig { | ||
val localProperties = | ||
Properties().apply { | ||
load(File(rootDir, "local.properties").inputStream()) | ||
} | ||
val id = localProperties["id"] as String | ||
val pw = localProperties["password"] as String | ||
|
||
buildConfigField("String", "ID", "\"$id\"") | ||
buildConfigField("String", "PASSWORD", "\"$pw\"") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BuildConfig 활용 좋습니다 👍 |
||
} | ||
buildFeatures { | ||
dataBinding = true | ||
buildConfig = true | ||
} | ||
} | ||
|
||
|
@@ -67,15 +82,21 @@ dependencies { | |
kapt(libs.androidx.room.compiler) | ||
|
||
// remote | ||
implementation(libs.converter.gson) | ||
implementation(libs.mockwebserver) | ||
implementation(libs.logging.interceptor) | ||
implementation(libs.kotlinx.serialization.json) | ||
implementation(libs.retrofit) | ||
implementation(libs.retrofit2.kotlinx.serialization.converter) | ||
|
||
// shimmer | ||
implementation(libs.shimmer) | ||
|
||
testImplementation(libs.assertj.core) | ||
testImplementation(libs.junit.jupiter) | ||
testImplementation(libs.kotest.runner.junit5) | ||
testImplementation(libs.mockk) | ||
testImplementation(libs.mockwebserver) | ||
testImplementation(libs.json) | ||
|
||
androidTestImplementation(libs.androidx.espresso.core) | ||
androidTestImplementation(libs.androidx.test.ext.junit) | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,17 @@ | ||
package woowacourse.shopping | ||
|
||
import android.app.Application | ||
import android.util.Log | ||
import okhttp3.mockwebserver.MockWebServer | ||
import woowacourse.shopping.data.remote.ProductMockWebServerDispatcher | ||
import woowacourse.shopping.data.datasource.local.UserPreference | ||
import woowacourse.shopping.di.DataSourceModule | ||
import woowacourse.shopping.di.DatabaseModule | ||
import java.io.IOException | ||
import woowacourse.shopping.di.RepositoryModule | ||
|
||
class ShoppingApplication : Application() { | ||
private val mockWebServer = MockWebServer() | ||
|
||
override fun onCreate() { | ||
super.onCreate() | ||
startMockServer() | ||
DatabaseModule.init(this) | ||
DataSourceModule.init(this) | ||
} | ||
|
||
override fun onTerminate() { | ||
super.onTerminate() | ||
mockWebServer.shutdown() | ||
} | ||
|
||
private fun startMockServer() { | ||
Thread { | ||
try { | ||
mockWebServer.dispatcher = ProductMockWebServerDispatcher | ||
mockWebServer.start(PORT_NUMBER) | ||
Log.d("ShoppingApplication", "MockWebServer started on port $PORT_NUMBER") | ||
} catch (e: IOException) { | ||
Log.e("ShoppingApplication", "Failed to start MockWebServer", e) | ||
} | ||
}.start() | ||
} | ||
|
||
companion object { | ||
private const val PORT_NUMBER = 1999 | ||
RepositoryModule.init(this) | ||
UserPreference.init(this) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,10 +7,13 @@ import woowacourse.shopping.domain.model.CartItem | |
class CartItemMapper( | ||
private val productDataSource: ProductDataSource, | ||
) { | ||
fun toDomain(data: CartEntity): CartItem { | ||
val product = productDataSource.fetchProductById(data.productId) | ||
return CartItem(product, data.quantity) | ||
} | ||
// fun toDomain(data: CartEntity): CartItem { | ||
// productDataSource.fetchProductById(data.productId){ result -> | ||
// result. | ||
// } | ||
// return CartItem(product, data.quantity) | ||
// } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 사용하지 않는 코드인걸까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
|
||
fun toData(domain: CartItem): CartEntity = | ||
CartEntity( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
상품목록에서 한가지 궁금한게 있어요.
이미지가 같은 상품에 대해서,
그 중 하나의 상품 개수를 증가시켰을 때, 이미지가 같은 상품들이 함께 깜빡이는 이슈가 있습니다.
어떤 이유이고 어떻게 개선할 수 있을까요?
screencapture-1748594987448.mp4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이미지 정보가 없거나 문제가 있는 상품일 경우 Glide 설정에서 모두 동일한 drawable을 넣었습니다.
구현 당시에는 notifyDataSetChanged() 를 호출하며 전체를 갱신하다보니 동일한 이미지 소스에 애니메이션이 들어갔지 않나 하는 추측을 해보았습니다.
이 리뷰를 보기 전에 ListAdapter 로 수정해버려 위와 같은 문제가 발생하지 않아 정확한 원인을 찾지는 못했습니다. 🥲