Skip to content

Commit 0519fa9

Browse files
feat: empty state view
1 parent 9f0ae15 commit 0519fa9

File tree

8 files changed

+175
-16
lines changed

8 files changed

+175
-16
lines changed

course/src/main/java/org/openedx/course/presentation/assignments/CourseContentAssignmentScreen.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,19 @@ import androidx.compose.ui.unit.Dp
5151
import androidx.compose.ui.unit.dp
5252
import androidx.fragment.app.FragmentManager
5353
import org.openedx.core.BlockType
54-
import org.openedx.core.NoContentScreenType
5554
import org.openedx.core.domain.model.AssignmentProgress
5655
import org.openedx.core.domain.model.Block
5756
import org.openedx.core.domain.model.BlockCounts
5857
import org.openedx.core.domain.model.CourseProgress
5958
import org.openedx.core.domain.model.Progress
6059
import org.openedx.core.presentation.course.CourseViewMode
61-
import org.openedx.core.ui.NoContentScreen
6260
import org.openedx.core.ui.theme.OpenEdXTheme
6361
import org.openedx.core.ui.theme.appColors
6462
import org.openedx.core.ui.theme.appShapes
6563
import org.openedx.core.ui.theme.appTypography
6664
import org.openedx.core.utils.TimeUtils
6765
import org.openedx.course.R
66+
import org.openedx.course.presentation.contenttab.CourseContentAssignmentEmptyState
6867
import org.openedx.course.presentation.ui.CourseProgress
6968
import org.openedx.foundation.presentation.WindowSize
7069
import org.openedx.foundation.presentation.WindowType
@@ -87,11 +86,13 @@ fun CourseContentAssignmentScreen(
8786
windowSize: WindowSize,
8887
viewModel: CourseAssignmentViewModel,
8988
fragmentManager: FragmentManager,
89+
onNavigateToHome: () -> Unit = {},
9090
) {
9191
val uiState by viewModel.uiState.collectAsState()
9292
CourseContentAssignmentScreen(
9393
uiState = uiState,
9494
windowSize = windowSize,
95+
onNavigateToHome = onNavigateToHome,
9596
onAssignmentClick = { subSectionBlock ->
9697
viewModel.courseRouter.navigateToCourseSubsections(
9798
fm = fragmentManager,
@@ -107,6 +108,7 @@ fun CourseContentAssignmentScreen(
107108
private fun CourseContentAssignmentScreen(
108109
uiState: CourseAssignmentUIState,
109110
windowSize: WindowSize,
111+
onNavigateToHome: () -> Unit,
110112
onAssignmentClick: (Block) -> Unit,
111113
) {
112114
val screenWidth by remember(key1 = windowSize) {
@@ -129,7 +131,9 @@ private fun CourseContentAssignmentScreen(
129131
}
130132

131133
is CourseAssignmentUIState.Empty -> {
132-
NoContentScreen(noContentScreenType = NoContentScreenType.COURSE_ASSIGNMENT)
134+
CourseContentAssignmentEmptyState(
135+
onReturnToCourseClick = onNavigateToHome
136+
)
133137
}
134138

135139
is CourseAssignmentUIState.CourseData -> {
@@ -505,6 +509,7 @@ private fun CourseContentAssignmentScreenPreview() {
505509
courseProgress = mockCourseProgress
506510
),
507511
onAssignmentClick = {},
512+
onNavigateToHome = {},
508513
)
509514
}
510515
}
@@ -517,6 +522,7 @@ private fun CourseContentAssignmentScreenEmptyPreview() {
517522
windowSize = WindowSize(WindowType.Compact, WindowType.Compact),
518523
uiState = CourseAssignmentUIState.Empty,
519524
onAssignmentClick = {},
525+
onNavigateToHome = {},
520526
)
521527
}
522528
}
@@ -536,6 +542,7 @@ private fun CourseContentAssignmentScreenTabletPreview() {
536542
courseProgress = mockCourseProgress
537543
),
538544
onAssignmentClick = {},
545+
onNavigateToHome = {},
539546
)
540547
}
541548
}

