Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into feat/offline
Browse files Browse the repository at this point in the history
# Conflicts:
#	course/src/main/java/org/openedx/course/presentation/outline/CourseOutlineViewModel.kt
#	course/src/main/java/org/openedx/course/presentation/videos/CourseVideoViewModel.kt
  • Loading branch information
PavloNetrebchuk committed Jul 9, 2024
2 parents 060b065 + 02a83ed commit 8019d86
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
Expand Down Expand Up @@ -127,9 +128,9 @@ private fun RestorePasswordScreen(
) {
val scaffoldState = rememberScaffoldState()
val scrollState = rememberScrollState()
var email by rememberSaveable {
mutableStateOf("")
}
var email by rememberSaveable { mutableStateOf("") }
var isEmailError by rememberSaveable { mutableStateOf(false) }
val keyboardController = LocalSoftwareKeyboardController.current

Scaffold(
scaffoldState = scaffoldState,
Expand Down Expand Up @@ -269,12 +270,20 @@ private fun RestorePasswordScreen(
description = stringResource(id = authR.string.auth_example_email),
onValueChanged = {
email = it
isEmailError = false
},
imeAction = ImeAction.Done,
keyboardActions = {
it.clearFocus()
onRestoreButtonClick(email)
}
keyboardController?.hide()
if (email.isNotEmpty()) {
it.clearFocus()
onRestoreButtonClick(email)
} else {
isEmailError = email.isEmpty()
}
},
isError = isEmailError,
errorMessages = stringResource(id = authR.string.auth_error_empty_email)
)
Spacer(Modifier.height(50.dp))
if (uiState == RestorePasswordUIState.Loading) {
Expand All @@ -292,7 +301,12 @@ private fun RestorePasswordScreen(
modifier = buttonWidth.testTag("btn_reset_password"),
text = stringResource(id = authR.string.auth_reset_password),
onClick = {
onRestoreButtonClick(email)
keyboardController?.hide()
if (email.isNotEmpty()) {
onRestoreButtonClick(email)
} else {
isEmailError = email.isEmpty()
}
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
Expand Down Expand Up @@ -220,6 +221,9 @@ private fun AuthForm(
) {
var login by rememberSaveable { mutableStateOf("") }
var password by rememberSaveable { mutableStateOf("") }
val keyboardController = LocalSoftwareKeyboardController.current
var isEmailError by rememberSaveable { mutableStateOf(false) }
var isPasswordError by rememberSaveable { mutableStateOf(false) }

Column(horizontalAlignment = Alignment.CenterHorizontally) {
LoginTextField(
Expand All @@ -229,18 +233,30 @@ private fun AuthForm(
description = stringResource(id = R.string.auth_enter_email_username),
onValueChanged = {
login = it
})
isEmailError = false
},
isError = isEmailError,
errorMessages = stringResource(id = R.string.auth_error_empty_username_email)
)

Spacer(modifier = Modifier.height(18.dp))
PasswordTextField(
modifier = Modifier
.fillMaxWidth(),
onValueChanged = {
password = it
isPasswordError = false
},
onPressDone = {
onEvent(AuthEvent.SignIn(login = login, password = password))
}
keyboardController?.hide()
if (password.isNotEmpty()) {
onEvent(AuthEvent.SignIn(login = login, password = password))
} else {
isEmailError = login.isEmpty()
isPasswordError = password.isEmpty()
}
},
isError = isPasswordError,
)

Row(
Expand Down Expand Up @@ -282,7 +298,13 @@ private fun AuthForm(
textColor = MaterialTheme.appColors.primaryButtonText,
backgroundColor = MaterialTheme.appColors.secondaryButtonBackground,
onClick = {
onEvent(AuthEvent.SignIn(login = login, password = password))
keyboardController?.hide()
if (login.isNotEmpty() && password.isNotEmpty()) {
onEvent(AuthEvent.SignIn(login = login, password = password))
} else {
isEmailError = login.isEmpty()
isPasswordError = password.isEmpty()
}
}
)
}
Expand All @@ -294,6 +316,7 @@ private fun AuthForm(
isMicrosoftAuthEnabled = state.isMicrosoftAuthEnabled,
isSignIn = true,
) {
keyboardController?.hide()
onEvent(AuthEvent.SocialSignIn(it))
}
}
Expand All @@ -303,6 +326,7 @@ private fun AuthForm(
@Composable
private fun PasswordTextField(
modifier: Modifier = Modifier,
isError: Boolean,
onValueChanged: (String) -> Unit,
onPressDone: () -> Unit,
) {
Expand Down Expand Up @@ -361,9 +385,21 @@ private fun PasswordTextField(
focusManager.clearFocus()
onPressDone()
},
isError = isError,
textStyle = MaterialTheme.appTypography.bodyMedium,
singleLine = true
singleLine = true,
)
if (isError) {
Text(
modifier = Modifier
.testTag("txt_password_error")
.fillMaxWidth()
.padding(top = 4.dp),
text = stringResource(id = R.string.auth_error_empty_password),
style = MaterialTheme.appTypography.bodySmall,
color = MaterialTheme.appColors.error,
)
}
}

@Preview(uiMode = UI_MODE_NIGHT_NO)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ internal fun SignUpView(
textColor = MaterialTheme.appColors.primaryButtonText,
backgroundColor = MaterialTheme.appColors.secondaryButtonBackground,
onClick = {
keyboardController?.hide()
showErrorMap.clear()
onRegisterClick(AuthType.PASSWORD)
}
Expand All @@ -455,6 +456,7 @@ internal fun SignUpView(
isMicrosoftAuthEnabled = uiState.isMicrosoftAuthEnabled,
isSignIn = false,
) {
keyboardController?.hide()
onRegisterClick(it)
}
}
Expand All @@ -478,7 +480,10 @@ private fun RegistrationScreenPreview() {
SignUpView(
windowSize = WindowSize(WindowType.Compact, WindowType.Compact),
uiState = SignUpUIState(
allFields = listOf(field, field, field.copy(required = false)),
allFields = listOf(field),
requiredFields = listOf(field, field),
optionalFields = listOf(field, field),
agreementFields = listOf(field),
),
uiMessage = null,
onBackClick = {},
Expand Down
32 changes: 24 additions & 8 deletions auth/src/main/java/org/openedx/auth/presentation/ui/AuthUI.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
Expand Down Expand Up @@ -69,14 +70,15 @@ fun RequiredFields(
showErrorMap: MutableMap<String, Boolean?>,
selectableNamesMap: MutableMap<String, String?>,
onFieldUpdated: (String, String) -> Unit,
onSelectClick: (String, RegistrationField, List<RegistrationField.Option>) -> Unit
onSelectClick: (String, RegistrationField, List<RegistrationField.Option>) -> Unit,
) {
fields.forEach { field ->
when (field.type) {
RegistrationFieldType.TEXT,
RegistrationFieldType.EMAIL,
RegistrationFieldType.CONFIRM_EMAIL,
RegistrationFieldType.PASSWORD -> {
RegistrationFieldType.PASSWORD,
-> {
InputRegistrationField(
modifier = Modifier.fillMaxWidth(),
isErrorShown = showErrorMap[field.name] ?: true,
Expand Down Expand Up @@ -232,9 +234,11 @@ fun LoginTextField(
modifier: Modifier = Modifier,
title: String,
description: String,
isError: Boolean = false,
errorMessages: String = "",
onValueChanged: (String) -> Unit,
imeAction: ImeAction = ImeAction.Next,
keyboardActions: (FocusManager) -> Unit = { it.moveFocus(FocusDirection.Down) }
keyboardActions: (FocusManager) -> Unit = { it.moveFocus(FocusDirection.Down) },
) {
var loginTextFieldValue by rememberSaveable(stateSaver = TextFieldValue.Saver) {
mutableStateOf(
Expand Down Expand Up @@ -281,16 +285,28 @@ fun LoginTextField(
},
textStyle = MaterialTheme.appTypography.bodyMedium,
singleLine = true,
modifier = modifier.testTag("tf_email")
modifier = modifier.testTag("tf_email"),
isError = isError
)
if (isError) {
Text(
modifier = Modifier
.testTag("txt_email_error")
.fillMaxWidth()
.padding(top = 4.dp),
text = errorMessages,
style = MaterialTheme.appTypography.bodySmall,
color = MaterialTheme.appColors.error,
)
}
}

@Composable
fun InputRegistrationField(
modifier: Modifier,
isErrorShown: Boolean,
registrationField: RegistrationField,
onValueChanged: (String, String, Boolean) -> Unit
onValueChanged: (String, String, Boolean) -> Unit,
) {
var inputRegistrationFieldValue by rememberSaveable {
mutableStateOf(registrationField.placeholder)
Expand Down Expand Up @@ -401,7 +417,7 @@ fun SelectableRegisterField(
registrationField: RegistrationField,
isErrorShown: Boolean,
initialValue: String,
onClick: (String, List<RegistrationField.Option>) -> Unit
onClick: (String, List<RegistrationField.Option>) -> Unit,
) {
val helperTextColor = if (registrationField.errorInstructions.isEmpty()) {
MaterialTheme.appColors.textSecondary
Expand Down Expand Up @@ -489,7 +505,7 @@ fun SelectableRegisterField(
fun ExpandableText(
modifier: Modifier = Modifier,
isExpanded: Boolean,
onClick: (Boolean) -> Unit
onClick: (Boolean) -> Unit,
) {
val transitionState = remember {
MutableTransitionState(isExpanded).apply {
Expand Down Expand Up @@ -537,7 +553,7 @@ fun ExpandableText(
@Composable
internal fun PasswordVisibilityIcon(
isPasswordVisible: Boolean,
onClick: () -> Unit
onClick: () -> Unit,
) {
val (image, description) = if (isPasswordVisible) {
Icons.Filled.VisibilityOff to stringResource(R.string.auth_accessibility_hide_password)
Expand Down
3 changes: 3 additions & 0 deletions auth/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
<string name="auth_restore_password_success">We have sent a password recover instructions to your email %s</string>
<string name="auth_example_email" translatable="false">username@domain.com</string>
<string name="auth_enter_email_username" tools:ignore="MissingTranslation">Enter email or username</string>
<string name="auth_error_empty_username_email">Please enter your username or e-mail address and try again.</string>
<string name="auth_error_empty_email">Please enter your e-mail address and try again.</string>
<string name="auth_enter_password">Enter password</string>
<string name="auth_error_empty_password">Please enter your password and try again.</string>
<string name="auth_create_new_account">Create an account to start learning today!</string>
<string name="auth_compete_registration" translatable="false">Complete your registration</string>
<string name="auth_google" tools:ignore="ExtraTranslation">Sign in with Google</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextOverflow
Expand Down Expand Up @@ -244,8 +245,7 @@ fun OfflineQueueCard(
maxLines = 1
)

val progress = progressValue.toFloat() / progressSize

val progress = if (progressSize == 0L) 0f else progressValue.toFloat() / progressSize
LinearProgressIndicator(
modifier = Modifier
.fillMaxWidth()
Expand Down Expand Up @@ -563,6 +563,11 @@ fun VideoSubtitles(
} else {
MaterialTheme.appColors.textFieldBorder
}
val fontWeight = if (currentIndex == index) {
FontWeight.SemiBold
} else {
FontWeight.Normal
}
Text(
modifier = Modifier
.fillMaxWidth()
Expand All @@ -571,7 +576,8 @@ fun VideoSubtitles(
},
text = Jsoup.parse(item.content).text(),
color = textColor,
style = MaterialTheme.appTypography.bodyMedium
style = MaterialTheme.appTypography.bodyMedium,
fontWeight = fontWeight,
)
Spacer(Modifier.height(16.dp))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ class VideoUnitFragment : Fragment(R.layout.fragment_video_unit) {
viewModel.isDownloaded = getBoolean(ARG_DOWNLOADED)
}
viewModel.downloadSubtitles()
handler.removeCallbacks(videoTimeRunnable)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ open class VideoUnitViewModel(


open fun markBlockCompleted(blockId: String, medium: String) {
logLoadedCompletedEvent(videoUrl, false, getCurrentVideoTime(), medium)
if (!isBlockAlreadyCompleted) {
logLoadedCompletedEvent(videoUrl, false, getCurrentVideoTime(), medium)
viewModelScope.launch {
try {
isBlockAlreadyCompleted = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class VideoViewModel(
}

fun markBlockCompleted(blockId: String, medium: String) {
logLoadedCompletedEvent(videoUrl, false, currentVideoTime, medium)
if (!isBlockAlreadyCompleted) {
logLoadedCompletedEvent(videoUrl, false, currentVideoTime, medium)
viewModelScope.launch {
try {
isBlockAlreadyCompleted = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ private fun DiscussionAddThreadScreen(
),
isSingleLine = false,
withRequiredMark = true,
imeAction = ImeAction.Done,
imeAction = ImeAction.Default,
keyboardActions = { focusManager ->
focusManager.clearFocus()
keyboardController?.hide()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ private fun InputEditField(
},
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = keyboardType,
imeAction = ImeAction.Done
imeAction = ImeAction.Default
),
keyboardActions = KeyboardActions {
keyboardController?.hide()
Expand Down

0 comments on commit 8019d86

Please sign in to comment.