This repository has been archived by the owner on Nov 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 707
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Disclaimer screen + bugfixes (#3098)
* WIP: Disclaimer screen * Build UI components * WIP: Disclaimer screen * Implement the Disclaimer screen * Fix crash * Finish the Disclaimer screen * Make `stale` keep bugs * WIP: Fix memoization * Fix memoization issues * Bugfixes: memoization + Categories screen * Optimize memoization * Fix tags memoization * Get rid of legacy `EventBus` * Bump version to "4.6.2" (162) * Add "Report a bug" btn in Settings
- Loading branch information
1 parent
4d55e4d
commit b63f146
Showing
65 changed files
with
972 additions
and
423 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
plugins { | ||
id("ivy.feature") | ||
} | ||
|
||
android { | ||
namespace = "com.ivy.disclaimer" | ||
} | ||
|
||
dependencies { | ||
implementation(projects.shared.data.core) | ||
implementation(projects.shared.ui.core) | ||
implementation(projects.shared.ui.navigation) | ||
|
||
testImplementation(projects.shared.ui.testing) | ||
} |
83 changes: 83 additions & 0 deletions
83
screen/disclaimer/src/main/java/com/ivy/disclaimer/DisclaimerScreen.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package com.ivy.disclaimer | ||
|
||
import androidx.compose.foundation.layout.Spacer | ||
import androidx.compose.foundation.layout.height | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.lazy.LazyColumn | ||
import androidx.compose.foundation.lazy.itemsIndexed | ||
import androidx.compose.material3.Scaffold | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.unit.dp | ||
import com.ivy.disclaimer.composables.AcceptTermsText | ||
import com.ivy.disclaimer.composables.AgreeButton | ||
import com.ivy.disclaimer.composables.AgreementCheckBox | ||
import com.ivy.disclaimer.composables.DisclaimerTopAppBar | ||
import com.ivy.navigation.screenScopedViewModel | ||
import com.ivy.ui.component.OpenSourceCard | ||
|
||
@Composable | ||
fun DisclaimerScreenImpl() { | ||
val viewModel: DisclaimerViewModel = screenScopedViewModel() | ||
val viewState = viewModel.uiState() | ||
DisclaimerScreenUi(viewState = viewState, onEvent = viewModel::onEvent) | ||
} | ||
|
||
@Composable | ||
fun DisclaimerScreenUi( | ||
viewState: DisclaimerViewState, | ||
onEvent: (DisclaimerViewEvent) -> Unit, | ||
modifier: Modifier = Modifier, | ||
) { | ||
Scaffold( | ||
modifier = modifier, | ||
topBar = { | ||
DisclaimerTopAppBar() | ||
}, | ||
content = { innerPadding -> | ||
Content( | ||
modifier = Modifier.padding(innerPadding), | ||
viewState = viewState, | ||
onEvent = onEvent, | ||
) | ||
} | ||
) | ||
} | ||
|
||
@Composable | ||
private fun Content( | ||
viewState: DisclaimerViewState, | ||
onEvent: (DisclaimerViewEvent) -> Unit, | ||
modifier: Modifier = Modifier | ||
) { | ||
LazyColumn( | ||
modifier = modifier.padding(horizontal = 16.dp) | ||
) { | ||
item { | ||
OpenSourceCard() | ||
} | ||
item { | ||
Spacer(modifier = Modifier.height(12.dp)) | ||
AcceptTermsText() | ||
} | ||
itemsIndexed(items = viewState.checkboxes) { index, item -> | ||
Spacer(modifier = Modifier.height(8.dp)) | ||
AgreementCheckBox( | ||
viewState = item, | ||
onClick = { | ||
onEvent(DisclaimerViewEvent.OnCheckboxClick(index)) | ||
} | ||
) | ||
} | ||
item { | ||
Spacer(modifier = Modifier.height(12.dp)) | ||
AgreeButton( | ||
enabled = viewState.agreeButtonEnabled, | ||
) { onEvent(DisclaimerViewEvent.OnAgreeClick) } | ||
} | ||
item { | ||
// To ensure proper scrolling | ||
Spacer(modifier = Modifier.height(48.dp)) | ||
} | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
screen/disclaimer/src/main/java/com/ivy/disclaimer/DisclaimerViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.ivy.disclaimer | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.mutableStateOf | ||
import androidx.compose.runtime.setValue | ||
import androidx.lifecycle.viewModelScope | ||
import com.ivy.data.repository.LegalRepository | ||
import com.ivy.navigation.Navigation | ||
import com.ivy.ui.ComposeViewModel | ||
import dagger.hilt.android.lifecycle.HiltViewModel | ||
import kotlinx.collections.immutable.toImmutableList | ||
import kotlinx.coroutines.launch | ||
import javax.inject.Inject | ||
|
||
@HiltViewModel | ||
class DisclaimerViewModel @Inject constructor( | ||
private val navigation: Navigation, | ||
private val legalRepo: LegalRepository, | ||
) : ComposeViewModel<DisclaimerViewState, DisclaimerViewEvent>() { | ||
|
||
private var checkboxes by mutableStateOf(LegalCheckboxes) | ||
|
||
@Composable | ||
override fun uiState(): DisclaimerViewState { | ||
return DisclaimerViewState( | ||
checkboxes = checkboxes, | ||
agreeButtonEnabled = checkboxes.all(CheckboxViewState::checked), | ||
) | ||
} | ||
|
||
override fun onEvent(event: DisclaimerViewEvent) { | ||
when (event) { | ||
DisclaimerViewEvent.OnAgreeClick -> handleAgreeClick() | ||
is DisclaimerViewEvent.OnCheckboxClick -> handleCheckboxClick(event) | ||
} | ||
} | ||
|
||
private fun handleAgreeClick() { | ||
viewModelScope.launch { | ||
legalRepo.setDisclaimerAccepted(accepted = true) | ||
navigation.back() | ||
} | ||
} | ||
|
||
private fun handleCheckboxClick(event: DisclaimerViewEvent.OnCheckboxClick) { | ||
checkboxes = checkboxes.mapIndexed { index, item -> | ||
if (index == event.index) { | ||
item.copy( | ||
checked = !item.checked | ||
) | ||
} else { | ||
item | ||
} | ||
}.toImmutableList() | ||
} | ||
|
||
companion object { | ||
// LEGAL text - do NOT extract or translate | ||
val LegalCheckboxes = listOf( | ||
CheckboxViewState( | ||
text = "I recognize this app is open-source and provided 'as-is' " + | ||
"with no warranties, explicit or implied. " + | ||
"I fully accept all risks of errors, defects, or failures, " + | ||
"using the app solely at my own risk.", | ||
checked = false, | ||
), | ||
CheckboxViewState( | ||
text = "I understand there is no warranty for the accuracy, " + | ||
"reliability, or completeness of my data. " + | ||
"Manual data backup is my responsibility, and I agree to not hold " + | ||
"the app liable for any data loss.", | ||
checked = false, | ||
), | ||
CheckboxViewState( | ||
text = "I hereby release the app developers, contributors, " + | ||
"and distributing company from any liability for " + | ||
"claims, damages, legal fees, or losses, including those resulting " + | ||
"from security breaches or data inaccuracies.", | ||
checked = false, | ||
), | ||
CheckboxViewState( | ||
text = "I am aware and accept that the app may display misleading information " + | ||
"or contain inaccuracies. " + | ||
"I assume full responsibility for verifying the integrity " + | ||
"of financial data and calculations before making " + | ||
"any decisions based on app data.", | ||
checked = false, | ||
), | ||
).toImmutableList() | ||
} | ||
} |
Oops, something went wrong.