Add: data and domain layers

This commit is contained in:
Carlos Martinez
2021-06-17 11:27:28 -04:00
parent 205de0ef8d
commit 3848ac0519
64 changed files with 211 additions and 648 deletions

View File

@@ -1,24 +0,0 @@
package dev.carlos.acronyms
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("dev.carlos.acronyms", appContext.packageName)
}
}

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dev.carlos.acronyms"
>
<application
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Acronyms"
/>
</manifest>

View File

@@ -1,51 +0,0 @@
package dev.carlos.acronyms.models
import android.os.Parcelable
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class ShortformRemote(
@SerializedName("sf") val value: String,
@SerializedName("lfs") val results: List<LongformRemote>
) : Parcelable {
@Parcelize
data class LongformRemote(
@SerializedName("lf") val value: String,
@SerializedName("freq") val corpusFrequency: Int,
@SerializedName("since") val since: Int
) : Parcelable
}
@Entity(tableName = ShortformEntity.TABLE_NAME, indices = [Index(value = ["value"], unique = true)])
@TypeConverters(LongformListConverter::class)
data class ShortformEntity(
@PrimaryKey
val value: String,
val results: List<LongformEntity>
) {
data class LongformEntity(
val value: String,
val corpusFrequency: Int,
val since: Int
)
companion object {
const val TABLE_NAME = "shortforms"
}
}
data class ShortformModel(
val value: String,
val results: List<LongformModel>
) {
data class LongformModel(
val value: String,
val corpusFrequency: Int,
val since: Int
)
}

View File

@@ -1,24 +0,0 @@
package dev.carlos.acronyms.models
import androidx.room.TypeConverter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
class LongformListConverter {
@TypeConverter
fun fromString(value: String): List<ShortformEntity.LongformEntity> {
val listType = object : TypeToken<List<ShortformEntity.LongformEntity>>() {}.type
return Gson().fromJson(value, listType)
}
@TypeConverter
fun fromList(list: List<ShortformEntity.LongformEntity>) = Gson().toJson(list)
}
fun ShortformRemote.toShortformEntity() = ShortformEntity(this.value, this.results.map {
ShortformEntity.LongformEntity(it.value, it.corpusFrequency, it.since)
})
fun ShortformEntity.toShortformModel() = ShortformModel(this.value, this.results.map {
ShortformModel.LongformModel(it.value, it.corpusFrequency, it.since)
})

View File

@@ -1,35 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108"
>
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="49.59793"
android:startX="42.9492"
android:endY="92.4963"
android:endX="85.84757"
android:type="linear"
>
<item
android:color="#44000000"
android:offset="0.0"
/>
<item
android:color="#00000000"
android:offset="1.0"
/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:strokeWidth="1"
android:strokeColor="#00000000"
/>
</vector>

View File

