-
Notifications
You must be signed in to change notification settings - Fork 9
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
CU-862k43hfa - Add circuit and decouple viewmodel from view #127
Changes from all commits
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 |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package io.newm.feature.login.screen.createaccount | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.remember | ||
import com.slack.circuit.retained.rememberRetained | ||
import com.slack.circuit.runtime.Navigator | ||
import com.slack.circuit.runtime.presenter.Presenter | ||
import io.newm.feature.login.screen.TextFieldState | ||
import io.newm.feature.login.screen.createaccount.signupform.SignupFormUiEvent | ||
import io.newm.feature.login.screen.password.ConfirmPasswordState | ||
import io.newm.feature.login.screen.password.PasswordState | ||
|
||
class CreateAccountPresenter : Presenter<CreateAccountUiState> { | ||
@Composable | ||
override fun present(): CreateAccountUiState { | ||
val userEmail = rememberRetained { TextFieldState() } | ||
val password = rememberRetained { PasswordState() } | ||
val passwordConfirmation = rememberRetained { ConfirmPasswordState(password) } | ||
|
||
return CreateAccountUiState.SignupForm( | ||
emailState = userEmail, | ||
passwordState = password, | ||
passwordConfirmationState = passwordConfirmation, | ||
) { event -> | ||
when (event) { | ||
SignupFormUiEvent.Next -> TODO() | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,99 +1,7 @@ | ||
package io.newm.feature.login.screen.createaccount | ||
|
||
import androidx.compose.foundation.layout.* | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.LaunchedEffect | ||
import androidx.compose.runtime.collectAsState | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.focus.FocusRequester | ||
import androidx.compose.ui.focus.focusRequester | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.unit.dp | ||
import io.newm.feature.login.screen.email.Email | ||
import io.newm.feature.login.screen.email.EmailState | ||
import io.newm.feature.login.screen.password.Password | ||
import io.newm.feature.login.screen.password.PasswordState | ||
import io.newm.core.resources.R | ||
import io.newm.core.ui.buttons.SecondaryButton | ||
import io.newm.feature.login.screen.PreLoginArtistBackgroundContentTemplate | ||
import com.slack.circuit.runtime.Screen | ||
import kotlinx.parcelize.Parcelize | ||
|
||
@Composable | ||
fun CreateAccountScreen( | ||
onUserLoggedIn: () -> Unit, | ||
onNext: () -> Unit, | ||
viewModel: CreateAccountViewModel | ||
) { | ||
val userState by viewModel.state.collectAsState() | ||
|
||
CreateAccountScreen( | ||
onUserLoggedIn = onUserLoggedIn, | ||
onNext = onNext, | ||
userState = userState, | ||
setUserEmail = viewModel::setUserEmail, | ||
setUserPassword = viewModel::setUserPassword, | ||
setUserPasswordConfirmation = viewModel::setUserPasswordConfirmation, | ||
requestCode = viewModel::requestCode, | ||
) | ||
} | ||
|
||
@Composable | ||
internal fun CreateAccountScreen( | ||
onUserLoggedIn: () -> Unit, | ||
onNext: () -> Unit, | ||
userState: CreateAccountViewModel.SignupUserState, | ||
setUserEmail: (String) -> Unit, | ||
setUserPassword: (String) -> Unit, | ||
setUserPasswordConfirmation: (String) -> Unit, | ||
requestCode: () -> Unit, | ||
) { | ||
PreLoginArtistBackgroundContentTemplate { | ||
|
||
LaunchedEffect( | ||
key1 = userState.verificationRequested, | ||
key2 = userState.verificationRequested | ||
) { | ||
if (userState.verificationRequested) { | ||
onNext() | ||
} | ||
if (userState.isUserRegistered) { | ||
onUserLoggedIn() | ||
} | ||
} | ||
|
||
val focusRequester = remember { FocusRequester() } | ||
|
||
val emailState = remember { EmailState() } | ||
Email(emailState = emailState, onImeAction = { focusRequester.requestFocus() }) | ||
|
||
val passwordState1 = remember { PasswordState() } | ||
Password( | ||
label = stringResource(id = R.string.password), | ||
passwordState = passwordState1, | ||
onImeAction = {}, | ||
modifier = Modifier.focusRequester(focusRequester), | ||
) | ||
|
||
val passwordState2 = remember { PasswordState() } | ||
Password( | ||
label = stringResource(id = R.string.password), | ||
passwordState = passwordState2, | ||
onImeAction = {}, | ||
modifier = Modifier.focusRequester(focusRequester), | ||
) | ||
|
||
Spacer(modifier = Modifier.height(16.dp)) | ||
|
||
SecondaryButton(text = "Next") { | ||
if (passwordState1.isValid && passwordState2.isValid | ||
&& passwordState1.text == passwordState2.text || true | ||
) { | ||
setUserEmail("[email protected]") | ||
setUserPassword("Password18") | ||
setUserPasswordConfirmation("Password18") | ||
requestCode() | ||
} | ||
} | ||
} | ||
} | ||
@Parcelize | ||
object CreateAccountScreen : Screen |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package io.newm.feature.login.screen.createaccount | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Modifier | ||
import com.slack.circuit.runtime.ui.Ui | ||
import io.newm.feature.login.screen.createaccount.CreateAccountUiState.SignupForm | ||
import io.newm.feature.login.screen.createaccount.signupform.SignUpFormUi | ||
|
||
class CreateAccountUi : Ui<CreateAccountUiState> { | ||
@Composable | ||
override fun Content(state: CreateAccountUiState, modifier: Modifier) { | ||
when (state) { | ||
is SignupForm -> { | ||
SignUpFormUi(state = state) | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package io.newm.feature.login.screen.createaccount | ||
|
||
import com.slack.circuit.runtime.CircuitUiState | ||
import io.newm.feature.login.screen.TextFieldState | ||
import io.newm.feature.login.screen.createaccount.signupform.SignupFormUiEvent | ||
|
||
sealed interface CreateAccountUiState : CircuitUiState { | ||
data class SignupForm( | ||
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. This looks great, curious with this approach will we be able to reuse states like Loading, Error or will those states have to exist within CreateAccountUiState seal class? 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. We could technically reuse them, but the overhead is not worth it |
||
val passwordConfirmationState: TextFieldState, | ||
val passwordState: TextFieldState, | ||
val emailState: TextFieldState, | ||
val eventSink: (SignupFormUiEvent) -> Unit, | ||
) : CreateAccountUiState | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package io.newm.feature.login.screen.createaccount.signupform | ||
|
||
import androidx.compose.foundation.layout.* | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.focus.FocusRequester | ||
import androidx.compose.ui.focus.focusRequester | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.unit.dp | ||
import io.newm.feature.login.screen.email.Email | ||
import io.newm.feature.login.screen.password.Password | ||
import io.newm.core.resources.R | ||
import io.newm.core.ui.buttons.SecondaryButton | ||
import io.newm.feature.login.screen.PreLoginArtistBackgroundContentTemplate | ||
import io.newm.feature.login.screen.createaccount.CreateAccountUiState.SignupForm | ||
|
||
@Composable | ||
fun SignUpFormUi( | ||
state: SignupForm, | ||
) { | ||
val onEvent = state.eventSink | ||
val focusRequester = remember { FocusRequester() } | ||
|
||
PreLoginArtistBackgroundContentTemplate { | ||
Email( | ||
emailState = state.emailState, | ||
onImeAction = { focusRequester.requestFocus() } | ||
) | ||
|
||
Password( | ||
label = stringResource(id = R.string.password), | ||
passwordState = state.passwordState, | ||
onImeAction = {}, | ||
modifier = Modifier.focusRequester(focusRequester), | ||
) | ||
|
||
Password( | ||
label = stringResource(id = R.string.password), | ||
passwordState = state.passwordConfirmationState, | ||
onImeAction = {}, | ||
modifier = Modifier.focusRequester(focusRequester), | ||
) | ||
|
||
Spacer(modifier = Modifier.height(16.dp)) | ||
|
||
SecondaryButton(text = "Next") { | ||
onEvent(SignupFormUiEvent.Next) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package io.newm.feature.login.screen.createaccount.signupform | ||
|
||
import com.slack.circuit.runtime.CircuitUiEvent | ||
|
||
sealed interface SignupFormUiEvent : CircuitUiEvent { | ||
object Next : SignupFormUiEvent | ||
} |
This file was deleted.
This file was deleted.
This file was deleted.
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.
Never heard about this Circuit library before. They should have used a different name instead of
Presenter
, because of all the old MVP architecture baggage. Or is Circuit really Mvp?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.
It's MVP with unidirectional data flow