Skip to content
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

SCRUM-83: 독후감 편집에서 태그 추가 및 제거 기능 구현 #8

Merged
merged 17 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
2899117
refactor: ViwModel Composable 에 직접 전달하지 않도록 변경
towitty Oct 26, 2024
3e1bfd9
modify: HomeScreen 의 TopAppbar 에서 Settings 화면 이동 하도록 변경
towitty Oct 28, 2024
0ae3e3f
feature/SCRUM-80: 설정 메인 페이지 구현
towitty Oct 30, 2024
82ff9c6
refactor: BookRemoteRepository 에서 bookList 상태를 가지고 있도록 변경
towitty Oct 30, 2024
1570699
chore: kapt 를 ksp 로 변경 및 Room 의존성 추가
towitty Nov 3, 2024
25f9574
refactor: getBooks 함수명 getBook 으로 변경 및 하드 코딩된 Book 변경
towitty Nov 3, 2024
ce08698
feature/SCRUM-81: 태그 관리 페이지 추가
towitty Nov 3, 2024
11155f2
modify: view 관련 작업, onCreateView 에서 onViewCreated 로 호출 위치 변경
towitty Nov 3, 2024
8f64e8f
feature: 태그 추가 icon 터치 시, 태그 이름과 색상을 선택하는BottomSheetDialog 구현
towitty Nov 3, 2024
c21803d
feature/SCRUM-82: 설정의 태그 추가 및 삭제 기능 구현
towitty Nov 6, 2024
0176977
test: BookRemoteRepository, TagLocalRepository 유닛 테스트 코드 추가
towitty Nov 7, 2024
32058b1
refactor: BottomNavigation 에 NavBackStackEntry 상태 중복해서 사용하는 부분 호이스팅 하…
towitty Nov 10, 2024
416e4ad
refactor: Hilt 를 이용한 모듈화 및 패키지 구조 변경
towitty Nov 12, 2024
9b449b5
chore: 가독성을 위한 패키지 구조 변경
towitty Nov 13, 2024
a4ab4db
refactor: 코드에서 사용되는 Icons 이미지 벡터 단일화
towitty Nov 13, 2024
e22fcee
fix: 패키지 구조에 맞게 fragment xml 파일의 경로 수정 및 FAB 를 통한 직접 입력 페이지 이동 안되는 문제 수정
towitty Nov 14, 2024
9ec6fb2
feature/SCRUM-83: 독후감 편집에서 태그 추가 및 제거 기능 구현
towitty Nov 14, 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
38 changes: 28 additions & 10 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
alias(libs.plugins.compose.compiler)
id("kotlin-kapt")
id("com.google.devtools.ksp")
id("com.google.dagger.hilt.android")
}

Expand All @@ -21,7 +21,7 @@ android {
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0.0"
versionName = "1.2.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

Expand All @@ -47,23 +47,26 @@ android {
jvmTarget = "1.8"
}
buildFeatures {
viewBinding = true
compose = true
buildConfig = true
}
kapt {
correctErrorTypes = true
}
}

dependencies {
// Hilt
implementation (libs.hilt.android)
kapt(libs.hilt.android.compiler)
implementation (libs.androidx.hilt.navigation.compose)
implementation(libs.hilt.android)
ksp(libs.hilt.android.compiler)
implementation(libs.androidx.hilt.navigation.compose)

// Glide
implementation (libs.glide)
annotationProcessor (libs.glide.compiler)
implementation(libs.glide)
annotationProcessor(libs.glide.compiler)

// Room
implementation(libs.androidx.room.runtime)
ksp(libs.androidx.room.compiler)
implementation(libs.androidx.room.ktx)

// Retrofit
implementation(libs.retrofit)
Expand All @@ -80,17 +83,32 @@ dependencies {
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.material)
implementation(libs.androidx.ui.viewbinding)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.activity)
implementation(libs.androidx.navigation.fragment)
implementation(libs.androidx.fragment)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.recyclerview)
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation(libs.androidx.material.icons.extended)
implementation(libs.androidx.navigation.compose)

testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.junit)
testImplementation(libs.mockk)

androidTestImplementation(libs.hilt.android.testing)
kspAndroidTest(libs.hilt.compiler)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)

debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}
12 changes: 8 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<uses-permission android:name="android.permission.INTERNET" />

<application
android:name = ".BookReportApplication"
android:name=".BookReportApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand All @@ -16,15 +16,19 @@
android:theme="@style/Theme.BookReport"
tools:targetApi="31">
<activity
android:name=".ui.MainActivity"
android:exported="true"
android:label="@string/app_name">
android:name=".presentation.ui.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".presentation.ui.SettingsActivity"
android:theme="@style/Theme.Material3.DayNight.NoActionBar"
android:exported="false" />
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.towitty.bookreport.data.database

import androidx.room.Database
import androidx.room.RoomDatabase
import com.towitty.bookreport.data.database.model.TagEntity


@Database(entities = [TagEntity::class], version = 1, exportSchema = false)
abstract class BookReportDatabase : RoomDatabase() {

abstract fun tagDao(): TagDao
}
28 changes: 28 additions & 0 deletions app/src/main/java/com/towitty/bookreport/data/database/TagDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.towitty.bookreport.data.database

import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import com.towitty.bookreport.data.database.model.TagEntity
import kotlinx.coroutines.flow.Flow

