-
Notifications
You must be signed in to change notification settings - Fork 169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
db refactor #973
db refactor #973
Changes from 5 commits
9299528
52b5cf9
71fda4f
2268b6f
4127be2
8db1842
5c0b689
d0c7f3c
2ad2dbc
bf13d05
076491d
7bac450
010eefd
5f3ab5a
d5d7c6b
5970f59
df94188
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,8 @@ import androidx.compose.runtime.livedata.observeAsState | |
import androidx.compose.runtime.mutableStateOf | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.ui.platform.LocalContext | ||
import androidx.lifecycle.ViewModelProvider | ||
import androidx.lifecycle.viewmodel.CreationExtras | ||
import androidx.lifecycle.viewmodel.compose.viewModel | ||
import androidx.navigation.compose.NavHost | ||
import androidx.navigation.compose.composable | ||
|
@@ -32,11 +34,9 @@ import com.jerboa.api.API | |
import com.jerboa.api.ApiState | ||
import com.jerboa.api.MINIMUM_API_VERSION | ||
import com.jerboa.db.APP_SETTINGS_DEFAULT | ||
import com.jerboa.db.AccountRepository | ||
import com.jerboa.db.AccountViewModel | ||
import com.jerboa.db.AccountViewModelFactory | ||
import com.jerboa.db.AppDB | ||
import com.jerboa.db.AppSettingsRepository | ||
import com.jerboa.db.AppDBContainer | ||
import com.jerboa.db.AppSettingsViewModel | ||
import com.jerboa.db.AppSettingsViewModelFactory | ||
import com.jerboa.ui.components.comment.edit.CommentEditActivity | ||
|
@@ -50,7 +50,7 @@ import com.jerboa.ui.components.common.Route | |
import com.jerboa.ui.components.common.ShowChangelog | ||
import com.jerboa.ui.components.common.ShowOutdatedServerDialog | ||
import com.jerboa.ui.components.common.SwipeToNavigateBack | ||
import com.jerboa.ui.components.common.getCurrentAccountSync | ||
import com.jerboa.ui.components.common.getCurrentAccount | ||
import com.jerboa.ui.components.common.takeDepsFromRoot | ||
import com.jerboa.ui.components.community.CommunityActivity | ||
import com.jerboa.ui.components.community.CommunityViewModel | ||
|
@@ -71,35 +71,28 @@ import com.jerboa.ui.components.report.post.CreatePostReportActivity | |
import com.jerboa.ui.components.settings.SettingsActivity | ||
import com.jerboa.ui.components.settings.about.AboutActivity | ||
import com.jerboa.ui.components.settings.account.AccountSettingsActivity | ||
import com.jerboa.ui.components.settings.account.AccountSettingsViewModel | ||
import com.jerboa.ui.components.settings.account.AccountSettingsViewModelFactory | ||
import com.jerboa.ui.components.settings.lookandfeel.LookAndFeelActivity | ||
import com.jerboa.ui.theme.JerboaTheme | ||
|
||
class JerboaApplication : Application() { | ||
private val database by lazy { AppDB.getDatabase(this) } | ||
val accountRepository by lazy { AccountRepository(database.accountDao()) } | ||
val appSettingsRepository by lazy { AppSettingsRepository(database.appSettingsDao()) } | ||
lateinit var container: AppDBContainer | ||
|
||
override fun onCreate() { | ||
super.onCreate() | ||
container = AppDBContainer(this) | ||
} | ||
} | ||
|
||
fun CreationExtras.jerboaApplication(): JerboaApplication = | ||
(this[ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY] as JerboaApplication) | ||
|
||
class MainActivity : AppCompatActivity() { | ||
private val siteViewModel by viewModels<SiteViewModel>() | ||
private val accountSettingsViewModel by viewModels<AccountSettingsViewModel> { | ||
AccountSettingsViewModelFactory((application as JerboaApplication).accountRepository) | ||
} | ||
private val accountViewModel: AccountViewModel by viewModels { | ||
AccountViewModelFactory((application as JerboaApplication).accountRepository) | ||
} | ||
private val appSettingsViewModel: AppSettingsViewModel by viewModels { | ||
AppSettingsViewModelFactory((application as JerboaApplication).appSettingsRepository) | ||
} | ||
|
||
@OptIn(ExperimentalAnimationApi::class) | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
|
||
val accountSync = getCurrentAccountSync(accountViewModel) | ||
|
||
setContent { | ||
val ctx = LocalContext.current | ||
|
||
|
@@ -115,10 +108,17 @@ class MainActivity : AppCompatActivity() { | |
null | ||
} | ||
|
||
LaunchedEffect(Unit) { | ||
fetchInitialData(accountSync, siteViewModel) | ||
val accountViewModel: AccountViewModel = viewModel(factory = AccountViewModelFactory.Factory) | ||
|
||
val account = getCurrentAccount(accountViewModel) | ||
|
||
LaunchedEffect(account) { | ||
if (account == null || account.id != -1) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was an occasional race condition type issue where As a solution to this, I set an initial state value in Let me know if there's a better way to handle something like this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems fine to me. |
||
fetchInitialData(account, siteViewModel) | ||
} | ||
} | ||
|
||
val appSettingsViewModel: AppSettingsViewModel = viewModel(factory = AppSettingsViewModelFactory.Factory) | ||
val appSettings by appSettingsViewModel.appSettings.observeAsState(APP_SETTINGS_DEFAULT) | ||
|
||
JerboaTheme( | ||
|
@@ -133,7 +133,7 @@ class MainActivity : AppCompatActivity() { | |
appSettings.usePrivateTabs, | ||
) | ||
|
||
ShowChangelog(appSettingsViewModel = appSettingsViewModel) | ||
ShowChangelog() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stuff like this scares me, it seems like it has no actual dependencies now, when in reality the appSettings does need to be injected. |
||
|
||
when (val siteRes = siteViewModel.siteRes) { | ||
is ApiState.Success -> { | ||
|
@@ -165,17 +165,14 @@ class MainActivity : AppCompatActivity() { | |
) { | ||
LoginActivity( | ||
navController = navController, | ||
accountViewModel = accountViewModel, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I saw in the workshop, the viewModel parameters weren't passed in directly, they used the factory in the composable instead, like https://github.com/dessalines/jerboa/pull/973/files#diff-6ca2c69ae054a88358d16c98f47efd02bb16eae48a09295b4db9bd5e99ba8e76R25. |
||
siteViewModel = siteViewModel, | ||
) | ||
} | ||
|
||
composable(route = Route.HOME) { | ||
BottomNavActivity( | ||
navController = navController, | ||
accountViewModel = accountViewModel, | ||
siteViewModel = siteViewModel, | ||
appSettingsViewModel = appSettingsViewModel, | ||
appSettings = appSettings, | ||
) | ||
} | ||
|
@@ -201,8 +198,6 @@ class MainActivity : AppCompatActivity() { | |
communityArg = Either.Left(args.id), | ||
navController = navController, | ||
communityViewModel = communityViewModel, | ||
accountViewModel = accountViewModel, | ||
appSettingsViewModel = appSettingsViewModel, | ||
showVotingArrowsInListView = appSettings.showVotingArrowsInListView, | ||
siteViewModel = siteViewModel, | ||
useCustomTabs = appSettings.useCustomTabs, | ||
|
@@ -233,8 +228,6 @@ class MainActivity : AppCompatActivity() { | |
communityArg = Either.Right(qualifiedName), | ||
navController = navController, | ||
communityViewModel = communityViewModel, | ||
accountViewModel = accountViewModel, | ||
appSettingsViewModel = appSettingsViewModel, | ||
showVotingArrowsInListView = appSettings.showVotingArrowsInListView, | ||
siteViewModel = siteViewModel, | ||
useCustomTabs = appSettings.useCustomTabs, | ||
|
@@ -299,8 +292,6 @@ class MainActivity : AppCompatActivity() { | |
personArg = Either.Left(args.id), | ||
savedMode = args.saved, | ||
navController = navController, | ||
accountViewModel = accountViewModel, | ||
appSettingsViewModel = appSettingsViewModel, | ||
showVotingArrowsInListView = appSettings.showVotingArrowsInListView, | ||
siteViewModel = siteViewModel, | ||
useCustomTabs = appSettings.useCustomTabs, | ||
|
@@ -330,8 +321,6 @@ class MainActivity : AppCompatActivity() { | |
personArg = Either.Right(qualifiedName), | ||
savedMode = false, | ||
navController = navController, | ||
accountViewModel = accountViewModel, | ||
appSettingsViewModel = appSettingsViewModel, | ||
showVotingArrowsInListView = appSettings.showVotingArrowsInListView, | ||
siteViewModel = siteViewModel, | ||
useCustomTabs = appSettings.useCustomTabs, | ||
|
@@ -352,7 +341,6 @@ class MainActivity : AppCompatActivity() { | |
val args = Route.CommunityListArgs(it) | ||
CommunityListActivity( | ||
navController = navController, | ||
accountViewModel = accountViewModel, | ||
siteViewModel = siteViewModel, | ||
selectMode = args.select, | ||
blurNSFW = appSettings.blurNSFW, | ||
|
@@ -389,7 +377,6 @@ class MainActivity : AppCompatActivity() { | |
|
||
CreatePostActivity( | ||
navController = navController, | ||
accountViewModel = accountViewModel, | ||
initialUrl = url, | ||
initialBody = body, | ||
initialImage = image, | ||
|
@@ -405,7 +392,6 @@ class MainActivity : AppCompatActivity() { | |
) { | ||
InboxActivity( | ||
navController = navController, | ||
accountViewModel = accountViewModel, | ||
siteViewModel = siteViewModel, | ||
blurNSFW = appSettings.blurNSFW, | ||
) | ||
|
@@ -426,7 +412,6 @@ class MainActivity : AppCompatActivity() { | |
SwipeToNavigateBack(navController = navController) { | ||
PostActivity( | ||
id = Either.Left(args.id), | ||
accountViewModel = accountViewModel, | ||
navController = navController, | ||
showCollapsedCommentContent = appSettings.showCollapsedCommentContent, | ||
showActionBarByDefault = appSettings.showCommentActionBarByDefault, | ||
|
@@ -455,7 +440,6 @@ class MainActivity : AppCompatActivity() { | |
val args = Route.CommentArgs(it) | ||
PostActivity( | ||
id = Either.Right(args.id), | ||
accountViewModel = accountViewModel, | ||
navController = navController, | ||
useCustomTabs = appSettings.useCustomTabs, | ||
usePrivateTabs = appSettings.usePrivateTabs, | ||
|
@@ -482,7 +466,6 @@ class MainActivity : AppCompatActivity() { | |
|
||
CommentReplyActivity( | ||
replyItem = replyItem, | ||
accountViewModel = accountViewModel, | ||
navController = navController, | ||
siteViewModel = siteViewModel, | ||
isModerator = args.isModerator, | ||
|
@@ -500,7 +483,6 @@ class MainActivity : AppCompatActivity() { | |
val commentView by navController.takeDepsFromRoot<CommentEditDeps>() | ||
CommentEditActivity( | ||
commentView = commentView, | ||
accountViewModel = accountViewModel, | ||
navController = navController, | ||
) | ||
} | ||
|
@@ -509,7 +491,6 @@ class MainActivity : AppCompatActivity() { | |
val postView by navController.takeDepsFromRoot<PostEditDeps>() | ||
PostEditActivity( | ||
postView = postView, | ||
accountViewModel = accountViewModel, | ||
navController = navController, | ||
) | ||
} | ||
|
@@ -518,7 +499,6 @@ class MainActivity : AppCompatActivity() { | |
val privateMessage by navController.takeDepsFromRoot<PrivateMessageDeps>() | ||
PrivateMessageReplyActivity( | ||
privateMessageView = privateMessage, | ||
accountViewModel = accountViewModel, | ||
navController = navController, | ||
siteViewModel = siteViewModel, | ||
) | ||
|
@@ -535,7 +515,6 @@ class MainActivity : AppCompatActivity() { | |
val args = Route.CommentReportArgs(it) | ||
CreateCommentReportActivity( | ||
commentId = args.id, | ||
accountViewModel = accountViewModel, | ||
navController = navController, | ||
) | ||
} | ||
|
@@ -551,22 +530,19 @@ class MainActivity : AppCompatActivity() { | |
val args = Route.PostReportArgs(it) | ||
CreatePostReportActivity( | ||
postId = args.id, | ||
accountViewModel = accountViewModel, | ||
navController = navController, | ||
) | ||
} | ||
|
||
composable(route = Route.SETTINGS) { | ||
SettingsActivity( | ||
navController = navController, | ||
accountViewModel = accountViewModel, | ||
) | ||
} | ||
|
||
composable(route = Route.LOOK_AND_FEEL) { | ||
LookAndFeelActivity( | ||
navController = navController, | ||
appSettingsViewModel = appSettingsViewModel, | ||
) | ||
} | ||
|
||
|
@@ -578,9 +554,7 @@ class MainActivity : AppCompatActivity() { | |
) { | ||
AccountSettingsActivity( | ||
navController = navController, | ||
accountViewModel = accountViewModel, | ||
siteViewModel = siteViewModel, | ||
accountSettingsViewModel = accountSettingsViewModel, | ||
) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.jerboa.db | ||
|
||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import androidx.lifecycle.viewmodel.initializer | ||
import androidx.lifecycle.viewmodel.viewModelFactory | ||
import com.jerboa.db.entity.Account | ||
import com.jerboa.db.repository.AccountRepository | ||
import com.jerboa.jerboaApplication | ||
import kotlinx.coroutines.launch | ||
|
||
class AccountViewModel(private val repository: AccountRepository) : ViewModel() { | ||
|
||
val currentAccount = repository.currentAccount | ||
val allAccounts = repository.allAccounts | ||
|
||
fun insert(account: Account) = viewModelScope.launch { | ||
repository.insert(account) | ||
} | ||
|
||
fun removeCurrent() = viewModelScope.launch { | ||
repository.removeCurrent() | ||
} | ||
|
||
fun setCurrent(accountId: Int) = viewModelScope.launch { | ||
repository.setCurrent(accountId) | ||
} | ||
|
||
fun delete(account: Account) = viewModelScope.launch { | ||
repository.delete(account) | ||
} | ||
} | ||
|
||
object AccountViewModelFactory { | ||
val Factory = viewModelFactory { | ||
initializer { | ||
AccountViewModel(jerboaApplication().container.accountRepository) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is referenced in view model factories here https://github.com/dessalines/jerboa/pull/973/files#diff-41754fa505a06441b96271ba020ae2e014472578466e14a44fd7ce01a6c578f4R37, based on the compose room workshop again https://github.com/google-developer-training/basic-android-kotlin-compose-training-inventory-app/blob/room/app/src/main/java/com/example/inventory/ui/AppViewModelProvider.kt#L65