mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-17 08:37:03 +05:30
Merge #165
165: Allow backup and restore of saved posts r=msfjarvis a=msfjarvis Very much WIP, lacks essentially everything right now. Co-authored-by: Aditya Wasan <adityawasan55@gmail.com> Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
commit
e50a8e8d68
25 changed files with 389 additions and 28 deletions
8
.idea/artifacts/database_jvm.xml
generated
Normal file
8
.idea/artifacts/database_jvm.xml
generated
Normal file
|
@ -0,0 +1,8 @@
|
|||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="database-jvm">
|
||||
<output-path>$PROJECT_DIR$/database/build/libs</output-path>
|
||||
<root id="archive" name="database-jvm.jar">
|
||||
<element id="module-output" name="database.Claw.database.jvmMain" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
|
@ -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"))
|
||||
}
|
||||
|
|
|
@ -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 = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,14 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.settings.SettingsActivity"
|
||||
android:theme="@style/Platform.Theme.Claw"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -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<List<SavedPost>>()
|
||||
|
||||
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) } }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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() }
|
||||
},
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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) }
|
||||
)
|
||||
}
|
|
@ -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() },
|
||||
)
|
||||
}
|
|
@ -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) } }
|
||||
}
|
||||
}
|
9
app/src/main/res/drawable/ic_app_settings_24px.xml
Normal file
9
app/src/main/res/drawable/ic_app_settings_24px.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M21.81,12.74l-0.82,-0.63v-0.22l0.8,-0.63c0.16,-0.12 0.2,-0.34 0.1,-0.51l-0.85,-1.48c-0.07,-0.13 -0.21,-0.2 -0.35,-0.2 -0.05,0 -0.1,0.01 -0.15,0.03l-0.95,0.38c-0.08,-0.05 -0.11,-0.07 -0.19,-0.11l-0.15,-1.01c-0.03,-0.21 -0.2,-0.36 -0.4,-0.36h-1.71c-0.2,0 -0.37,0.15 -0.4,0.34l-0.14,1.01c-0.03,0.02 -0.07,0.03 -0.1,0.05l-0.09,0.06 -0.95,-0.38c-0.05,-0.02 -0.1,-0.03 -0.15,-0.03 -0.14,0 -0.27,0.07 -0.35,0.2l-0.85,1.48c-0.1,0.17 -0.06,0.39 0.1,0.51l0.8,0.63v0.23l-0.8,0.63c-0.16,0.12 -0.2,0.34 -0.1,0.51l0.85,1.48c0.07,0.13 0.21,0.2 0.35,0.2 0.05,0 0.1,-0.01 0.15,-0.03l0.95,-0.37c0.08,0.05 0.12,0.07 0.2,0.11l0.15,1.01c0.03,0.2 0.2,0.34 0.4,0.34h1.71c0.2,0 0.37,-0.15 0.4,-0.34l0.15,-1.01c0.03,-0.02 0.07,-0.03 0.1,-0.05l0.09,-0.06 0.95,0.38c0.05,0.02 0.1,0.03 0.15,0.03 0.14,0 0.27,-0.07 0.35,-0.2l0.85,-1.48c0.1,-0.17 0.06,-0.39 -0.1,-0.51zM18,13.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM17,17h2v4c0,1.1 -0.9,2 -2,2H7c-1.1,0 -2,-0.9 -2,-2V3c0,-1.1 0.9,-2 2,-2h10c1.1,0 2,0.9 2,2v4h-2V6H7v12h10v-1z" />
|
||||
</vector>
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,4 +11,9 @@
|
|||
<string name="open_comments">Open comments</string>
|
||||
<string name="change_sorting_order">Change sort order</string>
|
||||
<string name="newest_posts">Newest</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="settings_backup">Backup saved posts</string>
|
||||
<string name="settings_backup_desc">Export saved posts in a JSON file that can be restored later</string>
|
||||
<string name="settings_restore">Restore saved posts</string>
|
||||
<string name="settings_restore_desc">Import a previously exported copy of saved posts. Existing saved posts are not cleared</string>
|
||||
</resources>
|
||||
|
|
|
@ -13,4 +13,9 @@ enum class Strings {
|
|||
SavedPosts,
|
||||
SubmittedBy,
|
||||
NewestPosts,
|
||||
Settings,
|
||||
SettingsBackup,
|
||||
SettingsBackupDescription,
|
||||
SettingsRestore,
|
||||
SettingsRestoreDescription,
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
2
database/src/androidMain/AndroidManifest.xml
Normal file
2
database/src/androidMain/AndroidManifest.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="dev.msfjarvis.lobsters.database" />
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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()))
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.msfjarvis.lobsters.model
|
||||
package dev.msfjarvis.lobsters.data.model
|
||||
|
||||
import com.squareup.sqldelight.ColumnAdapter
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue