Skip to content

Commit bef4311

Browse files
authored
Merge pull request #12
Add placeholders for data
2 parents 9468cfd + 85eb339 commit bef4311

32 files changed

Lines changed: 799 additions & 346 deletions

app/src/main/java/ru/neexol/rtut/data/lessons/models/Lesson.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ data class Lesson(
1111
val number: Int,
1212
val weeks: List<Int>
1313
) {
14-
private fun formatName() = name.trim().lowercase().let {
14+
fun formatName() = name.trim().lowercase().let {
1515
if (it == "военная" || it == "подготовка") "Военная подготовка" else name
1616
}
1717
val lessonWithType = formatName() + (if (type.isNotBlank()) ", ${type.uppercase()}" else "")
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package ru.neexol.rtut.presentation.components
2+
3+
import androidx.annotation.DrawableRes
4+
import androidx.annotation.StringRes
5+
import androidx.compose.foundation.layout.*
6+
import androidx.compose.material.ContentAlpha
7+
import androidx.compose.material.Icon
8+
import androidx.compose.material.Text
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.ui.Alignment
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.draw.alpha
13+
import androidx.compose.ui.res.painterResource
14+
import androidx.compose.ui.res.stringResource
15+
import androidx.compose.ui.text.style.TextAlign
16+
import androidx.compose.ui.unit.dp
17+
import androidx.compose.ui.unit.sp
18+
19+
@Composable
20+
fun ImagePlaceholder(
21+
@DrawableRes iconId: Int,
22+
@StringRes labelId: Int
23+
) {
24+
Box(
25+
modifier = Modifier.fillMaxSize().imePadding(),
26+
contentAlignment = Alignment.Center
27+
) {
28+
Column(
29+
modifier = Modifier.padding(horizontal = 90.dp).alpha(ContentAlpha.medium),
30+
horizontalAlignment = Alignment.CenterHorizontally
31+
) {
32+
Icon(
33+
modifier = Modifier.size(80.dp),
34+
painter = painterResource(iconId),
35+
contentDescription = stringResource(labelId)
36+
)
37+
Text(
38+
text = stringResource(labelId),
39+
fontSize = 20.sp,
40+
textAlign = TextAlign.Center
41+
)
42+
}
43+
}
44+
}

app/src/main/java/ru/neexol/rtut/presentation/components/LessonItem.kt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,23 @@ import androidx.compose.material.Text
1313
import androidx.compose.runtime.Composable
1414
import androidx.compose.ui.Modifier
1515
import androidx.compose.ui.draw.alpha
16+
import androidx.compose.ui.platform.LocalClipboardManager
17+
import androidx.compose.ui.text.AnnotatedString
1618
import androidx.compose.ui.unit.dp
1719
import ru.neexol.rtut.data.lessons.models.Lesson
1820
import ru.neexol.rtut.data.lessons.models.LessonTime
1921

2022
@Composable
21-
fun LessonItem(lesson: Lesson?, time: LessonTime, onClick: (() -> Unit)? = null) {
23+
fun LessonItem(
24+
lesson: Lesson?,
25+
time: LessonTime,
26+
onClassroomCopy: () -> Unit,
27+
onLessonClick: (() -> Unit)? = null
28+
) {
2229
val surfaceModifier = if (lesson == null) {
2330
Modifier.alpha(ContentAlpha.disabled)
2431
} else {
25-
onClick?.let {
32+
onLessonClick?.let {
2633
Modifier.clickable { it() }
2734
} ?: Modifier
2835
}
@@ -33,7 +40,7 @@ fun LessonItem(lesson: Lesson?, time: LessonTime, onClick: (() -> Unit)? = null)
3340
Row(Modifier.padding(16.dp)) {
3441
Time(time)
3542
Payload(lesson)
36-
Classroom(lesson?.classroom)
43+
Classroom(lesson?.classroom, onClassroomCopy)
3744
}
3845
}
3946
}
@@ -76,11 +83,16 @@ private fun RowScope.Payload(lesson: Lesson?) {
7683
}
7784

7885
@Composable
79-
private fun Classroom(text: String?) {
86+
private fun Classroom(text: String?, onClassroomCopy: () -> Unit,) {
87+
val clipboardManager = LocalClipboardManager.current
8088
Text(
8189
modifier = Modifier
8290
.background(MaterialTheme.colors.primary, MaterialTheme.shapes.small)
83-
.padding(vertical = 5.dp, horizontal = 8.dp),
91+
.padding(vertical = 5.dp, horizontal = 8.dp)
92+
.clickable {
93+
clipboardManager.setText(AnnotatedString(text?.uppercase().toContent()))
94+
onClassroomCopy()
95+
},
8496
text = text?.uppercase().toContent(),
8597
style = MaterialTheme.typography.caption,
8698
color = MaterialTheme.colors.onPrimary
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package ru.neexol.rtut.presentation.components
2+
3+
import androidx.compose.runtime.snapshotFlow
4+
import com.google.accompanist.pager.ExperimentalPagerApi
5+
import com.google.accompanist.pager.PagerState
6+
import java.math.BigDecimal
7+
8+
@ExperimentalPagerApi
9+
fun scrollingPair(state1: PagerState, state2: PagerState) = when {
10+
state1.isScrollInProgress -> state1 to state2
11+
state2.isScrollInProgress -> state2 to state1
12+
else -> null
13+
}
14+
15+
@ExperimentalPagerApi
16+
suspend fun syncScroll(pair: Pair<PagerState, PagerState>?) {
17+
val (scrollingState, followingState) = pair ?: return
18+
snapshotFlow { scrollingState.currentPage + scrollingState.currentPageOffset }
19+
.collect { pagePart ->
20+
val divideAndRemainder = BigDecimal.valueOf(pagePart.toDouble())
21+
.divideAndRemainder(BigDecimal.ONE)
22+
23+
followingState.scrollToPage(
24+
divideAndRemainder[0].toInt(),
25+
divideAndRemainder[1].toFloat(),
26+
)
27+
}
28+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package ru.neexol.rtut.presentation.screens.main.ui
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.*
5+
import androidx.compose.material.*
6+
import androidx.compose.runtime.Composable
7+
import androidx.compose.runtime.LaunchedEffect
8+
import androidx.compose.runtime.remember
9+
import androidx.compose.runtime.rememberCoroutineScope
10+
import androidx.compose.ui.Alignment
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.res.painterResource
13+
import androidx.compose.ui.res.stringResource
14+
import androidx.compose.ui.unit.dp
15+
import kotlinx.coroutines.launch
16+
import ru.neexol.rtut.R
17+
import ru.neexol.rtut.presentation.components.GroupTextField
18+
import ru.neexol.rtut.presentation.screens.settings.SettingsViewModel
19+
20+
@Composable
21+
fun InitialGroupChoose(vm: SettingsViewModel) {
22+
val coroutineScope = rememberCoroutineScope()
23+
val snackbarHostState = remember { SnackbarHostState() }
24+
LaunchedEffect(vm.groupUiState.message) {
25+
vm.groupUiState.message?.let {
26+
coroutineScope.launch {
27+
snackbarHostState.currentSnackbarData?.dismiss()
28+
snackbarHostState.showSnackbar(it)
29+
vm.clearGroupMessage()
30+
}
31+
}
32+
}
33+
34+
Surface {
35+
Box(
36+
modifier = Modifier
37+
.fillMaxSize()
38+
.background(MaterialTheme.colors.primaryVariant),
39+
contentAlignment = Alignment.Center
40+
) {
41+
Column(
42+
modifier = Modifier.fillMaxWidth(),
43+
horizontalAlignment = Alignment.CenterHorizontally
44+
) {
45+
Icon(
46+
modifier = Modifier.size(148.dp),
47+
tint = MaterialTheme.colors.primary,
48+
painter = painterResource(R.drawable.ic_launcher_foreground),
49+
contentDescription = null
50+
)
51+
Text(stringResource(R.string.enter_group))
52+
Spacer(Modifier.size(16.dp))
53+
GroupTextField(stringResource(R.string.group_pattern), vm::editGroup)
54+
}
55+
SnackbarHost(
56+
hostState = snackbarHostState,
57+
modifier = Modifier.align(Alignment.BottomCenter)
58+
)
59+
}
60+
}
61+
}

app/src/main/java/ru/neexol/rtut/presentation/screens/main/ui/InitialScreen.kt

Lines changed: 0 additions & 58 deletions
This file was deleted.
Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package ru.neexol.rtut.presentation.screens.main.ui
22

3+
import androidx.compose.animation.Crossfade
34
import androidx.compose.animation.ExperimentalAnimationApi
45
import androidx.compose.foundation.layout.Column
6+
import androidx.compose.foundation.layout.fillMaxSize
57
import androidx.compose.foundation.layout.navigationBarsPadding
6-
import androidx.compose.material.ExperimentalMaterialApi
7-
import androidx.compose.material.ModalBottomSheetValue
8-
import androidx.compose.material.rememberModalBottomSheetState
8+
import androidx.compose.material.*
99
import androidx.compose.runtime.Composable
1010
import androidx.compose.runtime.derivedStateOf
1111
import androidx.compose.runtime.getValue
@@ -21,15 +21,26 @@ import ru.neexol.rtut.presentation.screens.settings.SettingsViewModel
2121
@Composable
2222
fun MainScreen() {
2323
val vm: SettingsViewModel = viewModel()
24-
if (!vm.groupUiState.group.isNullOrEmpty()) {
25-
val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
26-
val isSheetHidden by remember {
27-
derivedStateOf { !sheetState.isVisible }
28-
}
24+
Surface(
25+
modifier = Modifier.fillMaxSize(),
26+
color = MaterialTheme.colors.primaryVariant
27+
) {
28+
Crossfade(vm.groupUiState.group) { group ->
29+
when (group?.isEmpty()) {
30+
null -> {}
31+
true -> InitialGroupChoose(vm)
32+
else -> {
33+
val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
34+
val isSheetHidden by remember {
35+
derivedStateOf { !sheetState.isVisible }
36+
}
2937

30-
Column(Modifier.navigationBarsPadding()) {
31-
StatusBar(!isSheetHidden)
32-
Screens(sheetState, isSheetHidden, vm)
38+
Column(Modifier.navigationBarsPadding()) {
39+
StatusBar(!isSheetHidden)
40+
Screens(sheetState, isSheetHidden)
41+
}
42+
}
43+
}
3344
}
34-
} else InitialScreen(vm.groupUiState.group?.run { vm::editGroup })
45+
}
3546
}

app/src/main/java/ru/neexol/rtut/presentation/screens/main/ui/Screens.kt

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@ import androidx.navigation.compose.composable
1818
import androidx.navigation.compose.rememberNavController
1919
import com.google.accompanist.pager.ExperimentalPagerApi
2020
import kotlinx.coroutines.launch
21-
import ru.neexol.rtut.data.lessons.models.Lesson
2221
import ru.neexol.rtut.presentation.screens.main.Screen
2322
import ru.neexol.rtut.presentation.screens.map.ui.MapScreen
2423
import ru.neexol.rtut.presentation.screens.notes.NotesViewModel
2524
import ru.neexol.rtut.presentation.screens.notes.ui.NotesScreen
2625
import ru.neexol.rtut.presentation.screens.schedule.ui.ScheduleScreen
27-
import ru.neexol.rtut.presentation.screens.settings.SettingsViewModel
2826
import ru.neexol.rtut.presentation.screens.settings.ui.SettingsScreen
2927
import ru.neexol.rtut.presentation.screens.teacher.ui.TeacherScreen
3028

@@ -34,22 +32,17 @@ import ru.neexol.rtut.presentation.screens.teacher.ui.TeacherScreen
3432
@Composable
3533
internal fun Screens(
3634
sheetState: ModalBottomSheetState,
37-
isSheetHidden: Boolean,
38-
settingsVM: SettingsViewModel
35+
isSheetHidden: Boolean
3936
) {
4037
val mainNavController = rememberNavController()
38+
val coroutineScope = rememberCoroutineScope()
4139

4240
val notesVM = viewModel<NotesViewModel>()
4341
LaunchedEffect(isSheetHidden) {
4442
if (isSheetHidden) {
4543
notesVM.clearState()
4644
}
4745
}
48-
val coroutineScope = rememberCoroutineScope()
49-
val showNotes: (Lesson, String) -> Unit = { l, w ->
50-
notesVM.setLesson(l, w)
51-
coroutineScope.launch { sheetState.show() }
52-
}
5346

5447
ModalBottomSheetLayout(
5548
sheetState = sheetState,
@@ -60,10 +53,17 @@ internal fun Screens(
6053
bottomBar = { ScreensBottomBar(mainNavController) }
6154
) { innerPadding ->
6255
NavHost(mainNavController, Screen.Schedule.route, Modifier.padding(innerPadding)) {
63-
composable(Screen.Schedule.route) { ScheduleScreen { l, w -> showNotes(l, w) } }
56+
composable(Screen.Schedule.route) {
57+
ScheduleScreen(
58+
onLessonClick = { l, w ->
59+
notesVM.setLesson(l, w)
60+
coroutineScope.launch { sheetState.show() }
61+
}
62+
)
63+
}
6464
composable(Screen.Teacher.route) { TeacherScreen() }
6565
composable(Screen.Map.route) { MapScreen() }
66-
composable(Screen.Settings.route) { SettingsScreen(settingsVM) }
66+
composable(Screen.Settings.route) { SettingsScreen() }
6767
}
6868
}
6969
}

0 commit comments

Comments
 (0)