Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
 into feat/#4-feature-module
  • Loading branch information
DongChyeon committed Mar 31, 2024
2 parents 1b644d0 + 07204de commit 0baa7c2
Show file tree
Hide file tree
Showing 40 changed files with 833 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ out/
build/
# Local configuration file (sdk path, etc)
local.properties
secrets.properties
keystore.properties
output-metadata.json
# Proguard folder generated by Eclipse
Expand Down
1 change: 1 addition & 0 deletions build-logic/convention/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies {
compileOnly(libs.android.tools.common)
compileOnly(libs.kotlin.gradlePlugin)
compileOnly(libs.ksp.gradlePlugin)
compileOnly(libs.secrets.gradle.plugin)
}

gradlePlugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ internal fun Project.configureKotlinAndroid(
minSdk = Config.android.minSdkVersion
}

buildFeatures {
buildConfig = true
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_18
targetCompatibility = JavaVersion.VERSION_18
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package store.newsbriefing.app.buildlogic.extension

import com.android.build.api.dsl.CommonExtension
import com.google.android.libraries.mapsplatform.secrets_gradle_plugin.SecretsPluginExtension
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure

internal fun Project.configureSecret() {
extensions.configure<SecretsPluginExtension> {
defaultPropertiesFileName = "secrets.properties"
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package store.newsbriefing.app.buildlogic.plugin

import com.android.build.api.dsl.ApplicationExtension
import com.google.android.libraries.mapsplatform.secrets_gradle_plugin.SecretsPluginExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import store.newsbriefing.app.buildlogic.config.Config
import store.newsbriefing.app.buildlogic.extension.configureKotlinAndroid
import store.newsbriefing.app.buildlogic.extension.configureSecret

class AndroidApplicationConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.application")
apply("org.jetbrains.kotlin.android")
apply("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
}
// android
extensions.configure<ApplicationExtension> {
Expand All @@ -32,6 +35,8 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
}
}
}

configureSecret()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import store.newsbriefing.app.buildlogic.config.Config
import store.newsbriefing.app.buildlogic.extension.configureKotlinAndroid
import store.newsbriefing.app.buildlogic.extension.configureSecret

class AndroidLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.library")
apply("org.jetbrains.kotlin.android")
apply("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
}

extensions.configure<LibraryExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = Config.android.targetSdkVersion
}

configureSecret()
}
}
}
6 changes: 6 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@ plugins {
alias(libs.plugins.ksp) apply false
alias(libs.plugins.hilt) apply false
alias(libs.plugins.androidLibrary) apply false
}

