diff --git a/core/src/main/java/org/openedx/core/utils/TimeUtils.kt b/core/src/main/java/org/openedx/core/utils/TimeUtils.kt index 8e3b6fa1f..9ccfaebef 100644 --- a/core/src/main/java/org/openedx/core/utils/TimeUtils.kt +++ b/core/src/main/java/org/openedx/core/utils/TimeUtils.kt @@ -59,7 +59,7 @@ object TimeUtils { private fun dateToCourseDate(resourceManager: ResourceManager, date: Date?): String { return formatDate( - format = resourceManager.getString(R.string.core_date_format_MMMM_dd_yyyy), date = date + format = resourceManager.getString(R.string.core_date_format_MMM_dd_yyyy), date = date ) } @@ -152,7 +152,7 @@ object TimeUtils { ) } else { resourceManager.getString( - R.string.core_label_ending, dateToCourseDate(resourceManager, end) + R.string.core_label_ends, dateToCourseDate(resourceManager, end) ) } } diff --git a/core/src/main/res/values-uk/strings.xml b/core/src/main/res/values-uk/strings.xml index 3ff872c5a..2aab8871c 100644 --- a/core/src/main/res/values-uk/strings.xml +++ b/core/src/main/res/values-uk/strings.xml @@ -13,7 +13,7 @@ Виберіть значення Починається %1$s Закінчився %1$s - Закінчується %1$s + Закінчується %1$s Термін дії курсу закінчується %1$s Термін дії курсу закінчується %1$s Термін дії курсу минув %1$s @@ -31,7 +31,7 @@ Обліковий запис користувача не активовано. Будь ласка, спочатку активуйте свій обліковий запис. Надіслати електронний лист за допомогою ... Не встановлено жодного поштового клієнта - dd MMMM, yyyy + dd MMMM, yyyy dd MMM yyyy HH:mm Оновлення додатку Ми рекомендуємо вам оновитись до останньої версії. Оновіться зараз, щоб отримати останні функції та виправлення. diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index 4410e4007..fc60e06d0 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -18,7 +18,7 @@ Select value Starting %1$s Ended %1$s - Ending %1$s + Ends %1$s Course access expires %1$s Course access expires on %1$s Course access expired %1$s @@ -46,7 +46,7 @@ OS version: Device model: Feedback - MMMM dd, yyyy + MMM dd, yyyy dd MMM yyyy hh:mm aaa App Update We recommend that you update to the latest version. Upgrade now to receive the latest features and fixes. diff --git a/course/src/main/java/org/openedx/course/presentation/unit/container/CourseUnitContainerViewModel.kt b/course/src/main/java/org/openedx/course/presentation/unit/container/CourseUnitContainerViewModel.kt index 323adb7cb..48b7abf33 100644 --- a/course/src/main/java/org/openedx/course/presentation/unit/container/CourseUnitContainerViewModel.kt +++ b/course/src/main/java/org/openedx/course/presentation/unit/container/CourseUnitContainerViewModel.kt @@ -81,21 +81,6 @@ class CourseUnitContainerViewModel( private val _descendantsBlocks = MutableStateFlow>(listOf()) val descendantsBlocks = _descendantsBlocks.asStateFlow() - fun loadBlocks(mode: CourseViewMode) { - currentMode = mode - try { - val courseStructure = when (mode) { - CourseViewMode.FULL -> interactor.getCourseStructureFromCache() - CourseViewMode.VIDEOS -> interactor.getCourseStructureForVideos() - } - val blocks = courseStructure.blockData - courseName = courseStructure.name - this.blocks.clearAndAddAll(blocks) - } catch (e: Exception) { - //ignore e.printStackTrace() - } - } - init { _indexInContainer.value = 0 @@ -113,6 +98,21 @@ class CourseUnitContainerViewModel( } } + fun loadBlocks(mode: CourseViewMode) { + currentMode = mode + try { + val courseStructure = when (mode) { + CourseViewMode.FULL -> interactor.getCourseStructureFromCache() + CourseViewMode.VIDEOS -> interactor.getCourseStructureForVideos() + } + val blocks = courseStructure.blockData + courseName = courseStructure.name + this.blocks.clearAndAddAll(blocks) + } catch (e: Exception) { + //ignore e.printStackTrace() + } + } + fun setupCurrentIndex(componentId: String = "") { if (currentSectionIndex != -1) { return diff --git a/dashboard/src/main/java/org/openedx/DashboardUI.kt b/dashboard/src/main/java/org/openedx/DashboardUI.kt new file mode 100644 index 000000000..fcbc0d7bf --- /dev/null +++ b/dashboard/src/main/java/org/openedx/DashboardUI.kt @@ -0,0 +1,49 @@ +package org.openedx + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Lock +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import org.openedx.core.ui.theme.OpenEdXTheme +import org.openedx.core.ui.theme.appColors + +@Composable +fun Lock(modifier: Modifier = Modifier) { + Box( + modifier = modifier.fillMaxSize() + ) { + Icon( + modifier = Modifier + .size(32.dp) + .padding(top = 8.dp, end = 8.dp) + .background( + color = MaterialTheme.appColors.onPrimary.copy(0.5f), + shape = CircleShape + ) + .padding(4.dp) + .align(Alignment.TopEnd), + imageVector = Icons.Default.Lock, + contentDescription = null, + tint = MaterialTheme.appColors.onSurface + ) + } +} + +@Preview +@Composable +private fun LockPreview() { + OpenEdXTheme { + Lock() + } +} \ No newline at end of file diff --git a/dashboard/src/main/java/org/openedx/courses/presentation/AllEnrolledCoursesFragment.kt b/dashboard/src/main/java/org/openedx/courses/presentation/AllEnrolledCoursesFragment.kt index 7f0d67ff0..4c946f6b9 100644 --- a/dashboard/src/main/java/org/openedx/courses/presentation/AllEnrolledCoursesFragment.kt +++ b/dashboard/src/main/java/org/openedx/courses/presentation/AllEnrolledCoursesFragment.kt @@ -6,7 +6,6 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -22,7 +21,6 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.lazy.grid.GridCells @@ -31,7 +29,6 @@ import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.pager.rememberPagerState -import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Card import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.ExperimentalMaterialApi @@ -43,7 +40,6 @@ import androidx.compose.material.Scaffold import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.Search import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.pullRefresh @@ -60,7 +56,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi 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.LocalContext @@ -82,6 +77,7 @@ import androidx.fragment.app.FragmentManager import coil.compose.AsyncImage import coil.request.ImageRequest import org.koin.androidx.compose.koinViewModel +import org.openedx.Lock import org.openedx.core.UIMessage import org.openedx.core.domain.model.Certificate import org.openedx.core.domain.model.CourseAssignments @@ -511,20 +507,7 @@ private fun CourseItem( ) } if (!course.course.coursewareAccess?.errorCode.isNullOrEmpty()) { - Icon( - modifier = Modifier - .size(32.dp) - .padding(top = 8.dp, end = 8.dp) - .background( - color = Color.White, - shape = CircleShape - ) - .padding(4.dp) - .align(Alignment.TopEnd), - imageVector = Icons.Default.Lock, - contentDescription = null, - tint = MaterialTheme.appColors.textWarning - ) + Lock() } } } diff --git a/dashboard/src/main/java/org/openedx/courses/presentation/AllEnrolledCoursesViewModel.kt b/dashboard/src/main/java/org/openedx/courses/presentation/AllEnrolledCoursesViewModel.kt index 22e6914f8..536a5f335 100644 --- a/dashboard/src/main/java/org/openedx/courses/presentation/AllEnrolledCoursesViewModel.kt +++ b/dashboard/src/main/java/org/openedx/courses/presentation/AllEnrolledCoursesViewModel.kt @@ -1,6 +1,7 @@ package org.openedx.courses.presentation import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow @@ -60,6 +61,8 @@ class AllEnrolledCoursesViewModel( private val currentFilter: MutableStateFlow = MutableStateFlow(CourseStatusFilter.ALL) + private var job: Job? = null + init { collectDiscoveryNotifier() getCourses(currentFilter.value) @@ -109,7 +112,8 @@ class AllEnrolledCoursesViewModel( page = 1 currentFilter.value = courseStatusFilter } - viewModelScope.launch { + job?.cancel() + job = viewModelScope.launch { try { isLoading = true val response = if (networkConnection.isOnline() || page > 1) { diff --git a/dashboard/src/main/java/org/openedx/courses/presentation/PrimaryCourseScreen.kt b/dashboard/src/main/java/org/openedx/courses/presentation/PrimaryCourseScreen.kt index 2e10cfe88..3d271b79d 100644 --- a/dashboard/src/main/java/org/openedx/courses/presentation/PrimaryCourseScreen.kt +++ b/dashboard/src/main/java/org/openedx/courses/presentation/PrimaryCourseScreen.kt @@ -21,7 +21,6 @@ import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.Card import androidx.compose.material.CircularProgressIndicator @@ -36,7 +35,6 @@ import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowForwardIos import androidx.compose.material.icons.filled.ChevronRight -import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.School import androidx.compose.material.icons.filled.Warning import androidx.compose.material.pullrefresh.PullRefreshIndicator @@ -51,7 +49,6 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.layout.ContentScale @@ -68,6 +65,7 @@ import androidx.fragment.app.FragmentManager import coil.compose.AsyncImage import coil.request.ImageRequest import org.koin.androidx.compose.koinViewModel +import org.openedx.Lock import org.openedx.core.UIMessage import org.openedx.core.domain.model.Certificate import org.openedx.core.domain.model.CourseAssignments @@ -292,12 +290,14 @@ private fun UserCourses( openCourse = openCourse ) } - SecondaryCourses( - courses = userCourses.enrollments, - apiHostUrl = apiHostUrl, - onCourseClick = openCourse, - onViewAllClick = onViewAllClick - ) + if (userCourses.enrollments.isNotEmpty()) { + SecondaryCourses( + courses = userCourses.enrollments, + apiHostUrl = apiHostUrl, + onCourseClick = openCourse, + onViewAllClick = onViewAllClick + ) + } } } @@ -437,20 +437,7 @@ private fun CourseListItem( ) } if (!course.course.coursewareAccess?.errorCode.isNullOrEmpty()) { - Icon( - modifier = Modifier - .size(32.dp) - .padding(top = 8.dp, end = 8.dp) - .background( - color = Color.White, - shape = CircleShape - ) - .padding(4.dp) - .align(Alignment.TopEnd), - imageVector = Icons.Default.Lock, - contentDescription = null, - tint = MaterialTheme.appColors.textWarning - ) + Lock() } } } @@ -477,6 +464,7 @@ private fun AssignmentItem( contentDescription = null ) Column( + modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(4.dp) ) { val infoTextStyle = if (title.isNullOrEmpty()) { @@ -497,6 +485,12 @@ private fun AssignmentItem( ) } } + Icon( + modifier = Modifier.size(16.dp), + imageVector = Icons.AutoMirrored.Filled.ArrowForwardIos, + tint = MaterialTheme.appColors.textDark, + contentDescription = null + ) } }