Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
2dcf3c1
[BOOK-256] feat: Firebase Analytics 의존성 추가 및 로그 이벤트 추적 환경 설정
easyhooon Aug 12, 2025
87e3261
[BOOK-256] feat: 모든 Presenter 내에 logScreenView 주입
easyhooon Aug 12, 2025
035ba2c
[BOOK-265] feat: 기록 수정, 삭제 API 정의
seoyoon513 Aug 15, 2025
329a3c2
[BOOK-264] fix: 약관 동의 화면 간격 수정
seoyoon513 Aug 15, 2025
93447c9
[BOOK-264] fix: Button 사이즈 가이드 수정
seoyoon513 Aug 15, 2025
108058b
[BOOK-264] fix: ReedDialog 간격 조건 수정
seoyoon513 Aug 15, 2025
86c3e38
[BOOK-264] fix: 도서 검색 화면 디테일 수정
seoyoon513 Aug 15, 2025
16cddb4
[BOOK-264] fix: 내서재 화면 디테일 수정
seoyoon513 Aug 15, 2025
f3b992c
[BOOK-264] fix: 내서재 검색 화면 디테일 수정
seoyoon513 Aug 15, 2025
875744e
[BOOK-264] fix: 기록 등록 디테일 수정
seoyoon513 Aug 15, 2025
210cd24
[BOOK-264] fix: 홈 화면 디테일 수정
seoyoon513 Aug 15, 2025
83aa432
[BOOK-264] fix: 도서 상세 화면 디테일 수정
seoyoon513 Aug 15, 2025
07af68c
[BOOK-264] fix: 기록 상세 화면 디테일 수정
seoyoon513 Aug 15, 2025
3720fca
[BOOK-260] feat: 스플래시 화면 네트워크 연결 에러 대응
easyhooon Aug 15, 2025
b1645f8
[BOOK-260] chore: model 모듈내 누락된 stable 어노테이션 추가
easyhooon Aug 15, 2025
12cd888
[BOOK-260] chore: update oss_licenses.json
easyhooon Aug 16, 2025
1401a84
[BOOK-260] chore: license 대문자 통일
easyhooon Aug 16, 2025
53cd427
[BOOK-260] chore: 검색어 네이밍 query로 통일
easyhooon Aug 16, 2025
e919ffb
[BOOK-260] chore: 하위 컴포저블 함수 modifier 최상위 부모꺼 사용하지 않도록 수정
easyhooon Aug 16, 2025
fabd9b2
Merge pull request #146 from YAPP-Github/BOOK-260-fix/#142
easyhooon Aug 16, 2025
16e94be
[BOOK-264] fix: 내서재 EmptyView 텍스트 중앙 정렬
seoyoon513 Aug 17, 2025
662f53a
[BOOK-264] fix: 스플래시 텍스트 중앙 정렬
seoyoon513 Aug 17, 2025
0fbfb09
[BOOK-264] fix: BookUpdateBottomSheet 디테일 수정
seoyoon513 Aug 17, 2025
96abbc7
Merge pull request #147 from YAPP-Github/BOOK-264-fix/#144
seoyoon513 Aug 17, 2025
d423869
[BOOK-265] chore: Icon 리소스 추가
seoyoon513 Aug 17, 2025
6fe16ab
[BOOK-265] feat: 기록 디테일 메뉴 바텀시트 구현
seoyoon513 Aug 17, 2025
9692b4e
[BOOK-265] refactor: 가시성 변경 public -> internal
seoyoon513 Aug 17, 2025
4719351
[BOOK-265] feat: 기록 사제 API 연동
seoyoon513 Aug 17, 2025
c744fcd
[BOOK-265] feat: 독서 기록 수정 화면 UI 구현 WIP
seoyoon513 Aug 17, 2025
ec6be51
[BOOK-265] chore: feature:edit 모듈로 분리
seoyoon513 Aug 17, 2025
b6e0b6d
[BOOK-265] feat: String Resource 추출
seoyoon513 Aug 17, 2025
7a18514
[BOOK-272] chore: 필요 없는 어노테이션 제거
easyhooon Aug 17, 2025
52c982b
[BOOK-272] chore: ErrorDialogSpec @StringRes 어노테이션 추가
easyhooon Aug 17, 2025
2f278af
[BOOK-272] refactor: 각 feature 모듈내 UiState @Immutable 어노테이션 추가
easyhooon Aug 17, 2025
ef9f144
[BOOK-265] feat: 기록 상세 -> 수정 화면으로 이동 시 args 전달
seoyoon513 Aug 17, 2025
87aaece
[BOOK-265] feat: 감정 수정 화면 UI 구현
seoyoon513 Aug 17, 2025
23a8f32
[BOOK-265] feat: 독서 기록 수정 API 연동
seoyoon513 Aug 17, 2025
c9708a9
[BOOK-265] feat: 페이지 폰트 변경
seoyoon513 Aug 17, 2025
8eb2e9a
Merge branch 'develop' into BOOK-265-feature/#145
seoyoon513 Aug 17, 2025
abc2fbb
[BOOK-265] feat: 도서 상세 RecordItem 디자인 변경사항 반영
seoyoon513 Aug 17, 2025
73b8d82
[BOOK-265] feat: RecordItem에 기록 메뉴 및 기능 연동
seoyoon513 Aug 17, 2025
e6c7b43
[BOOK-265] feat: 기록 삭제 후 리스트 업데이트
seoyoon513 Aug 17, 2025
efa6c9e
[BOOK-265] chore: 이름 변경 OnMoreMenuClick -> OnRecordMenuClick
seoyoon513 Aug 17, 2025
64c37c8
[BOOK-265] chore: code style check success
seoyoon513 Aug 17, 2025
eff679a
[BOOK-265] fix: 네비게이션 바 버튼 스타일일때 키보드와 하단 버튼 사이 간격이 벌어지는 문제 해결
easyhooon Aug 18, 2025
79777d2
[BOOK-272] chore: InfinityLazyColumn limitCount default value 상수로 통일
easyhooon Aug 18, 2025
25eded3
[BOOK-272] feat: 내 서재에 저장한 도서 삭제 API 연동
easyhooon Aug 18, 2025
dd87258
[BOOK-265] chore: 불필요한 userBookId 파라미터 제거
seoyoon513 Aug 18, 2025
fe16fdc
[BOOK-265] chore: 토끼 리뷰 반영
seoyoon513 Aug 18, 2025
977d408
[BOOK-265] refactor: 컴포넌트 생명주기에 맞춰 코루틴 관리하도록 개선
seoyoon513 Aug 18, 2025
1e15367
Merge pull request #149 from YAPP-Github/BOOK-265-feature/#145
seoyoon513 Aug 18, 2025
59b8510
Merge remote-tracking branch 'origin/develop' into BOOK-272-feature/#148
easyhooon Aug 19, 2025
71a931b
[BOOK-272] feat: 기록 화면 누락된 imePadding 적용 및 Scaffold contentWindowInse…
easyhooon Aug 19, 2025
fbceb2a
[BOOK-272] feat: 등록한 도서 삭제 기능 구현
easyhooon Aug 19, 2025
11b435a
[BOOK-272] chore: remove -> delete 삭제 워딩 통일
easyhooon Aug 19, 2025
7c0c118
[BOOK-272] chore: 로그 및 contentDescription remove -> delete 삭제 워딩 통일
easyhooon Aug 19, 2025
599e0f0
Merge pull request #153 from YAPP-Github/BOOK-272-feature/#148
easyhooon Aug 19, 2025
13e95da
[BOOK-274] feat: 앱 버전 색상 변경
easyhooon Aug 19, 2025
23cf844
[BOOK-274] feat: firebase remote config 의존성 추가 및 firebase hilt module 추가
easyhooon Aug 19, 2025
248a00a
[BOOK-274] feat: 설정 화면 내 앱 최신 버전 표기 추가
easyhooon Aug 19, 2025
501a537
[BOOK-274] fix: 파일명 오타 수정 및 잘못된 BuildConfig 참조 수정
easyhooon Aug 19, 2025
c5552a2
[BOOK-274] chore: 다시 시도 -> 다시 시도하기 워딩 변경
easyhooon Aug 20, 2025
165c773
[BOOK-274] feat: 스플래시 화면내 강제 업데이트 기능 구현
easyhooon Aug 20, 2025
c8725a8
[BOOK-274] refactor: repository 함수 호출 구문 함수화
easyhooon Aug 20, 2025
30ab43e
[BOOK-275] feat: CloudVision API 정의
seoyoon513 Aug 20, 2025
d27193c
[BOOK-273] feat: 기록 카드 화면 resource 추가
easyhooon Aug 20, 2025
5477428
[BOOK-273] fix: 독서 기록 화면 문장 입력시 키보드에 의해 문장 스캔 버튼이 가려지는 문제 해결
easyhooon Aug 20, 2025
3d54ce0
[BOOK-273] chore: 필요없는 imePadding() 제거
easyhooon Aug 20, 2025
7972082
[BOOK-273] feat: 도서 상세, 기록 상세 -> 기록 카드 화면 연결
easyhooon Aug 20, 2025
50dfa5a
[BOOK-273] feat: RecordCardPresenter, RecordCardUiState 구성
easyhooon Aug 20, 2025
85c5b78
[BOOK-273] feat: RecordCard UI 구성
easyhooon Aug 20, 2025
8e362f6
[BOOK-275] fix: DTO 필드명 수정
seoyoon513 Aug 20, 2025
98cf936
[BOOK-275] feat: Cloud Vision API 키를 BuildConfig로 관리
seoyoon513 Aug 20, 2025
6fffe0e
[BOOK-275] feat: Cloud Vision API를 사용한 문장 스캔 기능 구현
seoyoon513 Aug 20, 2025
9434d5b
[BOOK-275] feat: 로딩 중 캡처 버튼 터치 막기
seoyoon513 Aug 20, 2025
793189b
[BOOK-275] feat: 에러 핸들링 추가
seoyoon513 Aug 20, 2025
3240abc
[BOOK-273] feat: 기록 카드 저장 및 공유 구현 WIP
easyhooon Aug 20, 2025
50d7037
[BOOK-273] feat: 이미지 저장/공유 관련 확장 함수 추가
easyhooon Aug 21, 2025
fec257e
[BOOK-273] feat: 기록 카드 저장/공유 기능 구현 완료
easyhooon Aug 21, 2025
3e86cd2
[BOOK-273] fix: 중복 패딩 제거 및 문구 시안에 맞게 변경
easyhooon Aug 21, 2025
b0fd45d
[BOOK-273] fix: 카드 공유 및 저장시 radius 제거
easyhooon Aug 21, 2025
b3a3b5b
[BOOK-273] fix: 기록 카드 높이 하드코딩 제거
easyhooon Aug 21, 2025
38c27b0
[BOOK-273] feat: 공통 LoadingIndicator 추가
easyhooon Aug 21, 2025
a36945b
[BOOK-273] fix: 독서 기록 API 중복 호출 방지를 위한 LoadingIndicator 추가
easyhooon Aug 21, 2025
df82134
[BOOK-273] feat: 기록 카드 문장 maxLine 옵션 추가
easyhooon Aug 21, 2025
adc1905
[BOOK-273] fix: 감상평 기록 화면 키보드에 의해 감상평 가이드 버튼 가려지는 문제 해결
easyhooon Aug 21, 2025
65a0aed
[BOOK-273] feat: 커스텀 툴팁 적용
seoyoon513 Aug 21, 2025
4b798d7
[BOOK-275] chore: code style check success
seoyoon513 Aug 21, 2025
fbf8b14
[BOOK-275] chore: 의미 없는 chain 삭제
seoyoon513 Aug 21, 2025
14d6c15
[BOOK-275] refactor: ImmutableList 초기화 리뷰 반영
seoyoon513 Aug 21, 2025
f772c15
[BOOK-275] refactor: 쿼리 파리미터로 보낸 API 키를 헤더로 전환
seoyoon513 Aug 21, 2025
8e0f3fd
[BOOK-256] feat: Error logEvent 추가 WIP
easyhooon Aug 21, 2025
f46dee2
Merge branch 'develop' into BOOK-256-feature/#139
easyhooon Aug 21, 2025
e53d4bf
[BOOK-275] refactor: 파일 읽기 및 인코딩을 CloudOcrRecognizer에서 처리
seoyoon513 Aug 21, 2025
2ed9202
[BOOK-275] feat: 촬영 시작 시 로딩 상태 띄우기 및 캡쳐 실패 이벤트 추가
seoyoon513 Aug 21, 2025
7b3b81b
[BOOK-275] feat: 선택 문장 병합 시 띄어쓰기 제거하고 붙여서 합치도록 변경
seoyoon513 Aug 21, 2025
9c624d9
[BOOK-256] feat: 누락된 Analytics 로그 수집 함수 추가
easyhooon Aug 21, 2025
69f2ae6
[BOOK-274] feat: 설정화면 내 선택 업데이트 팝업 연동 및 스토어 이동 플로우 구현
easyhooon Aug 21, 2025
6451482
[BOOK-274] refactor: 버전 비교 관련 Util 파일 및 PlayStore 이동 관련 Context 확장 함수 추가
easyhooon Aug 21, 2025
2e0bd37
[BOOK-256] fix: logScreenView 함수 스펙 변경 및 screenView 로 잘 못 매핑된 event 바…
easyhooon Aug 21, 2025
7ebfd45
[BOOK-273] fix: 기록 카드 도서 제목 디테일 수정
seoyoon513 Aug 21, 2025
d6d399d
[BOOK-273] chore: 도서 검색, 도서 등록, 기록 등록 에러 다이얼로그 제거
seoyoon513 Aug 21, 2025
6335da8
[BOOK-273] chore: 파일명 변경
seoyoon513 Aug 21, 2025
992ff4f
[BOOK-256] fix: 토끼 리뷰 반영
easyhooon Aug 21, 2025
f0c98dc
[BOOK-273] fix: 문장 스캔, 감상평 가이드 키보드에 가려지는 문제 해결
seoyoon513 Aug 21, 2025
af02634
Merge pull request #156 from YAPP-Github/BOOK-273-feature/#150
seoyoon513 Aug 21, 2025
4b2fd58
Merge branch 'develop' into BOOK-274-feature/#151
easyhooon Aug 21, 2025
89997a3
[BOOK-275] chore: code style check success
seoyoon513 Aug 21, 2025
cac3c81
Merge pull request #154 from YAPP-Github/BOOK-274-feature/#151
easyhooon Aug 21, 2025
f01d86f
Merge pull request #155 from YAPP-Github/BOOK-275-feature/#152
seoyoon513 Aug 21, 2025
12a3361
Merge remote-tracking branch 'origin/develop' into BOOK-256-feature/#139
easyhooon Aug 21, 2025
b9b77b6
Merge branch 'develop' into BOOK-256-feature/#139
easyhooon Aug 21, 2025
9594e5e
[BOOK-288] fix: 감상평 가이드 버튼이 키보드에 가려지는 문제 해결
seoyoon513 Aug 21, 2025
cd59711
[BOOK-288] chore: 미사용 변수 제거
seoyoon513 Aug 21, 2025
2c27921
[BOOK-256] fix: merge 이후 사라진 GA 로그 복원
easyhooon Aug 21, 2025
c91acf6
[BOOK-256] fix: merge 이후 사라진 GA 로그 복원
easyhooon Aug 21, 2025
3105272
[BOOK-256] fix: 설정 화면 최종 변경 사항 반영
easyhooon Aug 21, 2025
3ae7508
[BOOK-256] chore: app version update
easyhooon Aug 21, 2025
cb634d0
[BOOK-256] feat: 기록 카드 GA 로그 추가 및 온보딩 GA 로그 변경 사항 반영
easyhooon Aug 21, 2025
7821d4e
Merge pull request #157 from YAPP-Github/BOOK-256-feature/#139
easyhooon Aug 21, 2025
eed4c86
Merge branch 'develop' into BOOK-288-fix/#158
seoyoon513 Aug 21, 2025
5a0aa4a
Merge pull request #159 from YAPP-Github/BOOK-288-fix/#158
seoyoon513 Aug 21, 2025
a1894ce
fix: cd flow 내에 versionName 추출 방식 변경
easyhooon Aug 22, 2025
d8fcc92
Merge pull request #162 from YAPP-Github/BOOK-289-chore/#161
easyhooon Aug 22, 2025
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
8 changes: 4 additions & 4 deletions .github/workflows/android-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ jobs:
- name: Generate google-services.json
run: echo '${{ secrets.GOOGLE_SERVICES }}' | base64 -d > ./app/google-services.json