buildscript {
dependencies {
classpath(libs.secrets.gradle.plugin)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package store.newsbriefing.app.core.common

import java.time.Instant
import java.time.ZoneId
import java.time.ZonedDateTime


fun String.toZoneDateTime(): ZonedDateTime {
val instant = Instant.parse(this)
return instant.atZone(ZoneId.systemDefault())
}
5 changes: 5 additions & 0 deletions core/data/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
plugins {
alias(libs.plugins.briefing.android.library)
alias(libs.plugins.briefing.android.hilt)
}

android {
namespace = "store.newsbriefing.app.core.data"
}

dependencies {
api(projects.core.model)
api(projects.core.network)
api(projects.core.common)

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package store.newsbriefing.app.core.data.repository

import kotlinx.coroutines.flow.Flow
import store.newsbriefing.app.core.model.BriefingArticle
import store.newsbriefing.app.core.model.BriefingArticleCategory
import store.newsbriefing.app.core.model.BriefingArticleSummary
import store.newsbriefing.app.core.model.TimeOfDay
import java.time.LocalDate

interface BriefingRepository {
suspend fun getBriefingArticleSummaries(
briefingArticleCategory: BriefingArticleCategory,
dateLocalDate: LocalDate?,
timeOfDay: TimeOfDay?
): Flow<List<BriefingArticleSummary>>

suspend fun getBriefingArticle(articleId: Long): Flow<BriefingArticle>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package store.newsbriefing.app.core.data.repository

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import store.newsbriefing.app.core.model.BriefingArticle
import store.newsbriefing.app.core.model.BriefingArticleCategory
import store.newsbriefing.app.core.model.BriefingArticleSummary
import store.newsbriefing.app.core.model.TimeOfDay
import store.newsbriefing.app.core.network.datasource.BriefingNetworkDataSource
import store.newsbriefing.app.core.network.model.asExternalModel
import java.time.LocalDate

internal class DefaultBriefingRepository(
private val briefingNetworkDataSource: BriefingNetworkDataSource
) : BriefingRepository {
override suspend fun getBriefingArticleSummaries(
briefingArticleCategory: BriefingArticleCategory,
dateLocalDate: LocalDate?,
timeOfDay: TimeOfDay?
): Flow<List<BriefingArticleSummary>> = flow {
val summaries = briefingNetworkDataSource.getBriefingArticleSummaries(
briefingArticleCategory,
dateLocalDate,
timeOfDay
)
emit(summaries.map {
it.asExternalModel()
})
}

override suspend fun getBriefingArticle(articleId: Long): Flow<BriefingArticle> {
return flow {
emit(briefingNetworkDataSource.getBriefingArticle(articleId).asExternalModel())
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package store.newsbriefing.app.core.data.repository

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import store.newsbriefing.app.core.model.MemberDeleteResult
import store.newsbriefing.app.core.model.MemberToken
import store.newsbriefing.app.core.network.datasource.MemberNetworkDataSource
import store.newsbriefing.app.core.network.model.asExternalModel

internal class DefaultMemberRepository(val memberNetworkDataSource: MemberNetworkDataSource) :
MemberRepository {
override suspend fun deleteMember(memberId: Long): Flow<MemberDeleteResult> = flow {
emit(memberNetworkDataSource.deleteMember(memberId).asExternalModel())
}

override suspend fun getTokenWithSocialProvider(
provider: String,
identityToken: String
): Flow<MemberToken> = flow {
emit(
memberNetworkDataSource.getTokenWithSocialProvider(provider, identityToken)
.asExternalModel()
)
}

override suspend fun getRefreshedAccessToken(refreshToken: String): Flow<MemberToken> = flow {
emit(memberNetworkDataSource.getRefreshedAccessToken(refreshToken).asExternalModel())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package store.newsbriefing.app.core.data.repository

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import store.newsbriefing.app.core.model.Scrap
import store.newsbriefing.app.core.model.ScrapCreateResult
import store.newsbriefing.app.core.model.ScrapDeleteResult
import store.newsbriefing.app.core.network.datasource.ScrapNetworkDataSource
import store.newsbriefing.app.core.network.model.asExternalModel

internal class DefaultScrapRepository(private val scrapNetworkDataSource: ScrapNetworkDataSource) : ScrapRepository {
override fun getScrap(memberId: Long): Flow<List<Scrap>> = flow {
val scraps = scrapNetworkDataSource.getScrap(memberId).map { it.asExternalModel() }
emit(scraps)
}

override fun setScrap(memberId: Long, articleId: Long): Flow<ScrapCreateResult> = flow {
val result = scrapNetworkDataSource.setScrap(memberId, articleId).asExternalModel()
emit(result)
}

override fun unScrap(memberId: Long, articleId: Long): Flow<ScrapDeleteResult> = flow {
val result = scrapNetworkDataSource.unScrap(memberId, articleId).asExternalModel()
emit(result)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package store.newsbriefing.app.core.data.repository

import kotlinx.coroutines.flow.Flow
import store.newsbriefing.app.core.model.MemberDeleteResult
import store.newsbriefing.app.core.model.MemberToken

interface MemberRepository {

suspend fun deleteMember(memberId: Long): Flow<MemberDeleteResult>
suspend fun getTokenWithSocialProvider(provider: String, identityToken: String): Flow<MemberToken>
suspend fun getRefreshedAccessToken(refreshToken: String): Flow<MemberToken>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package store.newsbriefing.app.core.data.repository

import kotlinx.coroutines.flow.Flow
import store.newsbriefing.app.core.model.Scrap
import store.newsbriefing.app.core.model.ScrapCreateResult
import store.newsbriefing.app.core.model.ScrapDeleteResult

interface ScrapRepository {
fun getScrap(memberId: Long): Flow<List<Scrap>>
fun setScrap(memberId: Long, articleId: Long): Flow<ScrapCreateResult>
fun unScrap(memberId: Long, articleId: Long): Flow<ScrapDeleteResult>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package store.newsbriefing.app.core.data.repository.di

import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import store.newsbriefing.app.core.data.repository.BriefingRepository
import store.newsbriefing.app.core.data.repository.DefaultBriefingRepository
import store.newsbriefing.app.core.data.repository.DefaultMemberRepository
import store.newsbriefing.app.core.data.repository.DefaultScrapRepository
import store.newsbriefing.app.core.data.repository.MemberRepository
import store.newsbriefing.app.core.data.repository.ScrapRepository

@Module
@InstallIn(SingletonComponent::class)
abstract class DataModule {
@Binds
internal abstract fun bindBriefingRepository(
repository: DefaultBriefingRepository
): BriefingRepository

@Binds
internal abstract fun bindMemberRepository(
repository: DefaultMemberRepository
): MemberRepository

@Binds
internal abstract fun bindScrapRepository(
repository: DefaultScrapRepository
): ScrapRepository
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package store.newsbriefing.app.core.model

import java.time.ZonedDateTime

data class BriefingArticle(
val id: Long,
val ranks: Int,
val title: String,
val subtitle: String,
val content: String,
val date: ZonedDateTime,
val articles: List<BriefingArticleRelated>,
val isScrap: Boolean,
val isBriefingOpen: Boolean,
val isWarning: Boolean,
val scrapCount: Int,
val gptModel: String,
val timeOfDay: String,
val type: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package store.newsbriefing.app.core.model
enum class BriefingArticleCategory(val typeId: String) {
KOREA("KOREA"),
GLOBAL("GLOBAL"),
SOCIAL("SOCIAL"),
SCIENCE("SCIENCE"),
ECONOMY("ECONOMY");

companion object {
fun fromTypeName(typeName: String): BriefingArticleCategory {
return values().firstOrNull { it.typeId.equals(typeName, ignoreCase = true) }
?: throw IllegalArgumentException("Invalid typeName for ArticleType: $typeName")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package store.newsbriefing.app.core.model

data class BriefingArticleRelated(
val id: Int,
val press: String,
val title: String,
val url: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package store.newsbriefing.app.core.model

data class BriefingArticleSummary(
val id: Int,
val ranks: Int,
val title: String,
val subtitle: String,
val scrapCount: Int
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package store.newsbriefing.app.core.model

import java.time.ZonedDateTime

data class MemberDeleteResult(
val quitAt: ZonedDateTime
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package store.newsbriefing.app.core.model

data class MemberToken(
val memberId: Long,
val accessToken: String,
val refreshToken: String
)
Loading

0 comments on commit 0baa7c2

Please sign in to comment.