WIP: Implement local database caching/networking with KMP
This commit is contained in:
parent
f1e36df8c4
commit
cf4226d20c
19 changed files with 280 additions and 11 deletions
|
@ -77,8 +77,8 @@ class CategoryFormActivity : AppCompatActivity() {
|
|||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
when (item?.itemId) {
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
val upIntent: Intent? = NavUtils.getParentActivityIntent(this)
|
||||
|
||||
|
|
|
@ -171,8 +171,8 @@ class TransactionFormActivity : AppCompatActivity(), CoroutineScope {
|
|||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
when (item?.itemId) {
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
android.R.id.home -> onNavigateUp()
|
||||
R.id.action_save -> {
|
||||
val date = GregorianCalendar.getInstance().apply {
|
||||
|
|
|
@ -4,11 +4,11 @@ apply plugin: 'kotlin-android'
|
|||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
compileSdkVersion 30
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
|
|
@ -16,6 +16,7 @@ buildscript {
|
|||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.squareup.sqldelight:gradle-plugin:1.4.3'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@ apply plugin: 'kotlin-android'
|
|||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
compileSdkVersion 30
|
||||
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
include ':android', ':budgetlib', ':common', ':storage'
|
||||
include ':android', ':budgetlib', ':common', ':storage', ':shared'
|
||||
|
|
1
shared/.gitignore
vendored
Normal file
1
shared/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/build
|
98
shared/build.gradle.kts
Normal file
98
shared/build.gradle.kts
Normal file
|
@ -0,0 +1,98 @@
|
|||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("com.android.library")
|
||||
id("kotlin-android-extensions")
|
||||
kotlin("plugin.serialization") version "1.4.10"
|
||||
id("com.squareup.sqldelight")
|
||||
}
|
||||
group = "com.wbrawner.twigs"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
kotlin {
|
||||
android()
|
||||
ios {
|
||||
binaries {
|
||||
framework {
|
||||
baseName = "twigs"
|
||||
}
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation("io.ktor:ktor-client-core:1.4.2")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
|
||||
implementation("io.ktor:ktor-client-serialization:1.4.2")
|
||||
}
|
||||
}
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
}
|
||||
}
|
||||
val androidMain by getting {
|
||||
dependencies {
|
||||
implementation("com.google.android.material:material:1.2.0")
|
||||
implementation("com.squareup.sqldelight:android-driver:1.4.3")
|
||||
api("io.ktor:ktor-client-android:1.4.2")
|
||||
}
|
||||
}
|
||||
val androidTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-junit"))
|
||||
implementation("junit:junit:4.12")
|
||||
}
|
||||
}
|
||||
val iosMain by getting {
|
||||
dependencies {
|
||||
implementation("io.ktor:ktor-client-ios:1.4.2")
|
||||
implementation("com.squareup.sqldelight:native-driver:1.4.3")
|
||||
}
|
||||
}
|
||||
val iosTest by getting
|
||||
}
|
||||
}
|
||||
|
||||
sqldelight {
|
||||
database("TwigsDatabase") {
|
||||
packageName = "com.wbrawner.twigs"
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion(30)
|
||||
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
|
||||
defaultConfig {
|
||||
minSdkVersion(23)
|
||||
targetSdkVersion(30)
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
getByName("release") {
|
||||
isMinifyEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
val packForXcode by tasks.creating(Sync::class) {
|
||||
group = "build"
|
||||
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
|
||||
val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
|
||||
val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
|
||||
val framework = kotlin.targets.getByName<KotlinNativeTarget>(targetName).binaries.getFramework(mode)
|
||||
inputs.property("mode", mode)
|
||||
dependsOn(framework.linkTask)
|
||||
val targetDir = File(buildDir, "xcode-frameworks")
|
||||
from({ framework.outputDirectory })
|
||||
into(targetDir)
|
||||
}
|
||||
tasks.getByName("build").dependsOn(packForXcode)
|
21
shared/proguard-rules.pro
vendored
Normal file
21
shared/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.kts.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
2
shared/src/androidMain/AndroidManifest.xml
Normal file
2
shared/src/androidMain/AndroidManifest.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.wbrawner.twigs.android"/>
|
|
@ -0,0 +1,12 @@
|
|||
package com.wbrawner.twigs.shared
|
||||
|
||||
import android.content.Context
|
||||
import com.squareup.sqldelight.android.AndroidSqliteDriver
|
||||
import com.squareup.sqldelight.db.SqlDriver
|
||||
import com.wbrawner.twigs.TwigsDatabase
|
||||
|
||||
actual class DriverFactory(private val context: Context) {
|
||||
actual fun createDriver(): SqlDriver {
|
||||
return AndroidSqliteDriver(TwigsDatabase.Schema, context, "twigs.db")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package com.wbrawner.twigs.shared
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Summary(
|
||||
@SerialName("domains_being_blocked")
|
||||
val domainsBeingBlocked: String,
|
||||
@SerialName("dns_queries_today")
|
||||
val dnsQueriesToday: String,
|
||||
@SerialName("ads_blocked_today")
|
||||
val adsBlockedToday: String,
|
||||
@SerialName("ads_percentage_today")
|
||||
val adsPercentageToday: String,
|
||||
@SerialName("unique_domains")
|
||||
val uniqueDomains: String,
|
||||
@SerialName("queries_forwarded")
|
||||
val queriesForwarded: String,
|
||||
@SerialName("clients_ever_seen")
|
||||
val clientsEverSeen: String,
|
||||
@SerialName("unique_clients")
|
||||
val uniqueClients: String,
|
||||
@SerialName("dns_queries_all_types")
|
||||
val dnsQueriesAllTypes: String,
|
||||
@SerialName("queries_cached")
|
||||
val queriesCached: String,
|
||||
@SerialName("no_data_replies")
|
||||
val noDataReplies: String? = null,
|
||||
@SerialName("nx_domain_replies")
|
||||
val nxDomainReplies: String? = null,
|
||||
@SerialName("cname_replies")
|
||||
val cnameReplies: String? = null,
|
||||
@SerialName("in_replies")
|
||||
val ipReplies: String? = null,
|
||||
@SerialName("privacy_level")
|
||||
val privacyLevel: String,
|
||||
override val status: Status,
|
||||
@SerialName("gravity_last_updated")
|
||||
val gravity: Gravity? = null,
|
||||
val type: String? = null,
|
||||
val version: Int? = null
|
||||
) : StatusProvider
|
||||
|
||||
@Serializable
|
||||
enum class Status {
|
||||
@SerialName("enabled")
|
||||
ENABLED,
|
||||
@SerialName("disabled")
|
||||
DISABLED
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Gravity(
|
||||
@SerialName("file_exists")
|
||||
val fileExists: Boolean,
|
||||
val absolute: Int,
|
||||
val relative: Relative
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Relative(
|
||||
val days: String,
|
||||
val hours: String,
|
||||
val minutes: String
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class VersionResponse(val version: Int)
|
||||
|
||||
@Serializable
|
||||
data class TopItemsResponse(
|
||||
@SerialName("top_queries") val topQueries: Map<String, String>,
|
||||
@SerialName("top_ads") val topAds: Map<String, Double>
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class StatusResponse(
|
||||
override val status: Status
|
||||
) : StatusProvider
|
||||
|
||||
interface StatusProvider {
|
||||
val status: Status
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.wbrawner.twigs.shared
|
||||
|
||||
import com.squareup.sqldelight.db.SqlDriver
|
||||
import com.wbrawner.twigs.TwigsDatabase
|
||||
|
||||
expect class DriverFactory {
|
||||
fun createDriver(): SqlDriver
|
||||
}
|
||||
|
||||
fun createDatabase(driverFactory: DriverFactory): TwigsDatabase {
|
||||
val driver = driverFactory.createDriver()
|
||||
val database = TwigsDatabase(driver)
|
||||
|
||||
// Do more work with the database (see below).
|
||||
return database
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
CREATE TABLE IF NOT EXISTS budget (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
currencyCode TEXT
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
CREATE TABLE IF NOT EXISTS budget (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
currencyCode TEXT
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
CREATE TABLE IF NOT EXISTS budget (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
currencyCode TEXT
|
||||
);
|
|
@ -0,0 +1,6 @@
|
|||
CREATE TABLE IF NOT EXISTS budget (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
description TEXT,
|
||||
currencyCode TEXT
|
||||
);
|
|
@ -0,0 +1,10 @@
|
|||
package com.wbrawner.twigs.shared
|
||||
|
||||
import com.squareup.sqldelight.db.SqlDriver
|
||||
import com.wbrawner.twigs.TwigsDatabase
|
||||
|
||||
actual class DriverFactory {
|
||||
actual fun createDriver(): SqlDriver {
|
||||
return NativeSqliteDriver(TwigsDatabase.Schema, "twigs.db")
|
||||
}
|
||||
}
|
|
@ -4,12 +4,12 @@ apply plugin: 'kotlin-android'
|
|||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
compileSdkVersion 30
|
||||
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 29
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
|
|
Loading…
Reference in a new issue