@Dao
interface TagDao {
@Insert
suspend fun insertTag(tagEntity: TagEntity)

@Update
suspend fun updateTag(tagEntity: TagEntity)

@Delete
suspend fun deleteTag(tagEntity: TagEntity)

@Query("SELECT * FROM tags WHERE id = :id")
fun getTag(id: Int): Flow<TagEntity>

@Query("SELECT * FROM tags ORDER BY name ASC")
fun getAllTags(): Flow<List<TagEntity>>

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.towitty.bookreport.data.database.di

import com.towitty.bookreport.data.database.BookReportDatabase
import com.towitty.bookreport.data.database.TagDao
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

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

@Singleton
@Provides
fun provideTagDao(appDatabase: BookReportDatabase): TagDao = appDatabase.tagDao()

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.towitty.bookreport.data.database.di

import android.content.Context
import androidx.room.Room
import com.towitty.bookreport.data.database.BookReportDatabase
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

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

@Singleton
@Provides
fun provideBookReportDatabase(
@ApplicationContext context: Context
): BookReportDatabase = Room.databaseBuilder(
context,
BookReportDatabase::class.java,
"book_report_db"
).build()

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.towitty.bookreport.data.database.model

import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "tags")
data class TagEntity(
@PrimaryKey(autoGenerate = true)
val id:Int,
val name:String,
val color: Int
)

val emptyTagEntity = TagEntity(0, "", 0)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.towitty.bookreport.data.network

import com.towitty.bookreport.BuildConfig
import com.towitty.bookreport.model.Book
import com.towitty.bookreport.data.network.model.Book
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Header
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.towitty.bookreport.data.network

import android.util.Log
import com.towitty.bookreport.model.Book
import com.towitty.bookreport.data.network.model.Book
import com.towitty.bookreport.data.network.model.emptyBook
import com.towitty.bookreport.di.BookReportDispatchers
import com.towitty.bookreport.di.Dispatcher
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
import javax.inject.Inject
Expand All @@ -11,21 +14,21 @@ import javax.inject.Singleton
@Singleton
class BookRemoteDataSource @Inject constructor(
private val bookApi: ApiService,
private val ioDispatcher: CoroutineDispatcher
) {
suspend fun getBooks(query: String): Book {
@Dispatcher(BookReportDispatchers.IO) private val ioDispatcher: CoroutineDispatcher
) : IBookDataSource {
override suspend fun getBook(query: String): Book {
return withContext(ioDispatcher) {
try {
val response = bookApi.getSearchBook(query)
if (response.isSuccessful) {
response.body() ?: Book(lastBuildDate = "", total = 0, start = 0, display = 0, bookList = emptyList())
response.body() ?: emptyBook
} else {
Log.e("BookRemoteDataSource", "code: ${response.code()}")
Book(lastBuildDate = "", total = 0, start = 0, display = 0, bookList = emptyList())
emptyBook
}
} catch (e: Exception) {
Log.e("BookRemoteDataSource", "NetworkException: ${e.message}")
Book(lastBuildDate = "", total = 0, start = 0, display = 0, bookList = emptyList())
emptyBook
}
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.towitty.bookreport.data.network

import com.towitty.bookreport.data.network.model.Book

interface IBookDataSource {
suspend fun getBook(query: String): Book
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.towitty.bookreport.data.network.di

import com.towitty.bookreport.data.network.BookRemoteDataSource
import com.towitty.bookreport.data.network.IBookDataSource
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent

@InstallIn(SingletonComponent::class)
@Module
abstract class DataSourceModule {

@Binds
abstract fun bindsBookDataSource(bookRemoteDataSource: BookRemoteDataSource): IBookDataSource
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
package com.towitty.bookreport.di
package com.towitty.bookreport.data.network.di

import com.towitty.bookreport.data.network.ApiService
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.Dispatchers
import retrofit2.Converter
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import javax.inject.Singleton

@InstallIn(SingletonComponent::class)
@Module
class AppModules {

@Singleton
@Provides
fun provideDispatcherIO() = Dispatchers.IO
object NetworkModule {

@Singleton
@Provides
Expand All @@ -37,4 +32,4 @@ class AppModules {
fun provideApiService(
retrofit: Retrofit
): ApiService = retrofit.create(ApiService::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.towitty.bookreport.model
package com.towitty.bookreport.data.network.model

import com.google.gson.annotations.SerializedName

Expand Down Expand Up @@ -33,6 +33,14 @@ data class BookItem(
val description: String,
)

val emptyBook = Book(
lastBuildDate = "",
total = 0,
start = 0,
display = 0,
bookList = emptyList()
)

val emptyBookItem = BookItem(
title = "",
link = "",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.towitty.bookreport.data.repository

import com.towitty.bookreport.data.network.IBookDataSource
import com.towitty.bookreport.data.network.model.BookItem
import com.towitty.bookreport.data.network.model.emptyBookItem
import javax.inject.Inject

class BookRemoteRepository @Inject constructor(
private val bookRemoteDataSource: IBookDataSource
) : IBookRepository {
private var bookList: List<BookItem> = emptyList()

override suspend fun searchBooks(query: String): List<BookItem> {
bookList = bookRemoteDataSource.getBook(query).bookList
return bookList
}

override fun findBookByIsbn(isbn: String): BookItem = bookList.find { it.isbn == isbn } ?: emptyBookItem
}
Loading
Loading