diff --git a/src/app/src/androidTest/java/com/couchbase/learningpath/DatabaseIntegrationTests.kt b/src/app/src/androidTest/java/com/couchbase/learningpath/DatabaseIntegrationTests.kt index 004cb3d..83d6f7d 100644 --- a/src/app/src/androidTest/java/com/couchbase/learningpath/DatabaseIntegrationTests.kt +++ b/src/app/src/androidTest/java/com/couchbase/learningpath/DatabaseIntegrationTests.kt @@ -59,7 +59,7 @@ class DatabaseIntegrationTests { try { //arrange database context = ApplicationProvider.getApplicationContext() - databaseManager = DatabaseManager.getInstance(context) + databaseManager = DatabaseManager(context) //arrange test users user1 = User( @@ -84,16 +84,15 @@ class DatabaseIntegrationTests { val isAuth = authenticationService.authenticatedUser(user1.username, user1.password) //arrange repositories - auditRepository = AuditRepositoryDb(context, authenticationService) - stockItemRepository = StockItemRepositoryDb(context) - warehouseRepository = WarehouseRepositoryDb(context) - userProfileRepository = UserProfileRepository(context) + auditRepository = AuditRepositoryDb(authenticationService, databaseManager) + stockItemRepository = StockItemRepositoryDb(databaseManager) + warehouseRepository = WarehouseRepositoryDb(databaseManager) + userProfileRepository = UserProfileRepository(databaseManager) projectRepository = ProjectRepositoryDb( - context = context, authenticationService = authenticationService, - auditRepository = auditRepository, warehouseRepository = warehouseRepository, - stockItemRepository = stockItemRepository + stockItemRepository = stockItemRepository, + databaseManager = databaseManager ) //load sample data diff --git a/src/app/src/main/java/com/couchbase/learningpath/InventoryApplication.kt b/src/app/src/main/java/com/couchbase/learningpath/InventoryApplication.kt index ef407de..3ccfdeb 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/InventoryApplication.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/InventoryApplication.kt @@ -1,15 +1,14 @@ package com.couchbase.learningpath import android.app.Application +import com.couchbase.learningpath.data.DatabaseManager import org.koin.android.BuildConfig import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidLogger -import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.core.context.GlobalContext import org.koin.core.logger.Level import org.koin.core.module.Module import org.koin.dsl.module -import java.lang.ref.WeakReference import com.couchbase.learningpath.data.KeyValueRepository import com.couchbase.learningpath.data.audits.AuditRepository @@ -41,6 +40,9 @@ import com.couchbase.learningpath.ui.project.ProjectListViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.InternalCoroutinesApi import kotlinx.serialization.ExperimentalSerializationApi +import org.koin.androidx.viewmodel.dsl.viewModelOf +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.bind @ExperimentalSerializationApi @ExperimentalCoroutinesApi @@ -69,31 +71,29 @@ class InventoryApplication @OptIn(InternalCoroutinesApi::class) private fun registerDependencies() : Module { return module { - // ** DO NOT listen to the NO cast needed warnings - removing the as statement will - // ** result in the application not functioning correctly - single { MockAuthenticationService() as AuthenticationService } - single { ReplicatorServiceDb(get(), this@InventoryApplication) as ReplicatorService } - single { UserProfileRepository(this@InventoryApplication) as KeyValueRepository } - single { WarehouseRepositoryDb(this@InventoryApplication) as WarehouseRepository } - single { ProjectRepositoryDb(this@InventoryApplication, get(), get(), get(), get()) as ProjectRepository } - single { StockItemRepositoryDb(this@InventoryApplication) as StockItemRepository } - single { AuditRepositoryDb(this@InventoryApplication, get()) as AuditRepository } + singleOf(::DatabaseManager) + singleOf(::MockAuthenticationService) bind AuthenticationService::class + singleOf(::ReplicatorServiceDb) bind ReplicatorService::class + singleOf(::UserProfileRepository) bind KeyValueRepository::class + singleOf(::WarehouseRepositoryDb) bind WarehouseRepository::class + singleOf(::ProjectRepositoryDb) bind ProjectRepository::class + singleOf(::StockItemRepositoryDb) bind StockItemRepository::class + singleOf(::AuditRepositoryDb) bind AuditRepository::class - viewModel { MainViewModel(get(), get(), WeakReference(this@InventoryApplication)) } - viewModel { LoginViewModel(get(), get(), WeakReference(this@InventoryApplication)) } - viewModel { ProjectListViewModel(get(), get()) } - viewModel { ProjectEditorViewModel(get()) } - viewModel { AuditListViewModel(get())} - viewModel { AuditEditorViewModel(get()) as AuditEditorViewModel} - - viewModel { WarehouseSelectionViewModel(get(), get()) } - viewModel { StockItemSelectionViewModel(get(), get()) } - viewModel { UserProfileViewModel(get(), get(), WeakReference(this@InventoryApplication)) } - viewModel { DeveloperViewModel(get()) } - viewModel { DevDatabaseInfoViewModel(get(), get(), get(), get(), get(), get()) } - viewModel { ReplicatorViewModel(get())} - viewModel { ReplicatorConfigViewModel(get())} + viewModelOf(::MainViewModel) + viewModelOf(::LoginViewModel) + viewModelOf(::ProjectListViewModel) + viewModelOf(::ProjectEditorViewModel) + viewModelOf(::AuditListViewModel) + viewModelOf(::AuditEditorViewModel) + viewModelOf(::WarehouseSelectionViewModel) + viewModelOf(::StockItemSelectionViewModel) + viewModelOf(::UserProfileViewModel) + viewModelOf(::DeveloperViewModel) + viewModelOf(::DevDatabaseInfoViewModel) + viewModelOf(::ReplicatorViewModel) + viewModelOf(::ReplicatorConfigViewModel) } } } \ No newline at end of file diff --git a/src/app/src/main/java/com/couchbase/learningpath/data/DatabaseManager.kt b/src/app/src/main/java/com/couchbase/learningpath/data/DatabaseManager.kt index bf0af9d..e1db3ea 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/data/DatabaseManager.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/data/DatabaseManager.kt @@ -2,14 +2,13 @@ package com.couchbase.learningpath.data import android.content.Context import com.couchbase.learningpath.models.User -import com.couchbase.learningpath.util.Singleton import com.couchbase.lite.* import java.io.File import java.io.FileOutputStream import java.util.zip.ZipEntry import java.util.zip.ZipInputStream -class DatabaseManager private constructor(private val context: Context) { +class DatabaseManager(private val context: Context) { var inventoryDatabase: Database? = null var warehouseDatabase: Database? = null @@ -253,6 +252,4 @@ class DatabaseManager private constructor(private val context: Context) { stream.close() } } - - companion object : Singleton(::DatabaseManager) } \ No newline at end of file diff --git a/src/app/src/main/java/com/couchbase/learningpath/data/audits/AuditRepositoryDb.kt b/src/app/src/main/java/com/couchbase/learningpath/data/audits/AuditRepositoryDb.kt index 4a7fd36..89c0dc7 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/data/audits/AuditRepositoryDb.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/data/audits/AuditRepositoryDb.kt @@ -2,12 +2,10 @@ package com.couchbase.learningpath.data.audits -import android.content.Context import android.util.Log import com.couchbase.learningpath.data.DatabaseManager import com.couchbase.learningpath.models.Audit import com.couchbase.learningpath.models.AuditDao -import com.couchbase.learningpath.models.Project import com.couchbase.learningpath.models.StockItem import com.couchbase.learningpath.services.AuthenticationService import com.couchbase.lite.* @@ -23,15 +21,13 @@ import java.util.* @OptIn(ExperimentalCoroutinesApi::class) class AuditRepositoryDb( - var context: Context, - private val authenticationService: AuthenticationService + private val authenticationService: AuthenticationService, + private val databaseManager: DatabaseManager ) : AuditRepository { - private val databaseResources: DatabaseManager = DatabaseManager.getInstance(context) - override fun getAuditsByProjectId(projectId: String): Flow>? { try { - val db = databaseResources.inventoryDatabase + val db = databaseManager.inventoryDatabase val team = authenticationService.getCurrentUser().team db?.let { database -> val query = @@ -58,7 +54,7 @@ class AuditRepositoryDb( override suspend fun get(projectId: String, auditId: String): Audit { return withContext(Dispatchers.IO) { try { - val db = databaseResources.inventoryDatabase + val db = databaseManager.inventoryDatabase db?.let { database -> val doc = database.getDocument(auditId) doc?.let { document -> @@ -89,7 +85,7 @@ class AuditRepositoryDb( override suspend fun save(document: Audit) { return withContext(Dispatchers.IO) { try { - val db = databaseResources.inventoryDatabase + val db = databaseManager.inventoryDatabase db?.let { database -> val json = Json.encodeToString(document) val doc = MutableDocument(document.auditId, json) @@ -108,7 +104,7 @@ class AuditRepositoryDb( ) { return withContext(Dispatchers.IO) { try { - val db = databaseResources.inventoryDatabase + val db = databaseManager.inventoryDatabase val audit = get(projectId, auditId) audit.stockItem = stockItem audit.notes = "Found item ${stockItem.name} - ${stockItem.description} in warehouse" @@ -139,7 +135,7 @@ class AuditRepositoryDb( return withContext(Dispatchers.IO) { var result = false try { - val db = databaseResources.inventoryDatabase + val db = databaseManager.inventoryDatabase db?.let { database -> val doc = database.getDocument(documentId) doc?.let { document -> @@ -158,7 +154,7 @@ class AuditRepositoryDb( return withContext(Dispatchers.IO) { var count = 0 try { - val db = DatabaseManager.getInstance(context).inventoryDatabase + val db = databaseManager.inventoryDatabase db?.let { database -> val query = database.createQuery("SELECT COUNT(*) AS count FROM _ AS item WHERE documentType=\"audit\"") // 1 diff --git a/src/app/src/main/java/com/couchbase/learningpath/data/project/ProjectRepositoryDb.kt b/src/app/src/main/java/com/couchbase/learningpath/data/project/ProjectRepositoryDb.kt index 1e37559..62bd67a 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/data/project/ProjectRepositoryDb.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/data/project/ProjectRepositoryDb.kt @@ -1,6 +1,5 @@ package com.couchbase.learningpath.data.project -import android.content.Context import android.util.Log import com.couchbase.lite.* import kotlinx.coroutines.Dispatchers @@ -17,7 +16,6 @@ import java.text.SimpleDateFormat import java.util.* import com.couchbase.learningpath.data.DatabaseManager -import com.couchbase.learningpath.data.audits.AuditRepository import com.couchbase.learningpath.data.stockItem.StockItemRepository import com.couchbase.learningpath.data.warehouse.WarehouseRepository import com.couchbase.learningpath.models.Audit @@ -30,23 +28,22 @@ import kotlinx.serialization.ExperimentalSerializationApi @ExperimentalCoroutinesApi @ExperimentalSerializationApi class ProjectRepositoryDb( - private val context: Context, private val authenticationService: AuthenticationService, - private val auditRepository: AuditRepository, private val warehouseRepository: WarehouseRepository, private val stockItemRepository: StockItemRepository, + private val databaseManager: DatabaseManager ) : ProjectRepository { private val projectDocumentType = "project" private val auditDocumentType = "audit" override val databaseName: String - get() = DatabaseManager.getInstance(context).currentInventoryDatabaseName + get() = databaseManager.currentInventoryDatabaseName //live query demo of returning project documents override fun getDocuments(team: String): Flow> { try { - val db = DatabaseManager.getInstance(context).inventoryDatabase + val db = databaseManager.inventoryDatabase // NOTE - the as method is a also a keyword in Kotlin, so it must be escaped using // `as` - this will probably break intellisense, so it will act like the where // method isn't available work around is to do your entire statement without the as @@ -92,7 +89,7 @@ class ProjectRepositoryDb( override suspend fun get(documentId: String): Project { return withContext(Dispatchers.IO) { try { - val db = DatabaseManager.getInstance(context).inventoryDatabase + val db = databaseManager.inventoryDatabase db?.let { database -> val doc = database.getDocument(documentId) doc?.let { document -> @@ -136,7 +133,7 @@ class ProjectRepositoryDb( override suspend fun updateProjectWarehouse(projectId: String, warehouse: Warehouse) { return withContext(Dispatchers.IO) { try { - val db = DatabaseManager.getInstance(context).inventoryDatabase + val db = databaseManager.inventoryDatabase val project = get(projectId) project.warehouse = warehouse db?.let { database -> @@ -153,7 +150,7 @@ class ProjectRepositoryDb( override suspend fun save(document: Project) { return withContext(Dispatchers.IO) { try { - val db = DatabaseManager.getInstance(context).inventoryDatabase + val db = databaseManager.inventoryDatabase db?.let { database -> val json = Json.encodeToString(document) val doc = MutableDocument(document.projectId, json) @@ -173,7 +170,7 @@ class ProjectRepositoryDb( return withContext(Dispatchers.IO) { var result = false try { - val db = DatabaseManager.getInstance(context).inventoryDatabase + val db = databaseManager.inventoryDatabase db?.let { database -> val projectDoc = database.getDocument(documentId) projectDoc?.let { document -> @@ -192,7 +189,7 @@ class ProjectRepositoryDb( return withContext(Dispatchers.IO) { var count = 0 try { - val db = DatabaseManager.getInstance(context).inventoryDatabase + val db = databaseManager.inventoryDatabase db?.let { database -> val query = QueryBuilder // 1 .select( @@ -223,7 +220,7 @@ class ProjectRepositoryDb( val stockItemsCount = stockItems.count() - 1 // <5> if (warehouseCount > 0 && stockItemsCount > 0) { - val db = DatabaseManager.getInstance(context).inventoryDatabase + val db = databaseManager.inventoryDatabase db?.let { database -> // batch operations for saving multiple documents // this is a faster way to process groups of documents at once diff --git a/src/app/src/main/java/com/couchbase/learningpath/data/stockItem/StockItemRepositoryDb.kt b/src/app/src/main/java/com/couchbase/learningpath/data/stockItem/StockItemRepositoryDb.kt index ec7c19c..cf9d6b0 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/data/stockItem/StockItemRepositoryDb.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/data/stockItem/StockItemRepositoryDb.kt @@ -2,9 +2,7 @@ package com.couchbase.learningpath.data.stockItem -import android.content.Context import android.util.Log -import androidx.compose.ui.text.toLowerCase import com.couchbase.learningpath.data.DatabaseManager import com.couchbase.learningpath.models.StockItem import com.couchbase.learningpath.models.StockItemDao @@ -16,21 +14,20 @@ import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json class StockItemRepositoryDb( - var context: Context + private val databaseManager: DatabaseManager ) : StockItemRepository { - private val databaseResources: DatabaseManager = DatabaseManager.getInstance(context) private val documentType = "item" override val databaseName: () -> String? = - { DatabaseManager.getInstance(context).warehouseDatabase?.name } + { databaseManager.warehouseDatabase?.name } override val databaseLocation: () -> String? = - { DatabaseManager.getInstance(context).warehouseDatabase?.path } + { databaseManager.warehouseDatabase?.path } override suspend fun get(): List { return withContext(Dispatchers.IO) { val stockItems = mutableListOf() try { - val db = databaseResources.warehouseDatabase + val db = databaseManager.warehouseDatabase db?.let { database -> val query = database.createQuery("SELECT * FROM _ AS item WHERE documentType=\"$documentType\"") @@ -51,7 +48,7 @@ class StockItemRepositoryDb( return withContext(Dispatchers.IO) { var count = 0 try { - val db = DatabaseManager.getInstance(context).warehouseDatabase + val db = databaseManager.warehouseDatabase db?.let { database -> val query = database.createQuery("SELECT COUNT(*) AS count FROM _ AS item WHERE documentType=\"$documentType\"") // 1 @@ -72,7 +69,7 @@ class StockItemRepositoryDb( return withContext(Dispatchers.IO) { val stockItems = mutableListOf() try { - val db = databaseResources.warehouseDatabase + val db = databaseManager.warehouseDatabase db?.let { database -> var queryString = "SELECT * FROM _ as item WHERE documentType=\"item\" AND lower(name) LIKE ('%' || \$parameterName || '%')" // 1 diff --git a/src/app/src/main/java/com/couchbase/learningpath/data/userprofile/UserProfileRepository.kt b/src/app/src/main/java/com/couchbase/learningpath/data/userprofile/UserProfileRepository.kt index 02ac842..08628b8 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/data/userprofile/UserProfileRepository.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/data/userprofile/UserProfileRepository.kt @@ -1,6 +1,5 @@ package com.couchbase.learningpath.data.userprofile -import android.content.Context import com.couchbase.lite.CouchbaseLiteException import com.couchbase.lite.MutableDocument @@ -9,15 +8,17 @@ import com.couchbase.learningpath.data.KeyValueRepository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -class UserProfileRepository(var context: Context) : KeyValueRepository { +class UserProfileRepository( + private val databaseManager: DatabaseManager +) : KeyValueRepository { private val userProfileType = "user" override fun inventoryDatabaseName(): String { - return DatabaseManager.getInstance(context).currentInventoryDatabaseName + return databaseManager.currentInventoryDatabaseName } override fun inventoryDatabaseLocation(): String? { - return DatabaseManager.getInstance(context).inventoryDatabase?.path + return databaseManager.inventoryDatabase?.path } override suspend fun get(currentUser: String): Map { @@ -25,7 +26,7 @@ class UserProfileRepository(var context: Context) : KeyValueRepository { val results = HashMap() // <1> results["email"] = currentUser as Any // <2> - val database = DatabaseManager.getInstance(context).inventoryDatabase + val database = databaseManager.inventoryDatabase database?.let { db -> val documentId = getCurrentUserDocumentId(currentUser) val doc = db.getDocument(documentId) // <3> @@ -57,7 +58,7 @@ class UserProfileRepository(var context: Context) : KeyValueRepository { val documentId = getCurrentUserDocumentId(email) val mutableDocument = MutableDocument(documentId, data) try { - val database = DatabaseManager.getInstance(context).inventoryDatabase + val database = databaseManager.inventoryDatabase database?.save(mutableDocument) } catch (e: CouchbaseLiteException) { android.util.Log.e(e.message, e.stackTraceToString()) @@ -69,7 +70,7 @@ class UserProfileRepository(var context: Context) : KeyValueRepository { override suspend fun count(): Int { return withContext(Dispatchers.IO) { - val database = DatabaseManager.getInstance(context).inventoryDatabase + val database = databaseManager.inventoryDatabase database?.let { db -> val query = "SELECT COUNT(*) AS count FROM _ WHERE documentType='$userProfileType'" val results = db.createQuery(query).execute().allResults() @@ -82,7 +83,7 @@ class UserProfileRepository(var context: Context) : KeyValueRepository { suspend fun delete(documentId: String): Boolean { return withContext(Dispatchers.IO) { var result = false - val database = DatabaseManager.getInstance(context).inventoryDatabase + val database = databaseManager.inventoryDatabase database?.let { db -> val document = db.getDocument(documentId) document?.let { diff --git a/src/app/src/main/java/com/couchbase/learningpath/data/warehouse/WarehouseRepositoryDb.kt b/src/app/src/main/java/com/couchbase/learningpath/data/warehouse/WarehouseRepositoryDb.kt index 84b340f..aa3cc06 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/data/warehouse/WarehouseRepositoryDb.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/data/warehouse/WarehouseRepositoryDb.kt @@ -1,6 +1,5 @@ package com.couchbase.learningpath.data.warehouse -import android.content.Context import android.util.Log import com.couchbase.lite.* import com.couchbase.lite.Function @@ -14,8 +13,9 @@ import com.couchbase.learningpath.data.DatabaseManager import com.couchbase.learningpath.models.Warehouse import com.couchbase.learningpath.models.WarehouseDao -class WarehouseRepositoryDb(context: Context) : WarehouseRepository { - private val databaseResources: DatabaseManager = DatabaseManager.getInstance(context) +class WarehouseRepositoryDb( + private val databaseManager: DatabaseManager +) : WarehouseRepository { private val documentType = "warehouse" private val cityAttributeName = "city" @@ -27,7 +27,7 @@ class WarehouseRepositoryDb(context: Context) : WarehouseRepository { return withContext(Dispatchers.IO){ val warehouses = mutableListOf() try { - val db = databaseResources.warehouseDatabase + val db = databaseManager.warehouseDatabase db?.let { database -> //search by city var whereQueryExpression = Function @@ -75,7 +75,7 @@ class WarehouseRepositoryDb(context: Context) : WarehouseRepository { return withContext(Dispatchers.IO) { val locations = mutableListOf() try { - val db = databaseResources.warehouseDatabase + val db = databaseManager.warehouseDatabase db?.let { val query = QueryBuilder .select(SelectResult.all()) @@ -99,7 +99,7 @@ class WarehouseRepositoryDb(context: Context) : WarehouseRepository { var resultCount = 0 val countAliasName = "count" try { - val db = databaseResources.warehouseDatabase + val db = databaseManager.warehouseDatabase db?.let { val query = QueryBuilder // <1> .select(SelectResult.expression(Function.count(Expression.string("*"))).`as`(countAliasName)) // <2> @@ -115,7 +115,7 @@ class WarehouseRepositoryDb(context: Context) : WarehouseRepository { } } - override val warehouseDatabaseName: () -> String? = { DatabaseManager.getInstance(context).warehouseDatabase?.name } + override val warehouseDatabaseName: () -> String? = { databaseManager.warehouseDatabase?.name } - override val warehouseDatabaseLocation: () -> String? = { DatabaseManager.getInstance(context).warehouseDatabase?.path } + override val warehouseDatabaseLocation: () -> String? = { databaseManager.warehouseDatabase?.path } } \ No newline at end of file diff --git a/src/app/src/main/java/com/couchbase/learningpath/services/ReplicatorServiceDb.kt b/src/app/src/main/java/com/couchbase/learningpath/services/ReplicatorServiceDb.kt index c7d9b49..0deaecc 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/services/ReplicatorServiceDb.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/services/ReplicatorServiceDb.kt @@ -1,6 +1,5 @@ package com.couchbase.learningpath.services -import android.content.Context import android.util.Log import androidx.compose.runtime.mutableStateOf import com.couchbase.learningpath.data.DatabaseManager @@ -16,9 +15,8 @@ import java.net.URI @OptIn( ExperimentalCoroutinesApi::class) class ReplicatorServiceDb ( private val authenticationService: AuthenticationService, - val context: Context) : ReplicatorService -{ - private val databaseManager = DatabaseManager.getInstance(context) + private val databaseManager: DatabaseManager +) : ReplicatorService { private var replicatorManager : ReplicatorManager? = null private var loggedInUser = authenticationService.getCurrentUser() diff --git a/src/app/src/main/java/com/couchbase/learningpath/ui/MainActivity.kt b/src/app/src/main/java/com/couchbase/learningpath/ui/MainActivity.kt index 791efb0..7007ee0 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/ui/MainActivity.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/ui/MainActivity.kt @@ -67,9 +67,10 @@ class MainActivity : ComponentActivity() { scope.launch { if (profileViewModel == null) { profileViewModel = UserProfileViewModel( + application = application, repository = userProfileRepository, authService = authService, - mainViewModel.context) + ) } else { profileViewModel?.updateUserProfileInfo() } diff --git a/src/app/src/main/java/com/couchbase/learningpath/ui/MainViewModel.kt b/src/app/src/main/java/com/couchbase/learningpath/ui/MainViewModel.kt index f500337..e6a978c 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/ui/MainViewModel.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/ui/MainViewModel.kt @@ -1,11 +1,9 @@ package com.couchbase.learningpath.ui -import android.content.Context import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import java.lang.ref.WeakReference import com.couchbase.learningpath.services.AuthenticationService import com.couchbase.learningpath.data.DatabaseManager @@ -14,24 +12,19 @@ import com.couchbase.learningpath.services.ReplicatorService class MainViewModel( private val authService: AuthenticationService, private val replicatorService: ReplicatorService, - val context: WeakReference, - + private val databaseManager: DatabaseManager ) : ViewModel() { val startDatabase: () -> Unit = { viewModelScope.launch(Dispatchers.IO) { - context.get()?.let { - DatabaseManager.getInstance(it).initializeDatabases(authService.getCurrentUser()) - } + databaseManager.initializeDatabases(authService.getCurrentUser()) } } val closeDatabase: () -> Unit = { viewModelScope.launch(Dispatchers.IO) { - context.get()?.let { - replicatorService.stopReplication() - DatabaseManager.getInstance(it).closeDatabases() - } + replicatorService.stopReplication() + databaseManager.closeDatabases() } } } \ No newline at end of file diff --git a/src/app/src/main/java/com/couchbase/learningpath/ui/login/LoginViewModel.kt b/src/app/src/main/java/com/couchbase/learningpath/ui/login/LoginViewModel.kt index b8b0ab4..bc9c685 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/ui/login/LoginViewModel.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/ui/login/LoginViewModel.kt @@ -1,13 +1,11 @@ package com.couchbase.learningpath.ui.login -import android.content.Context import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import java.lang.ref.WeakReference import com.couchbase.learningpath.data.DatabaseManager import com.couchbase.learningpath.services.AuthenticationService @@ -16,7 +14,7 @@ import com.couchbase.learningpath.services.ReplicatorService class LoginViewModel( private val authenticationService: AuthenticationService, private val replicatorService: ReplicatorService, - private val context: WeakReference + private val databaseManager: DatabaseManager ) : ViewModel() { private val _username = MutableLiveData("") @@ -37,19 +35,17 @@ class LoginViewModel( val isError: LiveData = _isError fun login(): Boolean { - context.get()?.let { itContext -> - _username.value?.let { uname -> - _password.value?.let { pwd -> - if (authenticationService.authenticatedUser(username = uname, password = pwd)) { - _isError.value = false - val currentUser = authenticationService.getCurrentUser() - viewModelScope.launch(Dispatchers.IO) { - //initialize database if needed - DatabaseManager.getInstance(itContext).initializeDatabases(currentUser) - replicatorService.updateAuthentication(isReset = false) - } - return true + _username.value?.let { uname -> + _password.value?.let { pwd -> + if (authenticationService.authenticatedUser(username = uname, password = pwd)) { + _isError.value = false + val currentUser = authenticationService.getCurrentUser() + viewModelScope.launch(Dispatchers.IO) { + //initialize database if needed + databaseManager.initializeDatabases(currentUser) + replicatorService.updateAuthentication(isReset = false) } + return true } } } diff --git a/src/app/src/main/java/com/couchbase/learningpath/ui/profile/UserProfileViewModel.kt b/src/app/src/main/java/com/couchbase/learningpath/ui/profile/UserProfileViewModel.kt index 53ade92..ab3b83b 100644 --- a/src/app/src/main/java/com/couchbase/learningpath/ui/profile/UserProfileViewModel.kt +++ b/src/app/src/main/java/com/couchbase/learningpath/ui/profile/UserProfileViewModel.kt @@ -1,19 +1,18 @@ package com.couchbase.learningpath.ui.profile -import android.content.Context +import android.app.Application import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.drawable.Drawable import androidx.compose.runtime.mutableStateOf import androidx.core.graphics.drawable.toBitmap -import androidx.lifecycle.ViewModel +import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import com.couchbase.lite.Blob import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.ByteArrayOutputStream -import java.lang.ref.WeakReference import com.couchbase.learningpath.data.KeyValueRepository import com.couchbase.learningpath.services.AuthenticationService @@ -21,10 +20,10 @@ import com.couchbase.learningpath.R import com.couchbase.learningpath.models.User class UserProfileViewModel( + application: Application, private val repository: KeyValueRepository, - authService: AuthenticationService, - context: WeakReference -) : ViewModel() { + authService: AuthenticationService +) : AndroidViewModel(application) { private var currentUser: User? = null @@ -40,7 +39,7 @@ class UserProfileViewModel( init { currentUser = authService.getCurrentUser() updateUserProfileInfo() - profilePic.value = BitmapFactory.decodeResource(context.get()?.resources, R.drawable.profile_placeholder) + profilePic.value = BitmapFactory.decodeResource(getApplication().resources, R.drawable.profile_placeholder) } fun updateUserProfileInfo() { diff --git a/src/app/src/main/java/com/couchbase/learningpath/util/Singleton.kt b/src/app/src/main/java/com/couchbase/learningpath/util/Singleton.kt deleted file mode 100644 index 5c6ed3e..0000000 --- a/src/app/src/main/java/com/couchbase/learningpath/util/Singleton.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.couchbase.learningpath.util - -//kotlin doesn't support singleton out of the box, so this is a quick -//class that simulates ideas of the singleton pattern -open class Singleton(creator: (A) -> T) { - private var creator: ((A) -> T)? = creator - @Volatile private var instance: T? = null - - fun getInstance(arg: A): T { - val checkInstance = instance - if (checkInstance != null) { - return checkInstance - } - - //need to make sure this works across threads - return synchronized(this) { - val checkInstanceAgain = instance - if (checkInstanceAgain != null) { - checkInstanceAgain - } else { - val created = creator!!(arg) - instance = created - creator = null - created - } - } - } -} \ No newline at end of file