@@ -1,204 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
>
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"
/>
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
</vector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,17 +0,0 @@
package dev.carlos.acronyms
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@@ -16,7 +16,7 @@ android {
versionName "1.0" versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
buildConfigField "String", "BASE_ENDPOINT", '"http://www.nactem.ac.uk/software/acromine/"' buildConfigField "String", "BASE_ENDPOINT", '"http://www.nactem.ac.uk"'
} }
buildTypes { buildTypes {
@@ -58,5 +58,5 @@ android {
dependencies { dependencies {
implementation project(":core") implementation project(":core")
implementation project(":acronyms") implementation project(':shortform')
} }

View File

@@ -6,7 +6,7 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<application <application
android:name=".MainApplication" android:name="dev.carlos.acronyms.MainApplication"
android:allowBackup="true" android:allowBackup="true"
android:fullBackupContent="false" android:fullBackupContent="false"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@@ -14,11 +14,12 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="false" android:supportsRtl="false"
android:theme="@style/Theme.Acronyms" android:theme="@style/Theme.Acronyms"
android:networkSecurityConfig="@xml/network_security_config"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
> >
<activity <activity
android:name=".views.MainActivity" android:name="dev.carlos.acronyms.views.MainActivity"
android:launchMode="singleTask" android:launchMode="singleTask"
> >
<intent-filter> <intent-filter>

View File

@@ -1,6 +1,7 @@
package dev.carlos.acronyms package dev.carlos.acronyms
import android.app.Application import android.app.Application
import dev.carlos.shortform.di.acronymsModule
import dev.carlos.acronyms.di.appModules import dev.carlos.acronyms.di.appModules
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin import org.koin.core.context.startKoin
@@ -24,7 +25,8 @@ class MainApplication : Application() {
modules( modules(
listOf( listOf(
appModules appModules,
acronymsModule
) )
) )
} }

View File

@@ -5,15 +5,11 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.NavigationUI import androidx.navigation.ui.NavigationUI
import dev.carlos.acronyms.R import dev.carlos.acronyms.R
import dev.carlos.acronyms.di.appModules
import dev.carlos.acronyms.viewmodel.NavigationViewmodel import dev.carlos.acronyms.viewmodel.NavigationViewmodel
import dev.carlos.core.extensions.findNavHostFragment
import dev.carlos.core.extensions.observeNonNull import dev.carlos.core.extensions.observeNonNull
import dev.carlos.core.navigation.NavigationRouter import dev.carlos.core.navigation.NavigationRouter
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.context.startKoin
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {

View File

@@ -5,7 +5,8 @@
android:layout_height="match_parent" android:layout_height="match_parent"
> >
<androidx.fragment.app.FragmentContainerView <!-- Still usign fragment because of this [https://issuetracker.google.com/issues/142847973] -->
<fragment
android:id="@+id/main_fragment_container" android:id="@+id/main_fragment_container"
android:name="androidx.navigation.fragment.NavHostFragment" android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">www.nactem.ac.uk</domain>
</domain-config>
</network-security-config>

View File

@@ -0,0 +1,7 @@
package dev.carlos.core.domain.network
sealed class RequestState {
class Success<out T>(val data: T) : RequestState()
object Loading : RequestState()
class Error(val throwable: Throwable) : RequestState()
}

View File

@@ -1,8 +0,0 @@
package dev.carlos.core.domain.network
sealed class RequestStatus {
object Ready : RequestStatus()
object Loading : RequestStatus()
object Errored : RequestStatus()
object Empty : RequestStatus()
}

View File

@@ -0,0 +1,3 @@
package dev.carlos.core.extensions
fun Int.notEmpty() = this > 0

View File

@@ -0,0 +1,19 @@
package dev.carlos.core.extensions
import dev.carlos.core.scheduler.Scheduler
import io.reactivex.Completable
import io.reactivex.Flowable
import io.reactivex.Observable
import io.reactivex.Single
fun <T> Observable<T>.runOnIo(scheduler: Scheduler): Observable<T> =
subscribeOn(scheduler.io()).observeOn(scheduler.ui())
fun <T> Single<T>.runOnIo(scheduler: Scheduler): Single<T> =
subscribeOn(scheduler.io()).observeOn(scheduler.ui())
fun <T> Flowable<T>.runOnIo(scheduler: Scheduler): Flowable<T> =
subscribeOn(scheduler.io()).observeOn(scheduler.ui())
fun Completable.runOnIo(scheduler: Scheduler): Completable =
subscribeOn(scheduler.io()).observeOn(scheduler.ui())

View File

@@ -0,0 +1,10 @@
package dev.carlos.core.scheduler
import io.reactivex.Scheduler
interface Scheduler {
fun io(): Scheduler
fun computation(): Scheduler
fun newThread(): Scheduler
fun ui(): Scheduler
}

View File

@@ -0,0 +1,15 @@
package dev.carlos.core.scheduler
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
class SchedulerProvider : Scheduler {
override fun io() = Schedulers.io()
override fun computation() = Schedulers.computation()
override fun newThread() = Schedulers.newThread()
override fun ui(): io.reactivex.Scheduler = AndroidSchedulers.mainThread()
}

View File

@@ -1,35 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108"
>
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="49.59793"
android:startX="42.9492"
android:endY="92.4963"
android:endX="85.84757"
android:type="linear"
>
<item
android:color="#44000000"
android:offset="0.0"
/>
<item
android:color="#00000000"
android:offset="1.0"
/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:strokeWidth="1"
android:strokeColor="#00000000"
/>
</vector>

View File

@@ -1,204 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
>
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"
/>
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"
/>
</vector>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,2 +1,2 @@
rootProject.name = "Acronyms" rootProject.name = "Acronyms"
include ':app', ':core', ':acronyms' include ':app', ':core', ':shortform'

View File

@@ -5,6 +5,12 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-parcelize' apply plugin: 'kotlin-parcelize'
android {
defaultConfig {
buildConfigField "String", "DB_NAME", '"acronyms.db"'
}
}
dependencies { dependencies {
implementation project(':core') implementation project(':core')
} }

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="dev.carlos.shortform" />

View File

@@ -0,0 +1,16 @@
package dev.carlos.shortform.data
import dev.carlos.shortform.data.cloud.AcronymsRemoteSource
import dev.carlos.shortform.data.models.ShortformModel
import dev.carlos.shortform.data.models.toShortformModel
import dev.carlos.shortform.domain.AcronymsRepository
import io.reactivex.Single
class AcronymsDataRepository(
private val remoteDatasource: AcronymsRemoteSource
) : AcronymsRepository {
override fun getAcronymDefinition(acronym: String): Single<ShortformModel> {
return remoteDatasource.getAcronymDefinition(acronym).map { it.single()?.toShortformModel() }
}
}

View File

@@ -0,0 +1,8 @@
package dev.carlos.shortform.data.cloud
import dev.carlos.shortform.data.cloud.model.ShortformRemote
import io.reactivex.Single
interface AcronymsRemoteSource {
fun getAcronymDefinition(acronym: String): Single<List<ShortformRemote>>
}

View File

@@ -0,0 +1,18 @@
package dev.carlos.shortform.data.cloud.model
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class ShortformRemote(
@SerializedName("sf") val value: String,
@SerializedName("lfs") val results: List<LongformRemote>
) : Parcelable {
@Parcelize
data class LongformRemote(
@SerializedName("lf") val value: String,
@SerializedName("freq") val corpusFrequency: Int,
@SerializedName("since") val since: Int
) : Parcelable
}

View File

@@ -0,0 +1,11 @@
package dev.carlos.shortform.data.cloud.retrofit
import dev.carlos.shortform.data.cloud.AcronymsRemoteSource
import dev.carlos.shortform.data.cloud.model.ShortformRemote
import io.reactivex.Single
class AcronymsRemoteDatasource(private val acronymsService: AcronymsService) : AcronymsRemoteSource {
override fun getAcronymDefinition(acronym: String): Single<List<ShortformRemote>> {
return acronymsService.getAcronymDefinition(acronym)
}
}

View File

@@ -0,0 +1,11 @@
package dev.carlos.shortform.data.cloud.retrofit
import dev.carlos.shortform.data.cloud.model.ShortformRemote
import io.reactivex.Single
import retrofit2.http.GET
import retrofit2.http.Query
interface AcronymsService {
@GET("/software/acromine/dictionary.py")
fun getAcronymDefinition(@Query("sf") acronym: String): Single<List<ShortformRemote>>
}

View File

@@ -0,0 +1,7 @@
package dev.carlos.shortform.data.models
import dev.carlos.shortform.data.cloud.model.ShortformRemote
fun ShortformRemote.toShortformModel() = ShortformModel(this.value, this.results.map {
ShortformModel.LongformModel(it.value, it.corpusFrequency, it.since)
})

View File

@@ -0,0 +1,12 @@
package dev.carlos.shortform.data.models
data class ShortformModel(
val value: String,
val results: List<LongformModel>
) {
data class LongformModel(
val value: String,
val corpusFrequency: Int,
val since: Int
)
}

View File

@@ -0,0 +1,25 @@
package dev.carlos.shortform.di
import dev.carlos.core.domain.network.RemoteClient
import dev.carlos.core.scheduler.Scheduler
import dev.carlos.core.scheduler.SchedulerProvider
import dev.carlos.shortform.data.AcronymsDataRepository
import dev.carlos.shortform.data.cloud.AcronymsRemoteSource
import dev.carlos.shortform.data.cloud.retrofit.AcronymsRemoteDatasource
import dev.carlos.shortform.data.cloud.retrofit.AcronymsService
import dev.carlos.shortform.domain.AcronymsRepository
import dev.carlos.shortform.domain.GetAcronymDefinition
import org.koin.dsl.module
val acronymsModule = module {
single<Scheduler> { SchedulerProvider() }
single {
get<RemoteClient>().getClient(AcronymsService::class.java)
}
factory<AcronymsRemoteSource> { AcronymsRemoteDatasource(get()) }
factory<AcronymsRepository> { AcronymsDataRepository(get()) }
factory { GetAcronymDefinition(get(), get()) }
}

View File

@@ -0,0 +1,9 @@
package dev.carlos.shortform.domain
import dev.carlos.shortform.data.models.ShortformModel
import io.reactivex.Flowable
import io.reactivex.Single
interface AcronymsRepository {
fun getAcronymDefinition(acronym: String): Single<ShortformModel>
}

View File

@@ -0,0 +1,15 @@
package dev.carlos.shortform.domain
import dev.carlos.shortform.data.models.ShortformModel
import dev.carlos.core.extensions.runOnIo
import dev.carlos.core.scheduler.Scheduler
import io.reactivex.Single
class GetAcronymDefinition(
private val acronymsRepository: AcronymsRepository,
private val scheduler: Scheduler
) {
fun getAcronymDefinition(acronym: String): Single<ShortformModel> {
return acronymsRepository.getAcronymDefinition(acronym).runOnIo(scheduler)
}
}