Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
148 changes: 148 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Reed - 문장과 감정을 함께 담는 독서 기록

[![Kotlin](https://img.shields.io/badge/Kotlin-2.2.0-blue.svg)](https://kotlinlang.org)
[![Gradle](https://img.shields.io/badge/gradle-8.11.1-green.svg)](https://gradle.org/)
[![Android Studio](https://img.shields.io/badge/Android%20Studio-2025.1.2%20%28Narwhal%29-green)](https://developer.android.com/studio)
[![minSdkVersion](https://img.shields.io/badge/minSdkVersion-28-red)](https://developer.android.com/distribute/best-practices/develop/target-sdk)
[![targetSdkVersion](https://img.shields.io/badge/targetSdkVersion-35-orange)](https://developer.android.com/distribute/best-practices/develop/target-sdk)
![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/YAPP-Github/Reed-Android?utm_source=oss&utm_medium=github&utm_campaign=YAPP-Github%2FReed-Android&labelColor=171717&color=FF570A&link=https%3A%2F%2Fcoderabbit.ai&label=CodeRabbit+Reviews)
<br/>
<img width="1024" height="500" alt="reed_graphic" src="https://github.com/user-attachments/assets/357cab12-db36-4de0-8fad-664abc5df8c8" />

<a href="https://play.google.com/store/apps/details?id=com.ninecraft.booket&hl=ko">
<img src="https://github.com/user-attachments/assets/8699ffd3-3399-45eb-9e2b-88818ba62091" width="200" />
</a>
Comment on lines +12 to +14
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Google Play 스토어 링크 유효성 확인

패키지 ID(com.ninecraft.booket)와 실제 배포 앱이 일치하는지 확인 필요. 미출시/변경 시 사용자를 404로 유도할 수 있습니다.


🌐 Web query:

현재 Google Play에 com.ninecraft.booket 패키지의 공개 스토어 페이지가 존재하는지 확인해 주세요. 존재하지 않으면 링크를 제거하거나 올바른 패키지 ID로 교체하세요.

💡 Result:

검색해봤습니다 — com.ninecraft.booket 패키지의 공개 Google Play 스토어 페이지는 찾을 수 없습니다. 링크가 있다면 제거하거나 올바른 패키지 ID로 교체하세요. 올바른 패키지 ID를 알려주시면 제가 다시 확인해 드리겠습니다.


Google Play 스토어 링크 제거 또는 올바른 패키지 ID로 교체

README.md (12–14)에서 com.ninecraft.booket 패키지에 해당하는 앱이 존재하지 않아 링크가 404를 반환합니다. 링크를 제거하거나 실제 배포된 앱의 올바른 패키지 ID로 교체해 주세요.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

13-13: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
In README.md around lines 12 to 14, the Google Play link points to package id
com.ninecraft.booket which returns 404; either remove the anchor and image or
replace the href with the correct Play Store package id for the app (and update
the image src if needed), ensuring the link targets an existing app and that the
badge image still displays correctly.

Comment on lines +13 to +14
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Google Play 배지에 alt 추가 (접근성/MD045)

링크 내부 이미지에 alt가 없습니다. 접근성과 markdownlint(MD045) 충족을 위해 alt를 추가하세요.

 <a href="https://play.google.com/store/apps/details?id=com.ninecraft.booket&hl=ko">
-    <img src="https://github.com/user-attachments/assets/8699ffd3-3399-45eb-9e2b-88818ba62091" width="200" />
+    <img alt="Get it on Google Play" src="https://github.com/user-attachments/assets/8699ffd3-3399-45eb-9e2b-88818ba62091" width="200" />
 </a>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<img src="https://github.com/user-attachments/assets/8699ffd3-3399-45eb-9e2b-88818ba62091" width="200" />
</a>
<a href="https://play.google.com/store/apps/details?id=com.ninecraft.booket&hl=ko">
<img alt="Get it on Google Play" src="https://github.com/user-attachments/assets/8699ffd3-3399-45eb-9e2b-88818ba62091" width="200" />
</a>
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

13-13: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
In README.md around lines 13-14, the <img> tag inside the link is missing an alt
attribute which violates accessibility and markdownlint MD045; add a concise,
descriptive alt attribute to the image (e.g., "Get it on Google Play" or an
appropriate Korean equivalent) so the <img> element reads alt="..." and
satisfies accessibility and the linter.


<p align="center">
<img src="https://github.com/user-attachments/assets/f31d5681-bbf0-4de4-93a6-37a2adf54df7" width="30%"/>
<img src="https://github.com/user-attachments/assets/db92e159-091d-425b-8cc2-2324d4191463" width="30%"/>
<img src="https://github.com/user-attachments/assets/5fd3f726-f493-4850-9d99-3933815dcd8b" width="30%"/>
</p>
<p align="center">
<img src="https://github.com/user-attachments/assets/bb7e3281-c7e4-453d-a921-cc4e9a051434" width="30%"/>
<img src="https://github.com/user-attachments/assets/7c211781-58e5-4413-9f20-f92b1d0c8f24" width="30%"/>
</p>
Comment on lines +17 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

이미지에 대체 텍스트(alt) 추가

접근성과 SEO, 그리고 markdownlint(MD045) 규칙을 위해 <img>에 alt 속성을 추가하세요.

-<img src="https://github.com/user-attachments/assets/f31d5681-bbf0-4de4-93a6-37a2adf54df7" width="30%"/>
-<img src="https://github.com/user-attachments/assets/db92e159-091d-425b-8cc2-2324d4191463" width="30%"/>
-<img src="https://github.com/user-attachments/assets/5fd3f726-f493-4850-9d99-3933815dcd8b" width="30%"/>
+<img alt="screenshot-1" src="https://github.com/user-attachments/assets/f31d5681-bbf0-4de4-93a6-37a2adf54df7" width="30%"/>
+<img alt="screenshot-2" src="https://github.com/user-attachments/assets/db92e159-091d-425b-8cc2-2324d4191463" width="30%"/>
+<img alt="screenshot-3" src="https://github.com/user-attachments/assets/5fd3f726-f493-4850-9d99-3933815dcd8b" width="30%"/>

-<img src="https://github.com/user-attachments/assets/bb7e3281-c7e4-453d-a921-cc4e9a051434" width="30%"/>
-<img src="https://github.com/user-attachments/assets/7c211781-58e5-4413-9f20-f92b1d0c8f24" width="30%"/>
+<img alt="screenshot-4" src="https://github.com/user-attachments/assets/bb7e3281-c7e4-453d-a921-cc4e9a051434" width="30%"/>
+<img alt="screenshot-5" src="https://github.com/user-attachments/assets/7c211781-58e5-4413-9f20-f92b1d0c8f24" width="30%"/>

-|<img width="144" src="https://github.com/user-attachments/assets/7e54768a-ce44-421d-8c03-9df7d0492855">|<img width="144" src="https://github.com/user-attachments/assets/a6cea688-cf9b-41ad-a3a0-9a0c11775fa2">|
+|<img alt="easyhooon-avatar" width="144" src="https://github.com/user-attachments/assets/7e54768a-ce44-421d-8c03-9df7d0492855">|<img alt="seoyoon513-avatar" width="144" src="https://github.com/user-attachments/assets/a6cea688-cf9b-41ad-a3a0-9a0c11775fa2">|

Also applies to: 96-96

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

14-14: Images should have alternate text (alt text)

(MD045, no-alt-text)


15-15: Images should have alternate text (alt text)

(MD045, no-alt-text)


16-16: Images should have alternate text (alt text)

(MD045, no-alt-text)


19-19: Images should have alternate text (alt text)

(MD045, no-alt-text)


20-20: Images should have alternate text (alt text)

(MD045, no-alt-text)

🤖 Prompt for AI Agents
In README.md around lines 14 to 21 (also apply same change at line 96), the
<img> tags are missing alt attributes which breaks accessibility, SEO and
markdownlint rule MD045; add an alt attribute to each <img> tag (use a short,
meaningful description of the image for content images, or alt="" for purely
decorative images) so each tag becomes <img src="..." alt="descriptive text"
...>, and ensure alt text is concise and relevant.


## Features
| 홈 | 도서 검색 및 등록 | 내서재 |
|:---:|:---:|:---:|
| <img width="230" alt="홈" src="https://github.com/user-attachments/assets/657e14e1-e578-4d7c-8c38-3591d61b1429" /> | <img width="230" alt="도서 검색 및 등록" src="https://github.com/user-attachments/assets/7a166abf-1160-4cdf-8ec5-f8071d7f0891" /> | <img width="230" alt="내서재" src="https://github.com/user-attachments/assets/d4679cd4-0188-4763-9adc-e210bef44ef0" /> |

| OCR | 기록 등록 | 도서 & 기록 상세 |
|:---:|:---:|:---:|
| <img width="230" alt="OCR" src="https://github.com/user-attachments/assets/8861b7ea-a0f6-4e26-91be-c15450259752" /> | <img width="230" alt="기록 등록" src="https://github.com/user-attachments/assets/32774861-c9fa-439c-a889-ccbc842eb528" /> | <img width="230" alt="도서 & 기록 상세" src="https://github.com/user-attachments/assets/34304a37-7de1-4876-bd55-f041077b3266" /> |

| 기록 카드 공유 |
|:---:|
| <img width="230" alt="기록 카드 공유" src="https://github.com/user-attachments/assets/4c01a5ed-e5a2-4be4-b950-96a457c87ad7" /> |

## TroubleShooting
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

섹션 제목 표기 통일: Troubleshooting

일반 표기 "Troubleshooting" 권장. 앵커/목차 자동생성 시 일관성 좋아집니다.

-## TroubleShooting
+## Troubleshooting
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## TroubleShooting
## Troubleshooting
🤖 Prompt for AI Agents
In README.md around lines 25 to 25, the section title uses "TroubleShooting"
which is inconsistent with the common "Troubleshooting" casing; rename the
header to "Troubleshooting" (capital T only) to ensure consistent section titles
and stable autogenerated anchors/TOC.

- [[Compose] M3 ModalBottomSheet 드래그(터치 이벤트) 막는 법](https://velog.io/@mraz3068/Compose-M3-ModalBottomSheet-Drag-Disabled)
- [Circuit 찍먹해보기(부제: Circuit 희망편)](https://speakerdeck.com/easyhooon/circuit-jjigmeoghaebogi-buje-circuit-hyimangpyeon)
- [Circuit 찍먹해보기(부제: Circuit 절망편)](https://speakerdeck.com/easyhooon/circuit-jjigmeoghaebogi-buje-circuit-jeolmangpyeon)
- [Jetpack Compose에서 CameraX + MLKit으로 OCR을 구현해보자](https://velog.io/@syoon513/Jetpack-Compose%EC%97%90%EC%84%9C-CameraX-MLKit%EC%9C%BC%EB%A1%9C-OCR%EC%9D%84-%EA%B5%AC%ED%98%84%ED%95%B4%EB%B3%B4%EC%9E%90)
- [[Android] 일회성 이벤트를 StateFlow, Compose의 State로 처리할 때 주의해야할 점](https://velog.io/@mraz3068/Handle-One-Time-Event-As-State)
- [Circuit Navigation 사용 시 feature 모듈간의 참조는 어떻게 해결했을까?](https://velog.io/@syoon513/Circuit-Navigation-%EC%82%AC%EC%9A%A9-%EC%8B%9C-feature-%EB%AA%A8%EB%93%88%EA%B0%84-%EC%88%9C%ED%99%98-%EC%B0%B8%EC%A1%B0%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%95%B4%EA%B2%B0%ED%96%88%EC%9D%84%EA%B9%8C)
- [Coroutine 에러 처리 패턴: 여러 API 호출을 한 번에 성공/실패 판정하기](https://velog.io/@syoon513/Coroutine-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC)
- [[Circuit] ImpressionEffect](https://velog.io/@mraz3068/Circuit-ImpressionEffect)
- [Coroutine CancellationException 따로 처리해야하는 케이스](https://velog.io/@mraz3068/Coroutine-CancellationException-UseCase)

## Development

### Required

- IDE : Android Studio 최신 버전
- JDK : Java 17을 실행할 수 있는 JDK
- (권장) Android Studio 설치 시 Embedded 된 JDK (Open JDK)
- Java 17을 사용하는 JDK (Open JDK, AdoptOpenJDK, GraalVM)
- Kotlin Language : 2.2.0

### Language

- Kotlin

### Libraries

- AndroidX
- Activity Compose
- Core
- DataStore
- StartUp
- Splash
- CameraX

- Kotlin Libraries (Coroutine, Serialization, Immutable Collection)
- Compose
- Material3

- [Circuit](https://github.com/slackhq/circuit)
- ~~Google ML Kit~~ Google Cloud Vision
- Dagger Hilt
- Retrofit, OkHttp3
- Lottie-Compose
- Firebase(Analytics, Crashlytics, Remote Config)
- Kakao-Auth
- [Logger](https://github.com/orhanobut/logger)
- [Compose-Stable-Marker](https://github.com/skydoves/compose-stable-marker)
- [Landscapist](https://github.com/skydoves/landscapist), Coil-Compose
- [ComposeExtensions](https://github.com/taehwandev/ComposeExtensions)
- [compose-effects](https://github.com/skydoves/compose-effects)
- [compose-shadow](https://github.com/adamglin0/compose-shadow)

#### Test & Code analysis

- Ktlint
- Detekt

#### Gradle Dependency

- Gradle Version Catalog

## Architecture
- Android App Architecture
- MVI

## Developers

|Android|Android|
|:---:|:---:|
|[이지훈](https://github.com/easyhooon)|[이서윤](https://github.com/seoyoon513)|
|<img width="144" src="https://github.com/user-attachments/assets/7e54768a-ce44-421d-8c03-9df7d0492855">|<img width="144" src="https://github.com/user-attachments/assets/a6cea688-cf9b-41ad-a3a0-9a0c11775fa2">|

## Module
<img width="1631" height="719" alt="image" src="https://github.com/user-attachments/assets/f6a26dcd-761a-4dab-ae3f-a32e87eb423b" />

## Package Structure
```
├── app
│   └── application
├── build-logic
├── core
│   ├── common
│   ├── data-api
│   ├── data-impl
│   ├── datastore-api
│   ├── datastore-impl
│   ├── designsystem
│   ├── model
│   ├── network
│   ├── ocr
│   └── ui
├── feature
│   ├── detail
│   ├── edit
│   ├── home
│   ├── library
│   ├── login
│   ├── main
│   ├── onboarding
│   ├── record
│   ├── screens
│   ├── settings
│   ├── splash
│   └── webview
├── gradle
   └── libs.versions.toml

```
<br/>
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.ninecraft.booket.feature.detail.book

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
Expand All @@ -25,6 +24,7 @@ import com.ninecraft.booket.feature.screens.RecordScreen
import com.ninecraft.booket.feature.screens.arguments.RecordEditArgs
import com.ninecraft.booket.feature.screens.extensions.delayedGoTo
import com.orhanobut.logger.Logger
import com.skydoves.compose.effects.RememberedEffect
import com.slack.circuit.codegen.annotations.CircuitInject
import com.slack.circuit.retained.rememberRetained
import com.slack.circuit.runtime.Navigator
Expand Down Expand Up @@ -241,7 +241,7 @@ class BookDetailPresenter @AssistedInject constructor(
}
}

LaunchedEffect(Unit) {
RememberedEffect(Unit) {
initialLoad()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class OssLicensesPresenter @AssistedInject constructor(
override fun present(): OssLicensesUiState {
fun handleEvent(event: OssLicensesUiEvent) {
when (event) {
is OssLicensesUiEvent.OnBackClicked -> {
is OssLicensesUiEvent.OnBackClick -> {
navigator.pop()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ internal fun OssLicenses(
ReedBackTopAppBar(
title = stringResource(R.string.oss_licenses_title),
onBackClick = {
state.eventSink(OssLicensesUiEvent.OnBackClicked)
state.eventSink(OssLicensesUiEvent.OnBackClick)
},
)
LazyColumn {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ data class OssLicensesUiState(
) : CircuitUiState

sealed interface OssLicensesUiEvent : CircuitUiEvent {
data object OnBackClicked : OssLicensesUiEvent
data object OnBackClick : OssLicensesUiEvent
}
2 changes: 0 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ android-gradle-plugin = "8.9.3"

## AndroidX
androidx-core = "1.16.0"
androidx-lifecycle = "2.9.2"
androidx-activity-compose = "1.10.1"
androidx-startup = "1.2.0"
androidx-splash = "1.0.1"
Expand Down Expand Up @@ -89,7 +88,6 @@ kotlin-gradle-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-p
compose-compiler-gradle-plugin = { group = "org.jetbrains.kotlin", name = "compose-compiler-gradle-plugin", version.ref = "kotlin" }

androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidx-lifecycle" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidx-activity-compose" }
androidx-splash = { group = "androidx.core", name = "core-splashscreen", version.ref = "androidx-splash" }
androidx-startup = { group = "androidx.startup", name = "startup-runtime", version.ref = "androidx-startup" }
Expand Down
Loading