Skip to content

Commit

Permalink
Merge pull request #8 from f-lab-edu/SCRUM-83
Browse files Browse the repository at this point in the history
SCRUM-83: 독후감 편집에서 태그 추가 및 제거 기능 구현
  • Loading branch information
towitty authored Nov 14, 2024
2 parents 6dd12e5 + 9ec6fb2 commit c58964c
Show file tree
Hide file tree
Showing 78 changed files with 1,923 additions and 267 deletions.
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

0 comments on commit c58964c

Please sign in to comment.