course/src/main/java/org/openedx/course/presentation/container/CourseContainerFragment.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,8 @@ private fun DashboardPager(
461461
fragmentManager: FragmentManager,
462462
onContentTabSelected: (CourseContentTab) -> Unit,
463463
) {
464+
val scope = rememberCoroutineScope()
465+
464466
HorizontalPager(
465467
state = pagerState,
466468
userScrollEnabled = false,
@@ -545,7 +547,16 @@ private fun DashboardPager(
545547
courseId = viewModel.courseId,
546548
courseName = viewModel.courseName,
547549
pagerState = contentTabPagerState,
548-
onTabSelected = onContentTabSelected
550+
onTabSelected = onContentTabSelected,
551+
onNavigateToHome = {
552+
scope.launch {
553+
pagerState.animateScrollToPage(
554+
CourseContainerTab.entries.indexOf(
555+
CourseContainerTab.HOME
556+
)
557+
)
558+
}
559+
}
549560
)
550561
}
551562
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package org.openedx.course.presentation.contenttab
2+
3+
import android.content.res.Configuration
4+
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Column
6+
import androidx.compose.foundation.layout.Spacer
7+
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.height
9+
import androidx.compose.foundation.layout.padding
10+
import androidx.compose.foundation.layout.size
11+
import androidx.compose.foundation.rememberScrollState
12+
import androidx.compose.foundation.verticalScroll
13+
import androidx.compose.material.Icon
14+
import androidx.compose.material.MaterialTheme
15+
import androidx.compose.material.Text
16+
import androidx.compose.material.icons.Icons
17+
import androidx.compose.material.icons.automirrored.filled.ArrowBack
18+
import androidx.compose.runtime.Composable
19+
import androidx.compose.ui.Alignment
20+
import androidx.compose.ui.Modifier
21+
import androidx.compose.ui.platform.LocalConfiguration
22+
import androidx.compose.ui.res.painterResource
23+
import androidx.compose.ui.res.stringResource
24+
import androidx.compose.ui.text.font.FontWeight
25+
import androidx.compose.ui.text.style.TextAlign
26+
import androidx.compose.ui.unit.dp
27+
import org.openedx.core.ui.IconText
28+
import org.openedx.core.ui.OpenEdXButton
29+
import org.openedx.core.ui.theme.appColors
30+
import org.openedx.core.ui.theme.appTypography
31+
import org.openedx.course.R
32+
33+
@Composable
34+
fun ContentTabEmptyState(
35+
message: String,
36+
onReturnToCourseClick: () -> Unit
37+
) {
38+
val configuration = LocalConfiguration.current
39+
Column(
40+
modifier = Modifier
41+
.fillMaxWidth()
42+
.padding(vertical = 24.dp)
43+
.verticalScroll(rememberScrollState()),
44+
verticalArrangement = Arrangement.Center,
45+
horizontalAlignment = Alignment.CenterHorizontally
46+
) {
47+
if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
48+
Icon(
49+
modifier = Modifier
50+
.size(120.dp),
51+
painter = painterResource(R.drawable.course_ic_warning),
52+
contentDescription = null,
53+
tint = MaterialTheme.appColors.textFieldHint
54+
)
55+
Spacer(Modifier.height(24.dp))
56+
}
57+
Text(
58+
modifier = Modifier.padding(horizontal = 24.dp),
59+
text = message,
60+
color = MaterialTheme.appColors.textPrimary,
61+
style = MaterialTheme.appTypography.bodyLarge,
62+
fontWeight = FontWeight.Medium,
63+
textAlign = TextAlign.Center
64+
)
65+
Spacer(Modifier.height(16.dp))
66+
OpenEdXButton(
67+
modifier = Modifier
68+
.fillMaxWidth()
69+
.padding(horizontal = 24.dp),
70+
textColor = MaterialTheme.appColors.secondaryButtonText,
71+
backgroundColor = MaterialTheme.appColors.secondaryButtonBackground,
72+
onClick = onReturnToCourseClick
73+
) {
74+
IconText(
75+
text = stringResource(id = R.string.course_return_to_course_home),
76+
icon = Icons.AutoMirrored.Filled.ArrowBack,
77+
color = MaterialTheme.appColors.secondaryButtonText,
78+
textStyle = MaterialTheme.appTypography.labelLarge
79+
)
80+
}
81+
}
82+
}
83+
84+
@Composable
85+
fun CourseContentAllEmptyState(
86+
onReturnToCourseClick: () -> Unit
87+
) {
88+
ContentTabEmptyState(
89+
message = stringResource(id = org.openedx.core.R.string.core_no_course_content),
90+
onReturnToCourseClick = onReturnToCourseClick
91+
)
92+
}
93+
94+
@Composable
95+
fun CourseContentVideoEmptyState(
96+
onReturnToCourseClick: () -> Unit
97+
) {
98+
ContentTabEmptyState(
99+
message = stringResource(id = org.openedx.core.R.string.core_no_videos),
100+
onReturnToCourseClick = onReturnToCourseClick
101+
)
102+
}
103+
104+
@Composable
105+
fun CourseContentAssignmentEmptyState(
106+
onReturnToCourseClick: () -> Unit
107+
) {
108+
ContentTabEmptyState(
109+
message = stringResource(id = org.openedx.core.R.string.core_no_assignments),
110+
onReturnToCourseClick = onReturnToCourseClick
111+
)
112+
}

course/src/main/java/org/openedx/course/presentation/contenttab/ContentTabScreen.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ fun ContentTabScreen(
5353
courseName: String,
5454
pagerState: PagerState,
5555
onTabSelected: (CourseContentTab) -> Unit = {},
56+
onNavigateToHome: () -> Unit = {},
5657
) {
5758
val tabsWidth by remember(key1 = windowSize) {
5859
mutableStateOf(
@@ -158,6 +159,7 @@ fun ContentTabScreen(
158159
)
159160
}),
160161
fragmentManager = fragmentManager,
162+
onNavigateToHome = onNavigateToHome
161163
)
162164

