diff --git a/.idea/artifacts/database_jvm.xml b/.idea/artifacts/database_jvm.xml
new file mode 100644
index 00000000..a32d631c
--- /dev/null
+++ b/.idea/artifacts/database_jvm.xml
@@ -0,0 +1,8 @@
+
+
+ $PROJECT_DIR$/database/build/libs
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 39eec84b..0d31a976 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -44,7 +44,6 @@ dependencies {
implementation(Dependencies.ThirdParty.accompanistFlow)
implementation(Dependencies.ThirdParty.Moshi.lib)
implementation(Dependencies.ThirdParty.Retrofit.moshi)
- implementation(Dependencies.ThirdParty.SQLDelight.androidDriver)
testImplementation(kotlin("test-junit"))
androidTestImplementation(kotlin("test-junit"))
}
diff --git a/app/src/androidTest/java/dev/msfjarvis/lobsters/ui/main/LobstersTopBarTest.kt b/app/src/androidTest/java/dev/msfjarvis/lobsters/ui/main/LobstersTopBarTest.kt
index cd66ee9b..56aaa61d 100644
--- a/app/src/androidTest/java/dev/msfjarvis/lobsters/ui/main/LobstersTopBarTest.kt
+++ b/app/src/androidTest/java/dev/msfjarvis/lobsters/ui/main/LobstersTopBarTest.kt
@@ -24,6 +24,7 @@ class LobstersTopBarTest : ScreenshotTest {
LobstersTopAppBar(
currentDestination = Destination.Hottest,
toggleSortingOrder = {},
+ launchSettings = {},
)
}
}
@@ -38,6 +39,7 @@ class LobstersTopBarTest : ScreenshotTest {
LobstersTopAppBar(
currentDestination = Destination.Hottest,
toggleSortingOrder = {},
+ launchSettings = {},
)
}
}
@@ -52,6 +54,7 @@ class LobstersTopBarTest : ScreenshotTest {
LobstersTopAppBar(
currentDestination = Destination.Saved,
toggleSortingOrder = {},
+ launchSettings = {},
)
}
}
@@ -66,6 +69,7 @@ class LobstersTopBarTest : ScreenshotTest {
LobstersTopAppBar(
currentDestination = Destination.Saved,
toggleSortingOrder = {},
+ launchSettings = {},
)
}
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d897211e..8f0e6c9e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -25,6 +25,14 @@
+
+
+
+
+
diff --git a/app/src/main/java/dev/msfjarvis/lobsters/data/backup/BackupHandler.kt b/app/src/main/java/dev/msfjarvis/lobsters/data/backup/BackupHandler.kt
new file mode 100644
index 00000000..441dd670
--- /dev/null
+++ b/app/src/main/java/dev/msfjarvis/lobsters/data/backup/BackupHandler.kt
@@ -0,0 +1,32 @@
+package dev.msfjarvis.lobsters.data.backup
+
+import com.squareup.moshi.Moshi
+import com.squareup.moshi.adapter
+import dev.msfjarvis.lobsters.data.local.SavedPost
+import dev.msfjarvis.lobsters.database.LobstersDatabase
+import javax.inject.Inject
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+
+@OptIn(ExperimentalStdlibApi::class)
+class BackupHandler
+@Inject
+constructor(
+ private val database: LobstersDatabase,
+ moshi: Moshi,
+) {
+ private val adapter = moshi.adapter>()
+
+ suspend fun exportSavedPosts(): ByteArray {
+ val posts =
+ withContext(Dispatchers.IO) { database.savedPostQueries.selectAllPosts().executeAsList() }
+ return adapter.toJson(posts).toByteArray(Charsets.UTF_8)
+ }
+
+ suspend fun importSavedPosts(json: ByteArray) {
+ withContext(Dispatchers.IO) {
+ val posts = requireNotNull(adapter.fromJson(json.toString(Charsets.UTF_8)))
+ database.transaction { posts.forEach { database.savedPostQueries.insertOrReplacePost(it) } }
+ }
+ }
+}
diff --git a/app/src/main/java/dev/msfjarvis/lobsters/injection/BackupModule.kt b/app/src/main/java/dev/msfjarvis/lobsters/injection/BackupModule.kt
new file mode 100644
index 00000000..545dcc5f
--- /dev/null
+++ b/app/src/main/java/dev/msfjarvis/lobsters/injection/BackupModule.kt
@@ -0,0 +1,21 @@
+package dev.msfjarvis.lobsters.injection
+
+import com.squareup.moshi.Moshi
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.android.components.ActivityComponent
+import dev.msfjarvis.lobsters.data.backup.BackupHandler
+import dev.msfjarvis.lobsters.database.LobstersDatabase
+
+@Module
+@InstallIn(ActivityComponent::class)
+object BackupModule {
+ @Provides
+ fun provideBackupHandler(
+ database: LobstersDatabase,
+ moshi: Moshi,
+ ): BackupHandler {
+ return BackupHandler(database, moshi)
+ }
+}
diff --git a/app/src/main/java/dev/msfjarvis/lobsters/injection/DatabaseModule.kt b/app/src/main/java/dev/msfjarvis/lobsters/injection/DatabaseModule.kt
index a960454d..6638523a 100644
--- a/app/src/main/java/dev/msfjarvis/lobsters/injection/DatabaseModule.kt
+++ b/app/src/main/java/dev/msfjarvis/lobsters/injection/DatabaseModule.kt
@@ -1,41 +1,29 @@
package dev.msfjarvis.lobsters.injection
import android.content.Context
-import com.squareup.sqldelight.android.AndroidSqliteDriver
-import com.squareup.sqldelight.db.SqlDriver
import dagger.Module
import dagger.Provides
-import dagger.Reusable
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
-import dev.msfjarvis.lobsters.data.local.SavedPost
+import dev.msfjarvis.lobsters.data.local.DriverFactory
+import dev.msfjarvis.lobsters.data.local.createDatabase
import dev.msfjarvis.lobsters.database.LobstersDatabase
-import dev.msfjarvis.lobsters.model.TagsAdapter
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {
- @Provides
- @Reusable
- fun providesTagsAdapter(): TagsAdapter {
- return TagsAdapter()
- }
-
@Provides
@Singleton
- fun providesSqlDriver(@ApplicationContext context: Context): SqlDriver {
- return AndroidSqliteDriver(LobstersDatabase.Schema, context, "SavedPosts.db")
+ fun providesDriverFactory(@ApplicationContext context: Context): DriverFactory {
+ return DriverFactory(context)
}
@Provides
@Singleton
- fun providesLobstersDatabase(sqlDriver: SqlDriver, tagsAdapter: TagsAdapter): LobstersDatabase {
- return LobstersDatabase(
- sqlDriver,
- SavedPost.Adapter(tagsAdapter),
- )
+ fun providesLobstersDatabase(driverFactory: DriverFactory): LobstersDatabase {
+ return createDatabase(driverFactory)
}
}
diff --git a/app/src/main/java/dev/msfjarvis/lobsters/ui/main/LobstersApp.kt b/app/src/main/java/dev/msfjarvis/lobsters/ui/main/LobstersApp.kt
index f9a9e9cf..88f438a3 100644
--- a/app/src/main/java/dev/msfjarvis/lobsters/ui/main/LobstersApp.kt
+++ b/app/src/main/java/dev/msfjarvis/lobsters/ui/main/LobstersApp.kt
@@ -1,5 +1,6 @@
package dev.msfjarvis.lobsters.ui.main
+import android.content.Intent
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.BottomNavigation
@@ -11,6 +12,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.KEY_ROUTE
@@ -24,6 +26,7 @@ import androidx.paging.compose.collectAsLazyPagingItems
import dev.msfjarvis.lobsters.ui.navigation.Destination
import dev.msfjarvis.lobsters.ui.posts.NetworkPosts
import dev.msfjarvis.lobsters.ui.posts.SavedPosts
+import dev.msfjarvis.lobsters.ui.settings.SettingsActivity
import dev.msfjarvis.lobsters.ui.viewmodel.LobstersViewModel
import dev.msfjarvis.lobsters.util.IconResource
import dev.msfjarvis.lobsters.utils.get
@@ -32,6 +35,7 @@ import kotlinx.coroutines.launch
@Composable
fun LobstersApp() {
val viewModel: LobstersViewModel = viewModel()
+ val context = LocalContext.current
val navController = rememberNavController()
val hottestPosts = viewModel.hottestPosts.collectAsLazyPagingItems()
val newestPosts = viewModel.newestPosts.collectAsLazyPagingItems()
@@ -70,7 +74,7 @@ fun LobstersApp() {
LobstersTopAppBar(
currentDestination,
viewModel::toggleSortOrder,
- )
+ ) { context.startActivity(Intent(context, SettingsActivity::class.java)) }
},
bottomBar = {
LobstersBottomNav(
diff --git a/app/src/main/java/dev/msfjarvis/lobsters/ui/main/LobstersTopAppBar.kt b/app/src/main/java/dev/msfjarvis/lobsters/ui/main/LobstersTopAppBar.kt
index fc63e087..3e2a4f51 100644
--- a/app/src/main/java/dev/msfjarvis/lobsters/ui/main/LobstersTopAppBar.kt
+++ b/app/src/main/java/dev/msfjarvis/lobsters/ui/main/LobstersTopAppBar.kt
@@ -22,6 +22,7 @@ import kotlinx.coroutines.launch
fun LobstersTopAppBar(
currentDestination: Destination,
toggleSortingOrder: suspend () -> Unit,
+ launchSettings: () -> Unit,
) {
val scope = rememberCoroutineScope()
TopAppBar(
@@ -42,6 +43,14 @@ fun LobstersTopAppBar(
},
)
}
+ IconResource(
+ resourceId = R.drawable.ic_app_settings_24px,
+ contentDescription = Strings.Settings.get(),
+ modifier =
+ Modifier.padding(horizontal = 8.dp, vertical = 8.dp).clickable {
+ scope.launch { launchSettings() }
+ },
+ )
}
)
}
diff --git a/app/src/main/java/dev/msfjarvis/lobsters/ui/settings/Options.kt b/app/src/main/java/dev/msfjarvis/lobsters/ui/settings/Options.kt
new file mode 100644
index 00000000..2861338b
--- /dev/null
+++ b/app/src/main/java/dev/msfjarvis/lobsters/ui/settings/Options.kt
@@ -0,0 +1,60 @@
+package dev.msfjarvis.lobsters.ui.settings
+
+import android.content.Context
+import androidx.activity.compose.registerForActivityResult
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.compose.runtime.Composable
+import dev.msfjarvis.lobsters.data.backup.BackupHandler
+import dev.msfjarvis.lobsters.utils.Strings
+import dev.msfjarvis.lobsters.utils.get
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+
+private const val JSON_MINE = "application/json"
+
+@Composable
+fun BackupOption(
+ context: Context,
+ backupHandler: BackupHandler,
+ coroutineScope: CoroutineScope,
+) {
+ val result =
+ registerForActivityResult(ActivityResultContracts.CreateDocument()) { uri ->
+ if (uri == null) return@registerForActivityResult
+ context.contentResolver.openOutputStream(uri)?.let {
+ coroutineScope.launch(Dispatchers.IO) {
+ it.write(backupHandler.exportSavedPosts())
+ it.close()
+ }
+ }
+ }
+ SettingsActionItem(
+ Strings.SettingsBackup.get(),
+ Strings.SettingsBackupDescription.get(),
+ onClick = { result.launch("Claw-export.json") }
+ )
+}
+
+@Composable
+fun RestoreOption(
+ context: Context,
+ backupHandler: BackupHandler,
+ coroutineScope: CoroutineScope,
+) {
+ val result =
+ registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
+ if (uri == null) return@registerForActivityResult
+ context.contentResolver.openInputStream(uri)?.let {
+ coroutineScope.launch(Dispatchers.IO) {
+ backupHandler.importSavedPosts(it.readBytes())
+ it.close()
+ }
+ }
+ }
+ SettingsActionItem(
+ title = Strings.SettingsRestore.get(),
+ description = Strings.SettingsRestoreDescription.get(),
+ onClick = { result.launch(JSON_MINE) }
+ )
+}
diff --git a/app/src/main/java/dev/msfjarvis/lobsters/ui/settings/Settings.kt b/app/src/main/java/dev/msfjarvis/lobsters/ui/settings/Settings.kt
new file mode 100644
index 00000000..9a43d2c2
--- /dev/null
+++ b/app/src/main/java/dev/msfjarvis/lobsters/ui/settings/Settings.kt
@@ -0,0 +1,95 @@
+package dev.msfjarvis.lobsters.ui.settings
+
+import android.content.Context
+import androidx.activity.ComponentActivity
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.material.Icon
+import androidx.compose.material.ListItem
+import androidx.compose.material.Scaffold
+import androidx.compose.material.Text
+import androidx.compose.material.TopAppBar
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.unit.dp
+import dev.msfjarvis.lobsters.data.backup.BackupHandler
+import dev.msfjarvis.lobsters.utils.Strings
+import dev.msfjarvis.lobsters.utils.get
+import kotlinx.coroutines.CoroutineScope
+
+@Composable
+fun LobstersSettings(
+ backupHandler: BackupHandler,
+) {
+ val context = LocalContext.current
+ val scope = rememberCoroutineScope()
+ Scaffold(
+ topBar = { SettingsTopBar(context) },
+ content = { SettingsBody(context, backupHandler, scope) },
+ )
+}
+
+@Composable
+fun SettingsTopBar(
+ context: Context,
+) {
+ TopAppBar(
+ title = { Text(Strings.Settings.get()) },
+ navigationIcon = {
+ Icon(
+ Icons.Default.ArrowBack,
+ contentDescription = Strings.Settings.get(),
+ modifier =
+ Modifier.padding(start = 16.dp).clickable { (context as ComponentActivity).finish() },
+ )
+ },
+ )
+}
+
+@Composable
+fun SettingsBody(
+ context: Context,
+ backupHandler: BackupHandler,
+ scope: CoroutineScope,
+) {
+ LazyColumn {
+ item {
+ BackupOption(
+ context,
+ backupHandler,
+ scope,
+ )
+ }
+ item {
+ RestoreOption(
+ context,
+ backupHandler,
+ scope,
+ )
+ }
+ }
+}
+
+@Composable
+fun SettingsActionItem(
+ title: String,
+ description: String? = null,
+ singleLineDescription: Boolean = true,
+ icon: ImageVector? = null,
+ onClick: (() -> Unit)? = null,
+) {
+ ListItem(
+ text = { Text(title) },
+ secondaryText = { description?.let { Text(it) } },
+ icon = { icon?.let { Icon(icon, null, Modifier.height(32.dp)) } },
+ singleLineSecondaryText = singleLineDescription,
+ modifier = Modifier.clickable { onClick?.invoke() },
+ )
+}
diff --git a/app/src/main/java/dev/msfjarvis/lobsters/ui/settings/SettingsActivity.kt b/app/src/main/java/dev/msfjarvis/lobsters/ui/settings/SettingsActivity.kt
new file mode 100644
index 00000000..38961b4e
--- /dev/null
+++ b/app/src/main/java/dev/msfjarvis/lobsters/ui/settings/SettingsActivity.kt
@@ -0,0 +1,20 @@
+package dev.msfjarvis.lobsters.ui.settings
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import dagger.hilt.android.AndroidEntryPoint
+import dev.msfjarvis.lobsters.data.backup.BackupHandler
+import dev.msfjarvis.lobsters.ui.theme.LobstersTheme
+import javax.inject.Inject
+
+@AndroidEntryPoint
+class SettingsActivity : ComponentActivity() {
+
+ @Inject lateinit var backupHandler: BackupHandler
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent { LobstersTheme { LobstersSettings(backupHandler) } }
+ }
+}
diff --git a/app/src/main/res/drawable/ic_app_settings_24px.xml b/app/src/main/res/drawable/ic_app_settings_24px.xml
new file mode 100644
index 00000000..0c0c36b0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_app_settings_24px.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/common/src/androidMain/kotlin/dev/msfjarvis/lobsters/utils/StringValue.kt b/common/src/androidMain/kotlin/dev/msfjarvis/lobsters/utils/StringValue.kt
index 8af20951..c561b196 100644
--- a/common/src/androidMain/kotlin/dev/msfjarvis/lobsters/utils/StringValue.kt
+++ b/common/src/androidMain/kotlin/dev/msfjarvis/lobsters/utils/StringValue.kt
@@ -11,13 +11,18 @@ private fun stringEnumMapper(stringEnum: Strings): Int {
Strings.AvatarContentDescription -> R.string.avatar_content_description
Strings.ChangeSortingOrder -> R.string.change_sorting_order
Strings.HottestPosts -> R.string.hottest_posts
+ Strings.NewestPosts -> R.string.newest_posts
Strings.NoSavedPost -> R.string.no_saved_posts
Strings.OpenComments -> R.string.open_comments
Strings.RefreshPostsContentDescription -> R.string.refresh_posts_content_description
Strings.RemoveFromSavedPosts -> R.string.remove_from_saved_posts
Strings.SavedPosts -> R.string.saved_posts
Strings.SubmittedBy -> R.string.submitted_by
- Strings.NewestPosts -> R.string.newest_posts
+ Strings.Settings -> R.string.settings
+ Strings.SettingsBackup -> R.string.settings_backup
+ Strings.SettingsBackupDescription -> R.string.settings_backup_desc
+ Strings.SettingsRestore -> R.string.settings_restore
+ Strings.SettingsRestoreDescription -> R.string.settings_restore_desc
}
}
diff --git a/common/src/androidMain/res/values/strings.xml b/common/src/androidMain/res/values/strings.xml
index 0de8ea60..74e570c2 100644
--- a/common/src/androidMain/res/values/strings.xml
+++ b/common/src/androidMain/res/values/strings.xml
@@ -11,4 +11,9 @@
Open comments
Change sort order
Newest
+ Settings
+ Backup saved posts
+ Export saved posts in a JSON file that can be restored later
+ Restore saved posts
+ Import a previously exported copy of saved posts. Existing saved posts are not cleared
diff --git a/common/src/commonMain/kotlin/dev/msfjarvis/lobsters/utils/Strings.kt b/common/src/commonMain/kotlin/dev/msfjarvis/lobsters/utils/Strings.kt
index 13d946a9..cff1c835 100644
--- a/common/src/commonMain/kotlin/dev/msfjarvis/lobsters/utils/Strings.kt
+++ b/common/src/commonMain/kotlin/dev/msfjarvis/lobsters/utils/Strings.kt
@@ -13,4 +13,9 @@ enum class Strings {
SavedPosts,
SubmittedBy,
NewestPosts,
+ Settings,
+ SettingsBackup,
+ SettingsBackupDescription,
+ SettingsRestore,
+ SettingsRestoreDescription,
}
diff --git a/common/src/jvmMain/kotlin/dev/msfjarvis/lobsters/utils/StringValue.kt b/common/src/jvmMain/kotlin/dev/msfjarvis/lobsters/utils/StringValue.kt
index 27f54788..c2a10b61 100644
--- a/common/src/jvmMain/kotlin/dev/msfjarvis/lobsters/utils/StringValue.kt
+++ b/common/src/jvmMain/kotlin/dev/msfjarvis/lobsters/utils/StringValue.kt
@@ -16,6 +16,13 @@ private fun stringEnumMapper(stringEnum: Strings): String {
Strings.SavedPosts -> "Saved"
Strings.SubmittedBy -> "submitted by %1s"
Strings.NewestPosts -> "Newest"
+ Strings.Settings -> "Settings"
+ Strings.SettingsBackup -> "Backup saved posts"
+ Strings.SettingsBackupDescription ->
+ "Export saved posts in a JSON file that can be restored later"
+ Strings.SettingsRestore -> "Restore saved posts"
+ Strings.SettingsRestoreDescription ->
+ "Import a previously exported copy of saved posts. Existing saved posts are not cleared"
}
}
diff --git a/database/build.gradle.kts b/database/build.gradle.kts
index daaf6ca9..763013a7 100644
--- a/database/build.gradle.kts
+++ b/database/build.gradle.kts
@@ -1,11 +1,48 @@
plugins {
- kotlin("jvm")
+ kotlin("multiplatform")
+ id("com.android.library")
id("com.squareup.sqldelight")
`lobsters-plugin`
}
-dependencies {
- testImplementation(Dependencies.Kotlin.Coroutines.core)
- testImplementation(Dependencies.ThirdParty.SQLDelight.jvmDriver)
- testImplementation(kotlin("test-junit"))
+// workaround for https://youtrack.jetbrains.com/issue/KT-43944
+android {
+ configurations {
+ create("androidTestApi")
+ create("androidTestDebugApi")
+ create("androidTestReleaseApi")
+ create("testApi")
+ create("testDebugApi")
+ create("testReleaseApi")
+ }
+}
+
+kotlin {
+ jvm()
+ android()
+
+ sourceSets {
+ val commonMain by getting {
+ }
+ val jvmTest by getting {
+ dependencies {
+ implementation(Dependencies.Kotlin.Coroutines.core)
+ implementation(kotlin("test-junit"))
+ }
+ }
+ val jvmMain by getting {
+ dependencies {
+ implementation(Dependencies.ThirdParty.SQLDelight.jvmDriver)
+ }
+ }
+ val androidMain by getting {
+ dependencies {
+ implementation(Dependencies.ThirdParty.SQLDelight.androidDriver)
+ }
+ }
+ }
+}
+
+android {
+ sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
}
diff --git a/database/src/androidMain/AndroidManifest.xml b/database/src/androidMain/AndroidManifest.xml
new file mode 100644
index 00000000..4ee754c1
--- /dev/null
+++ b/database/src/androidMain/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/database/src/androidMain/kotlin/dev/msfjarvis/lobsters/data/local/Database.kt b/database/src/androidMain/kotlin/dev/msfjarvis/lobsters/data/local/Database.kt
new file mode 100644
index 00000000..37209b72
--- /dev/null
+++ b/database/src/androidMain/kotlin/dev/msfjarvis/lobsters/data/local/Database.kt
@@ -0,0 +1,12 @@
+package dev.msfjarvis.lobsters.data.local
+
+import android.content.Context
+import com.squareup.sqldelight.android.AndroidSqliteDriver
+import com.squareup.sqldelight.db.SqlDriver
+import dev.msfjarvis.lobsters.database.LobstersDatabase
+
+actual class DriverFactory(private val context: Context) {
+ actual fun createDriver(): SqlDriver {
+ return AndroidSqliteDriver(LobstersDatabase.Schema, context, LobstersDatabaseName)
+ }
+}
diff --git a/database/src/commonMain/kotlin/dev/msfjarvis/lobsters/data/local/Database.kt b/database/src/commonMain/kotlin/dev/msfjarvis/lobsters/data/local/Database.kt
new file mode 100644
index 00000000..1ab3266e
--- /dev/null
+++ b/database/src/commonMain/kotlin/dev/msfjarvis/lobsters/data/local/Database.kt
@@ -0,0 +1,18 @@
+package dev.msfjarvis.lobsters.data.local
+
+import com.squareup.sqldelight.db.SqlDriver
+import dev.msfjarvis.lobsters.data.model.TagsAdapter
+import dev.msfjarvis.lobsters.database.LobstersDatabase
+
+internal const val LobstersDatabaseName = "SavedPosts.db"
+
+expect class DriverFactory {
+ fun createDriver(): SqlDriver
+}
+
+private fun getTagsAdapter() = TagsAdapter()
+
+fun createDatabase(driverFactory: DriverFactory): LobstersDatabase {
+ val driver = driverFactory.createDriver()
+ return LobstersDatabase(driver, SavedPost.Adapter(getTagsAdapter()))
+}
diff --git a/database/src/main/java/dev/msfjarvis/lobsters/model/TagsAdapter.kt b/database/src/commonMain/kotlin/dev/msfjarvis/lobsters/data/model/TagsAdapter.kt
similarity index 90%
rename from database/src/main/java/dev/msfjarvis/lobsters/model/TagsAdapter.kt
rename to database/src/commonMain/kotlin/dev/msfjarvis/lobsters/data/model/TagsAdapter.kt
index a4a04588..3b8fcb48 100644
--- a/database/src/main/java/dev/msfjarvis/lobsters/model/TagsAdapter.kt
+++ b/database/src/commonMain/kotlin/dev/msfjarvis/lobsters/data/model/TagsAdapter.kt
@@ -1,4 +1,4 @@
-package dev.msfjarvis.lobsters.model
+package dev.msfjarvis.lobsters.data.model
import com.squareup.sqldelight.ColumnAdapter
diff --git a/database/src/main/sqldelight/dev/msfjarvis/lobsters/data/local/SavedPost.sq b/database/src/commonMain/sqldelight/dev/msfjarvis/lobsters/data/local/SavedPost.sq
similarity index 100%
rename from database/src/main/sqldelight/dev/msfjarvis/lobsters/data/local/SavedPost.sq
rename to database/src/commonMain/sqldelight/dev/msfjarvis/lobsters/data/local/SavedPost.sq
diff --git a/database/src/jvmMain/kotlin/dev/msfjarvis/lobsters/data/local/Database.kt b/database/src/jvmMain/kotlin/dev/msfjarvis/lobsters/data/local/Database.kt
new file mode 100644
index 00000000..9883a8a3
--- /dev/null
+++ b/database/src/jvmMain/kotlin/dev/msfjarvis/lobsters/data/local/Database.kt
@@ -0,0 +1,13 @@
+package dev.msfjarvis.lobsters.data.local
+
+import com.squareup.sqldelight.db.SqlDriver
+import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver
+import dev.msfjarvis.lobsters.database.LobstersDatabase
+
+actual class DriverFactory {
+ actual fun createDriver(): SqlDriver {
+ val driver: SqlDriver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
+ LobstersDatabase.Schema.create(driver)
+ return driver
+ }
+}
diff --git a/database/src/test/java/dev/msfjarvis/lobsters/data/local/SqlDelightQueriesTest.kt b/database/src/jvmTest/kotlin/dev/msfjarvis/lobsters/data/local/SqlDelightQueriesTest.kt
similarity index 98%
rename from database/src/test/java/dev/msfjarvis/lobsters/data/local/SqlDelightQueriesTest.kt
rename to database/src/jvmTest/kotlin/dev/msfjarvis/lobsters/data/local/SqlDelightQueriesTest.kt
index 68bee231..5ca12981 100644
--- a/database/src/test/java/dev/msfjarvis/lobsters/data/local/SqlDelightQueriesTest.kt
+++ b/database/src/jvmTest/kotlin/dev/msfjarvis/lobsters/data/local/SqlDelightQueriesTest.kt
@@ -1,8 +1,8 @@
package dev.msfjarvis.lobsters.data.local
import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver
+import dev.msfjarvis.lobsters.data.model.TagsAdapter
import dev.msfjarvis.lobsters.database.LobstersDatabase
-import dev.msfjarvis.lobsters.model.TagsAdapter
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlinx.coroutines.runBlocking