Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
c030dd3
1.1.2버전 develop -> release 머지합니다 (#168)
LeeYongIn0517 Oct 13, 2024
44e2126
Merge branch 'release' of https://github.com/HMOAA/HMOA_ANDROID into …
LeeYongIn0517 Oct 13, 2024
9feb75f
Delete
LeeYongIn0517 Oct 13, 2024
a48f754
Delete
LeeYongIn0517 Oct 13, 2024
066804e
Delete
LeeYongIn0517 Oct 13, 2024
7dc9e0e
Release 1.1.2 버전 업로드 - 커밋 누락된 부분 추가 푸시 (#169)
LeeYongIn0517 Oct 14, 2024
eecba5c
HotFix: 카카오 sdk 버전 업그레이드 (#170) (#171)
LeeYongIn0517 Oct 15, 2024
3fc6571
v1.1.3 업데이트 수정 (#175)
LeeYongIn0517 Oct 15, 2024
689234e
v1.1.3 업데이트 (#172)
LeeYongIn0517 Oct 15, 2024
96ace7a
동기화 (#178)
uselessnaming Oct 30, 2024
dafd989
Chore: 데이터백업설정 변경
LeeYongIn0517 Nov 4, 2024
520fbe0
Chore: 테스트 버전 업그레이드 25->27
LeeYongIn0517 Nov 4, 2024
33d04e6
Fix: 주소지 추가 오류 수정 (#180)
uselessnaming Nov 5, 2024
3768957
chore: gitignore 파일 추가
LeeYongIn0517 Nov 6, 2024
6a5f790
chore: 주석해제
LeeYongIn0517 Nov 6, 2024
3c76629
Feat: 상품 구매 여부 확인 다이얼로그 추가
LeeYongIn0517 Nov 6, 2024
9e65cfe
Feat: Hbti 설문 양옆 스크롤 기능 추가
LeeYongIn0517 Nov 6, 2024
fc4893e
Delete: 주석 삭제
LeeYongIn0517 Nov 6, 2024
62698c2
Fix: LazyColumn으로 변경 후 스크롤위치 초기화 적용
LeeYongIn0517 Nov 6, 2024
ad96af9
Feature/hbti shj (#182)
uselessnaming Nov 12, 2024
8ed4112
Refactor: isNoteSelectedData상태 업데이트 함수 수정
LeeYongIn0517 Nov 13, 2024
1dc9e41
fix: Hbti ProgressBar 리컴포지션 최적화 및 UI 버그 개선
LeeYongIn0517 Nov 13, 2024
1cace44
Design: Hbti 향료 선택화면 디테일 변경
LeeYongIn0517 Nov 13, 2024
124959d
Fix: nullable 처리 누락 수정
LeeYongIn0517 Nov 13, 2024
caacc79
Merge commit 'ad96af9dba4682f44e701d7cdaabb5b31a8d71b6'
LeeYongIn0517 Nov 14, 2024
9d04ab6
Feature/hbti 버그 및 HBTI UI 수정 (#183)
LeeYongIn0517 Nov 15, 2024
bb08512
Feat: 향료주문 과정 설명 화면 api 적용
LeeYongIn0517 Nov 19, 2024
2b4ffc0
Feat: 향료주문 과정 설명 화면 네비게이션 추가
LeeYongIn0517 Nov 19, 2024
02db089
Feat: 가격대 향수추천 결과 화면 추가
LeeYongIn0517 Nov 19, 2024
284607a
Test: 향수 추천결과 화면 UI/단위 테스트 작성
LeeYongIn0517 Nov 19, 2024
4296f93
Test: 뷰모델 변경사항 반영한 테스트 수정
LeeYongIn0517 Nov 19, 2024
81d2d72
Fix: 브랜드 이미지 삭제 반영
LeeYongIn0517 Nov 19, 2024
706377a
Design: 상단 바 패딩 불일치 수정
LeeYongIn0517 Nov 19, 2024
7a7fe0b
Merge commit '9d04ab64d8d9b6c162dca26db501a7aa072cfb1a'
LeeYongIn0517 Nov 19, 2024
d308d8e
Fix: 향수 화면의 브랜드 사진 삭제 반영
LeeYongIn0517 Nov 19, 2024
fe16e40
Feature/hbti HBTI 디자인 최종 수정 반영 (#184)
LeeYongIn0517 Nov 19, 2024
b724f3b
Design: 디자인 추가 수정
LeeYongIn0517 Nov 19, 2024
2927c68
Chore: 버전 코드 수정 27->28
LeeYongIn0517 Nov 19, 2024
54d3185
Design: 버튼 크기 작아지는 현상 수정
LeeYongIn0517 Nov 19, 2024
7178580
Feature/hbti 디자인 수정 (#185)
LeeYongIn0517 Nov 19, 2024
473a19b
Feature/hbti shj 마지막 merge (#186)
uselessnaming Nov 21, 2024
23072c9
Merge commit '473a19b92871c8b6414e4c0578430fde17027ed2'
LeeYongIn0517 Nov 21, 2024
7e58fce
Chore: 버전코드 변경 28->30
LeeYongIn0517 Nov 22, 2024
d23f0cb
Merge commit '85f22d20ee326c5194b7c8ac4864899f2e830064'
LeeYongIn0517 Nov 23, 2024
b81b182
Merge commit '3fc657177ea7fcf0d8e0f4682bb259e3471c698d'
LeeYongIn0517 Nov 26, 2024
a6f43d1
Merge commit '689234e6e6f587bcfbab8c65d25c2fcd79656418'
LeeYongIn0517 Nov 26, 2024
71e93a9
Feat: SearchTopBar Debounce 적용
LeeYongIn0517 Dec 1, 2024
c1b7248
Fix: Debounce 필터링 조건 변경
LeeYongIn0517 Dec 1, 2024
b9ec5e4
Design: 홈 글씨 align 수정
LeeYongIn0517 Dec 1, 2024
9977649
Design: 향수 이미지 패딩 추가
LeeYongIn0517 Dec 1, 2024
455fd1e
Chore: 버전코드 변경 30->31
LeeYongIn0517 Dec 1, 2024
b074256
HotFix: nullable 처리 속성 추가
LeeYongIn0517 Dec 3, 2024
14962f1
Chore: 1.2.0 버전으로 업데이트 표기 변경
LeeYongIn0517 Dec 6, 2024
3eca334
Hotfix/1.2.0 (#190)
LeeYongIn0517 Dec 6, 2024
f6e2d19
Merge commit '3eca334fd3ee3fe344dadff2169582af41f012fe' into hotfix/d…
LeeYongIn0517 Dec 10, 2024
e2de217
Chore: compiler-metrics 옵션 추가
LeeYongIn0517 Dec 14, 2024
0898f15
Chore: kotlinx-collections-immutable 추가
LeeYongIn0517 Dec 14, 2024
5131f57
Docs: 임시 주석처리
LeeYongIn0517 Dec 14, 2024
12da75e
Chore: JUnit 의존성 누락된 부분 추가
LeeYongIn0517 Dec 14, 2024
08b8330
Docs: 임시 주석처리
LeeYongIn0517 Dec 14, 2024
46dd3c4
Refactor: 데이터 클래스 및 파라미터 안정성 보완
LeeYongIn0517 Dec 14, 2024
f487dac
Chore: .kotlin 빌드파일 gitignore 추가
LeeYongIn0517 Dec 14, 2024
f9d5fc3
Chore: kotlin 버전 업그레이드 1.9.0->1.9.21
LeeYongIn0517 Dec 14, 2024
154fab6
Chore: Immutable컬렉션 및 stable marker 라이브러리 추가
LeeYongIn0517 Dec 14, 2024
246eaf4
Refactor: 데이터 클래스 안정성 개선 및 리컴포지션 최적화
LeeYongIn0517 Dec 14, 2024
12ba5cd
Merge commit '0a1600e176d082cf483ddfd2eee772fcc813e20c' into migrate/ksp
LeeYongIn0517 Dec 15, 2024
f49e04a
Fix: 리컴포지션 최적화 오류 수정
LeeYongIn0517 Dec 18, 2024
5e6018a
Chore: compose-stable-marker 라이브러리 제거
LeeYongIn0517 Dec 18, 2024
a27e69e
Chore: immutable collection 제거
LeeYongIn0517 Dec 18, 2024
4b7715f
Merge: hotifx/design(1.2.0)
LeeYongIn0517 Dec 18, 2024
74c1540
Merge commit 'aaa1c8e27d03b246e11090eef9e62d1ee1a87016' into migrate/ksp
LeeYongIn0517 Dec 18, 2024
d7c2605
Merge commit '92f65bb1133ac045b938625cfff4b83a5dcbe53b' into migrate/ksp
LeeYongIn0517 Dec 21, 2024
cd06086
Refactor: 폴더 생성 및 이동
LeeYongIn0517 Dec 21, 2024
4070db6
Chore: google inapp update 라이브러리 추가
LeeYongIn0517 Dec 21, 2024
d95d32a
Chore: 버전코드 변경
LeeYongIn0517 Dec 22, 2024
2e84ca8
Feat: 인앱 업데이트 기능 추가
LeeYongIn0517 Dec 22, 2024
f9700b2
Refactor: 기존 PagingSource -> 제네릭 PerfumePagingSource로 리팩터링
LeeYongIn0517 Dec 24, 2024
0a1d9b4
Refactor: 향수 별 댓글 페이징소스 파일 통합
LeeYongIn0517 Dec 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import java.util.Properties
import java.util.*

plugins {
alias(libs.plugins.android.application)
Expand All @@ -21,7 +21,7 @@ android {
applicationId = "com.hmoa.app"
minSdk = 26
targetSdk = 34
versionCode = 33
versionCode = 35
versionName = "1.2.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Expand Down Expand Up @@ -90,6 +90,7 @@ dependencies {
implementation(project(":core-repository"))
implementation(project(":core-common"))

implementation(libs.app.update.ktx)
implementation(libs.bootpay) //부트페이
implementation(libs.bundles.kakao.login) // kakao
implementation(libs.bundles.hilt) // hilt
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:name=".view.MainActivity"
android:exported="true"
android:theme="@style/SplashTheme"
android:launchMode="singleTask">
Expand Down Expand Up @@ -64,12 +64,12 @@
</intent-filter>
</activity> <!-- 서비스를 추가하고 인텐트 필터를 설정한다. -->
<service
android:name=".FcmAppService"
android:name=".service.FcmAppService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.hmoa.app
package com.hmoa.app.service

import android.app.Notification
import android.app.NotificationChannel
Expand All @@ -8,28 +8,36 @@ import android.content.Context
import android.content.Intent
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.hmoa.app.view.MainActivity

class FcmAppService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
}

override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)

if(remoteMessage.data.isNotEmpty()){
if (remoteMessage.data.isNotEmpty()) {
sendNotification(remoteMessage.data)
}
}
private fun sendNotification(fcmData : Map<String, String>){

private fun sendNotification(fcmData: Map<String, String>) {
val CHANNEL_DEFAULT_IMPORTANCE = "channelId"
val ONGOING_NOTIFICATION = 1

val notificationIntent = Intent(this, MainActivity::class.java).apply{
val notificationIntent = Intent(this, MainActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
putExtra("deeplink",fcmData["deeplink"])
putExtra("id",fcmData["id"])
putExtra("deeplink", fcmData["deeplink"])
putExtra("id", fcmData["id"])
}
val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
val pendingIntent = PendingIntent.getActivity(
this,
0,
notificationIntent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)

val notification = Notification.Builder(this, CHANNEL_DEFAULT_IMPORTANCE)
.setContentTitle(fcmData["title"])
Expand All @@ -41,9 +49,10 @@ class FcmAppService : FirebaseMessagingService() {

val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

val channel = NotificationChannel(CHANNEL_DEFAULT_IMPORTANCE, "HMOA Channel", NotificationManager.IMPORTANCE_DEFAULT)
val channel =
NotificationChannel(CHANNEL_DEFAULT_IMPORTANCE, "HMOA Channel", NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)

notificationManager.notify(ONGOING_NOTIFICATION, notification)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.hmoa.app
package com.hmoa.app.view

import android.Manifest
import android.content.Intent
Expand All @@ -8,6 +8,8 @@ import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Box
Expand All @@ -32,19 +34,23 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.google.android.material.snackbar.Snackbar
import com.google.android.play.core.appupdate.AppUpdateInfo
import com.google.android.play.core.appupdate.AppUpdateManager
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.android.play.core.appupdate.AppUpdateOptions
import com.google.android.play.core.install.model.AppUpdateType
import com.google.android.play.core.install.model.InstallStatus
import com.google.android.play.core.install.model.UpdateAvailability
import com.google.firebase.messaging.FirebaseMessaging
import com.hmoa.app.BuildConfig
import com.hmoa.app.navigation.SetUpNavGraph
import com.hmoa.app.viewmodel.AppViewModel
import com.hmoa.core_common.permissions
import com.hmoa.core_designsystem.BottomScreen
import com.hmoa.core_designsystem.component.HomeTopBar
import com.hmoa.core_designsystem.component.MainBottomBar
import com.hmoa.core_domain.entity.navigation.AuthenticationRoute
import com.hmoa.core_domain.entity.navigation.CommunityRoute
import com.hmoa.core_domain.entity.navigation.HPediaRoute
import com.hmoa.core_domain.entity.navigation.HomeRoute
import com.hmoa.core_domain.entity.navigation.MagazineRoute
import com.hmoa.core_domain.entity.navigation.PerfumeRoute
import com.hmoa.core_domain.entity.navigation.UserInfoRoute
import com.hmoa.core_domain.entity.navigation.*
import com.hmoa.feature_brand.navigation.navigateToBrandSearch
import com.hmoa.feature_fcm.navigateToAlarmScreen
import com.hmoa.feature_home.navigation.navigateToHome
Expand Down Expand Up @@ -86,10 +92,94 @@ class MainActivity : AppCompatActivity() {
BottomScreen.Magazine.name,
BottomScreen.MyPage.name
)
private lateinit var appUpdateManager: AppUpdateManager
private val activityResultLauncher =
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result: ActivityResult ->
handleUpdateResult(result)
}

// Displays the snackbar notification and call to action.
fun popupSnackbarForCompleteUpdate() {
Snackbar.make(
findViewById(com.hmoa.core_designsystem.R.drawable.ic_fab),
"새로운 업데이트 다운로드가 완료되었습니다.",
Snackbar.LENGTH_INDEFINITE
).apply {
setAction("재시작") { appUpdateManager.completeUpdate() }
show()
}
}

private fun checkImmediateUpdateAvailability() {
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
if (shouldTriggerImmediateUpdate(appUpdateInfo)) {
Log.d("checkUpdateAvailability", "ImemediateUpdate")
startImmediateUpdate(appUpdateInfo)
}
}.addOnFailureListener { e ->
Log.e("UpdateFlow", "Failed to check update availability", e)
}
}

private fun checkFlexibleUpdateAvailability() {
appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
if (shouldTriggerFlexibleUpdate(appUpdateInfo)) {
Log.d("checkUpdateAvailability", "ImemediateUpdate")
startFlexibleUpdate(appUpdateInfo)
if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
popupSnackbarForCompleteUpdate()
}
}
}.addOnFailureListener { e ->
Log.e("UpdateFlow", "Failed to check update availability", e)
}
}


private fun shouldTriggerImmediateUpdate(appUpdateInfo: AppUpdateInfo): Boolean {
return appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE &&
appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
}

private fun shouldTriggerFlexibleUpdate(appUpdateInfo: AppUpdateInfo): Boolean {
return appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE &&
appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)
}


private fun startImmediateUpdate(appUpdateInfo: AppUpdateInfo) {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
activityResultLauncher,
AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build()
)
}

private fun startFlexibleUpdate(appUpdateInfo: AppUpdateInfo) {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
activityResultLauncher,
AppUpdateOptions.newBuilder(AppUpdateType.FLEXIBLE).build()
)
}

private fun handleUpdateResult(result: ActivityResult) {
if (result.resultCode == RESULT_OK) {
Log.d("UpdateFlow", "Update flow completed successfully!")
} else {
Log.e("UpdateFlow", "Update flow failed! Result code: ${result.resultCode}")
// 필요시 재시도 로직 추가 가능
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen()
WindowCompat.setDecorFitsSystemWindows(window, false)

appUpdateManager = AppUpdateManagerFactory.create(this)
checkImmediateUpdateAvailability()

requestNotificationPermission()
BootpayAnalytics.init(this, BuildConfig.BOOTPAY_APPLICATION_ID)

Expand Down Expand Up @@ -162,6 +252,11 @@ class MainActivity : AppCompatActivity() {
}
}

override fun onResume() {
super.onResume()
checkFlexibleUpdateAvailability()
}

//firebase 초기 토큰 처리
private fun initializeFirebaseSetting(fcmToken: String?, onSaveFcmToken: (token: String) -> Unit) {
FirebaseMessaging.getInstance().token.addOnSuccessListener {
Expand Down Expand Up @@ -273,4 +368,4 @@ class MainActivity : AppCompatActivity() {
lifecycleScope.launch { viewModel.saveNotificationEnabled(true) }
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.hmoa.app
package com.hmoa.app.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
Expand All @@ -7,8 +7,6 @@ import com.hmoa.core_domain.repository.LoginRepository
import com.hmoa.core_model.request.FCMTokenSaveRequestDto
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

Expand Down Expand Up @@ -43,4 +41,4 @@ class AppViewModel @Inject constructor(
suspend fun saveNotificationEnabled(isEnabled: Boolean) =
viewModelScope.launch { fcmRepository.saveNotificationEnabled(isEnabled) }

}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.hmoa.feature_home

import androidx.paging.PagingSource
import androidx.paging.PagingState

class PerfumePagingSource<T : Any, R>(
private val fetcher: suspend (pageNumber: Int) -> R,
private val mapper: (R) -> List<T>
) : PagingSource<Int, T>() {

override fun getRefreshKey(state: PagingState<Int, T>): Int? {
return state.anchorPosition?.let {
state.closestPageToPosition(it)?.prevKey?.plus(1)
?: state.closestPageToPosition(it)?.nextKey?.minus(1)
}
}

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, T> {
val pageNumber = params.key ?: 0
return try {
val response = fetcher(pageNumber)
val data = mapper(response)

val prevKey = if (pageNumber > 0) pageNumber - 1 else null
val nextKey = if (data.isEmpty()) null else pageNumber + 1

LoadResult.Page(
data = data,
prevKey = prevKey,
nextKey = nextKey
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
}
Loading
Loading