163165
CourseContentTab.VIDEOS -> CourseContentVideoScreen(
@@ -168,13 +170,15 @@ fun ContentTabScreen(
168170
courseName
169171
)
170172
}),
171-
fragmentManager = fragmentManager
173+
fragmentManager = fragmentManager,
174+
onNavigateToHome = onNavigateToHome
172175
)
173176

174177
CourseContentTab.ASSIGNMENTS -> CourseContentAssignmentScreen(
175178
windowSize = windowSize,
176179
viewModel = koinViewModel(parameters = { parametersOf(courseId) }),
177180
fragmentManager = fragmentManager,
181+
onNavigateToHome = onNavigateToHome
178182
)
179183
}
180184
}

course/src/main/java/org/openedx/course/presentation/outline/CourseContentAllScreen.kt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ import androidx.compose.ui.unit.Dp
4141
import androidx.compose.ui.unit.dp
4242
import androidx.fragment.app.FragmentManager
4343
import org.openedx.core.BlockType
44-
import org.openedx.core.NoContentScreenType
4544
import org.openedx.core.domain.model.AssignmentProgress
4645
import org.openedx.core.domain.model.Block
4746
import org.openedx.core.domain.model.BlockCounts
@@ -54,14 +53,14 @@ import org.openedx.core.extension.getChapterBlocks
5453
import org.openedx.core.presentation.course.CourseViewMode
5554
import org.openedx.core.ui.CircularProgress
5655
import org.openedx.core.ui.HandleUIMessage
57-
import org.openedx.core.ui.NoContentScreen
5856
import org.openedx.core.ui.OpenEdXButton
5957
import org.openedx.core.ui.TextIcon
6058
import org.openedx.core.ui.displayCutoutForLandscape
6159
import org.openedx.core.ui.theme.OpenEdXTheme
6260
import org.openedx.core.ui.theme.appColors
6361
import org.openedx.core.ui.theme.appTypography
6462
import org.openedx.course.R
63+
import org.openedx.course.presentation.contenttab.CourseContentAllEmptyState
6564
import org.openedx.course.presentation.ui.CourseDatesBanner
6665
import org.openedx.course.presentation.ui.CourseDatesBannerTablet
6766
import org.openedx.course.presentation.ui.CourseMessage
@@ -79,6 +78,7 @@ fun CourseContentAllScreen(
7978
windowSize: WindowSize,
8079
viewModel: CourseContentAllViewModel,
8180
fragmentManager: FragmentManager,
81+
onNavigateToHome: () -> Unit = {},
8282
) {
8383
val uiState by viewModel.uiState.collectAsState()
8484
val uiMessage by viewModel.uiMessage.collectAsState(null)
@@ -95,6 +95,7 @@ fun CourseContentAllScreen(
9595
windowSize = windowSize,
9696
uiState = uiState,
9797
uiMessage = uiMessage,
98+
onNavigateToHome = onNavigateToHome,
9899
onExpandClick = { block ->
99100
if (viewModel.switchCourseSections(block.id)) {
100101
viewModel.sequentialClickedEvent(
@@ -158,6 +159,7 @@ private fun CourseContentAllUI(
158159
windowSize: WindowSize,
159160
uiState: CourseContentAllUIState,
160161
uiMessage: UIMessage?,
162+
onNavigateToHome: () -> Unit,
161163
onExpandClick: (Block) -> Unit,
162164
onSubSectionClick: (Block) -> Unit,
163165
onResumeClick: (String) -> Unit,
@@ -217,7 +219,9 @@ private fun CourseContentAllUI(
217219
when (uiState) {
218220
is CourseContentAllUIState.CourseData -> {
219221
if (uiState.courseStructure.blockData.isEmpty()) {
220-
NoContentScreen(noContentScreenType = NoContentScreenType.COURSE_OUTLINE)
222+
CourseContentAllEmptyState(
223+
onReturnToCourseClick = onNavigateToHome
224+
)
221225
} else {
222226
LazyColumn(
223227
modifier = Modifier.fillMaxSize(),
@@ -332,7 +336,9 @@ private fun CourseContentAllUI(
332336
}
333337

334338
CourseContentAllUIState.Error -> {
335-
NoContentScreen(noContentScreenType = NoContentScreenType.COURSE_OUTLINE)
339+
CourseContentAllEmptyState(
340+
onReturnToCourseClick = onNavigateToHome
341+
)
336342
}
337343

338344
CourseContentAllUIState.Loading -> {
@@ -423,6 +429,7 @@ private fun CourseOutlineScreenPreview() {
423429
onDownloadClick = {},
424430
onResetDatesClick = {},
425431
onCertificateClick = {},
432+
onNavigateToHome = {},
426433
)
427434
}
428435
}
@@ -458,6 +465,7 @@ private fun CourseContentAllScreenTabletPreview() {
458465
onDownloadClick = {},
459466
onResetDatesClick = {},
460467
onCertificateClick = {},
468+
onNavigateToHome = {},
461469
)
462470
}
463471
}

0 commit comments

Comments
 (0)