- name: Extract Version Name from ApplicationConstants.kt
- name: Extract Version Name from libs.versions.toml
run: |
set -euo pipefail
VERSION=$(grep "VERSION_NAME" build-logic/src/main/kotlin/com/ninecraft/booket/convention/ApplicationConstants.kt | sed -E 's/.*VERSION_NAME\s*=\s*"([^"]+)".*/\1/')
VERSION=$(grep "versionName" gradle/libs.versions.toml | sed -E 's/.*versionName\s*=\s*"([^"]+)".*/\1/')
if [[ -z "$VERSION" ]]; then
echo "Error: ApplicationConstants.kt에서 VERSION_NAME 값을 추출하지 못했습니다." >&2
echo "Error: toml에서 versionName 값을 추출하지 못했습니다." >&2
exit 1
fi
echo "version=v${VERSION}" >> "$GITHUB_OUTPUT"
echo "Version extracted from ApplicationConstants.kt: v${VERSION}"
echo "Version extracted from toml: v${VERSION}"
id: extract_version

- name: Generate Firebase Release Note
Expand Down
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ dependencies {
projects.feature.settings,
projects.feature.splash,
projects.feature.webview,
projects.feature.edit,

libs.androidx.activity.compose,
libs.androidx.startup,
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@

</activity>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">

<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"
tools:replace="android:resource" />
</provider>

</application>

</manifest>
11 changes: 11 additions & 0 deletions app/src/main/res/xml/provider_paths.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path
name="external_files"
path="." />
<root-path
name="root"
path="." />
</paths>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import com.ninecraft.booket.convention.ApplicationConstants
import com.ninecraft.booket.convention.Plugins
import com.ninecraft.booket.convention.applyPlugins
import com.ninecraft.booket.convention.configureAndroid
import com.ninecraft.booket.convention.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
Expand All @@ -19,9 +20,9 @@ internal class AndroidApplicationConventionPlugin : Plugin<Project> {
configureAndroid(this)

defaultConfig {
targetSdk = ApplicationConstants.TARGET_SDK
versionName = ApplicationConstants.VERSION_NAME
versionCode = ApplicationConstants.VERSION_CODE
targetSdk = libs.versions.targetSdk.get().toInt()
versionName = libs.versions.versionName.get()
versionCode = libs.versions.versionCode.get().toInt()
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions build-logic/src/main/kotlin/AndroidLibraryConventionPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import com.android.build.gradle.LibraryExtension
import com.ninecraft.booket.convention.Plugins
import com.ninecraft.booket.convention.applyPlugins
import com.ninecraft.booket.convention.configureAndroid
import com.ninecraft.booket.convention.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import com.ninecraft.booket.convention.ApplicationConstants

internal class AndroidLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
Expand All @@ -19,7 +19,7 @@ internal class AndroidLibraryConventionPlugin : Plugin<Project> {
configureAndroid(this)

defaultConfig.apply {
targetSdk = ApplicationConstants.TARGET_SDK
targetSdk = libs.versions.targetSdk.get().toInt()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension

internal fun Project.configureAndroid(extension: CommonExtension<*, *, *, *, *, *>) {
extension.apply {
compileSdk = ApplicationConstants.COMPILE_SDK
compileSdk = libs.versions.compileSdk.get().toInt()

defaultConfig {
minSdk = ApplicationConstants.MIN_SDK
minSdk = libs.versions.minSdk.get().toInt()
}

compileOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ package com.ninecraft.booket.convention
import org.gradle.api.JavaVersion

internal object ApplicationConstants {
const val MIN_SDK = 28
const val TARGET_SDK = 35
const val COMPILE_SDK = 35
const val VERSION_CODE = 3
const val VERSION_NAME = "1.0.0"
const val JAVA_VERSION_INT = 17
val javaVersion = JavaVersion.VERSION_17
}
10 changes: 10 additions & 0 deletions core/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ plugins {

android {
namespace = "com.ninecraft.booket.core.common"

buildFeatures {
buildConfig = true
}

defaultConfig {
buildConfigField("String", "PACKAGE_NAME", "\"${libs.versions.packageName.get()}\"")
}
}

dependencies {
Expand All @@ -18,6 +26,8 @@ dependencies {

libs.kotlinx.collections.immutable,

platform(libs.firebase.bom),
libs.firebase.analytics,
libs.logger,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.ninecraft.booket.core.common.analytics

import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.logEvent
import com.orhanobut.logger.Logger
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class AnalyticsHelper @Inject constructor(
private val firebaseAnalytics: FirebaseAnalytics,
) {

fun logScreenView(screenName: String) {
Logger.d("Analytics - Screen View: $screenName")
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) {
param(FirebaseAnalytics.Param.SCREEN_NAME, screenName)
}
}

fun logEvent(eventName: String) {
Logger.d("Analytics - Event: $eventName")
firebaseAnalytics.logEvent(eventName) {}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.ninecraft.booket.core.common.analytics.di

import com.google.firebase.Firebase
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.analytics
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object AnalyticsModule {

@Provides
@Singleton
fun provideFirebaseAnalytics(): FirebaseAnalytics {
return Firebase.analytics
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.ninecraft.booket.core.common.constants

import androidx.annotation.StringRes

data class ErrorDialogSpec(
val message: String,
val buttonLabel: String,
@StringRes val buttonLabelResId: Int,
val action: () -> Unit,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.ninecraft.booket.core.common.extensions

import android.content.ContentValues
import android.content.Context
import android.content.Intent
import androidx.core.net.toUri
import com.ninecraft.booket.core.common.BuildConfig
import android.graphics.Bitmap
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.core.app.ShareCompat
import androidx.core.content.FileProvider
import com.orhanobut.logger.Logger
import java.io.File

@Suppress("TooGenericExceptionCaught")
fun Context.externalShareForBitmap(bitmap: ImageBitmap) {
try {
val file = File(bitmap.saveToDisk(this))
val uri = FileProvider.getUriForFile(this, "$packageName.provider", file)

ShareCompat.IntentBuilder(this)
.setStream(uri)
.setType("image/png")
.startChooser()
} catch (e: Exception) {
Logger.e("[externalShareFoBitmap] message: ${e.message}")
}
}

@Suppress("TooGenericExceptionCaught")
fun Context.saveImageToGallery(bitmap: ImageBitmap) {
try {
val fileName = "reed_record_${System.currentTimeMillis()}.png"
val contentValues = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
put(MediaStore.Images.Media.MIME_TYPE, "image/png")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
put(MediaStore.Images.Media.IS_PENDING, 1)
}
}

val imageUri =
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
imageUri?.let { uri ->
contentResolver.openOutputStream(uri)?.use { outputStream ->
bitmap.asAndroidBitmap().compress(Bitmap.CompressFormat.PNG, 100, outputStream)
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentValues.clear()
contentValues.put(MediaStore.Images.Media.IS_PENDING, 0)
contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: Exception) {
Logger.e("Failed to save image to gallery: ${e.message}")
}
}

fun Context.openPlayStore() {
val intent =
Intent(Intent.ACTION_VIEW, "market://details?id=${BuildConfig.PACKAGE_NAME}".toUri())
startActivity(intent)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.ninecraft.booket.core.common.extensions

import android.content.Context
import android.graphics.Bitmap
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import java.io.File
import java.io.FileOutputStream

fun ImageBitmap.saveToDisk(context: Context): String {
val fileName = "shared_image_${System.currentTimeMillis()}.png"
val cachePath = File(context.cacheDir, "images").also { it.mkdirs() }
val file = File(cachePath, fileName)
val outputStream = FileOutputStream(file)

asAndroidBitmap().compress(Bitmap.CompressFormat.PNG, 100, outputStream)
outputStream.flush()
outputStream.close()

return file.absolutePath
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import androidx.compose.material3.ripple
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.graphics.layer.GraphicsLayer
import androidx.compose.ui.graphics.layer.drawLayer
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.semantics.Role
import com.ninecraft.booket.core.common.utils.MultipleEventsCutter
Expand Down Expand Up @@ -45,3 +48,9 @@ fun Modifier.clickableSingle(
interactionSource = remember { MutableInteractionSource() },
)
}

fun Modifier.captureToGraphicsLayer(graphicsLayer: GraphicsLayer) =
this.drawWithContent {
graphicsLayer.record { this@drawWithContent.drawContent() }
drawLayer(graphicsLayer)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.ninecraft.booket.core.common.util

import com.orhanobut.logger.Logger

/**
* 두 버전을 비교하는 함수
*
* @param version1 첫 번째 버전 (예: "1.2.3")
* @param version2 두 번째 버전 (예: "1.1.0")
* @return 양수면 version1 > version2, 음수면 version1 < version2, 0이면 같음
*
* 버전 형식: "메이저.마이너.패치" (예: 1.2.3)
* 비교 순서: 메이저 → 마이너 → 패치 버전 순으로 비교
*/
fun compareVersions(version1: String, version2: String): Int {
Logger.d("compareVersions: version1: $version1, version2: $version2")

if (!Regex("""^\d+\.\d+\.\d+$""").matches(version1)) return 0
if (!Regex("""^\d+\.\d+\.\d+$""").matches(version2)) return 0

val v1 = version1.split('.').map { it.toInt() }
val v2 = version2.split('.').map { it.toInt() }

// 메이저 버전 비교
if (v1[0] != v2[0]) return v1[0] - v2[0]

// 마이너 버전 비교
if (v1[1] != v2[1]) return v1[1] - v2[1]

// 패치 버전 비교
return v1[2] - v2[2]
}

/**
* 현재 앱 버전이 최소 요구 버전보다 낮은지 확인하는 함수
*
* @param currentVersion 현재 앱의 버전 (예: "1.0.0")
* @param minVersion 최소 요구 버전 (Firebase Remote Config에서 가져온 값)
* @return true면 강제 업데이트 필요 (현재 버전 < 최소 요구 버전), false면 업데이트 불필요
*/
fun isUpdateRequired(currentVersion: String, minVersion: String): Boolean {
return compareVersions(currentVersion, minVersion) < 0
}
Loading
Loading