Complete main activity scroll

This commit is contained in:
2024-12-15 12:39:55 +04:00
parent 0d872c1c5f
commit 880e10309f
5 changed files with 112 additions and 32 deletions

1
.idea/misc.xml generated
View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">

View File

@@ -7,10 +7,10 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@@ -18,7 +18,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
@@ -27,13 +26,8 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.DateRange import androidx.compose.material.icons.filled.DateRange
import androidx.compose.material.icons.filled.KeyboardArrowRight
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Divider
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
import androidx.compose.material3.Snackbar import androidx.compose.material3.Snackbar
@@ -45,21 +39,25 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import com.example.ssau_schedule.api.Http import com.example.ssau_schedule.api.Http
import com.example.ssau_schedule.api.LessonAPI import com.example.ssau_schedule.api.LessonAPI
import com.example.ssau_schedule.api.LessonAPIErrorMessage import com.example.ssau_schedule.api.LessonAPIErrorMessage
import com.example.ssau_schedule.components.EmptyDay
import com.example.ssau_schedule.components.LessonCards import com.example.ssau_schedule.components.LessonCards
import com.example.ssau_schedule.data.base.Database import com.example.ssau_schedule.data.base.Database
import com.example.ssau_schedule.data.base.entity.lesson.Lesson import com.example.ssau_schedule.data.base.entity.lesson.Lesson
import com.example.ssau_schedule.data.store.StoreUtils import com.example.ssau_schedule.data.store.StoreUtils
import com.example.ssau_schedule.ui.theme.SSAU_ScheduleTheme import com.example.ssau_schedule.ui.theme.SSAU_ScheduleTheme
import kotlinx.coroutines.launch
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import java.util.Date import java.util.Date
@@ -73,8 +71,6 @@ class MainActivity : ComponentActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent { setContent {
SSAU_ScheduleTheme { SSAU_ScheduleTheme {
MainPage() MainPage()
@@ -87,14 +83,15 @@ class MainActivity : ComponentActivity() {
database = remember { Database.getInstance(applicationContext) } database = remember { Database.getInstance(applicationContext) }
val snackbarHostState = remember { SnackbarHostState() } val snackbarHostState = remember { SnackbarHostState() }
val lessons = remember { mutableStateOf<List<Lesson>>(listOf()) } val lessons = remember { mutableStateOf<List<Lesson>>(listOf()) }
val animationScope = rememberCoroutineScope()
val currentDate = remember { mutableStateOf(Date()) } val currentDate = remember { mutableStateOf(Date()) }
val currentDayOfWeek = remember { val currentDayOfWeek = remember {
mutableIntStateOf(Utils.Date.getDateOfWeek(currentDate.value)) mutableIntStateOf(Utils.Date.getDayOfWeek(currentDate.value))
} }
val pagerState = rememberPagerState( val pagerState = rememberPagerState(
initialPage = currentDayOfWeek.intValue-1, pageCount = {Int.MAX_VALUE}) initialPage = currentDayOfWeek.intValue,
pageCount = {Int.MAX_VALUE}
)
LaunchedEffect(false) { LaunchedEffect(false) {
lessons.value = database.lessonDao().getAll() lessons.value = database.lessonDao().getAll()
} }
@@ -145,13 +142,18 @@ class MainActivity : ComponentActivity() {
.padding(padding) .padding(padding)
.imePadding(), .imePadding(),
) { ) {
Column { Column(Modifier.fillMaxHeight()) {
Box(Modifier.fillMaxWidth().height(60.dp)) { Box(Modifier.fillMaxWidth().height(60.dp)) {
Row(Modifier.fillMaxSize().padding(10.dp), Row(Modifier.fillMaxSize().padding(10.dp),
horizontalArrangement = Arrangement.SpaceBetween) { horizontalArrangement = Arrangement.SpaceBetween) {
Box(Modifier.height(40.dp).width(40.dp) Box(Modifier.height(40.dp).width(40.dp)
.shadow(elevation = 6.dp, shape = RoundedCornerShape(50)) .shadow(elevation = 6.dp, shape = RoundedCornerShape(50))
.background(MaterialTheme.colorScheme.surface), .background(MaterialTheme.colorScheme.surface)
.clickable {
animationScope.launch {
pagerState.animateScrollToPage(pagerState.currentPage-1)
}
},
) { ) {
Icon(Icons.AutoMirrored.Filled.KeyboardArrowLeft, Icon(Icons.AutoMirrored.Filled.KeyboardArrowLeft,
contentDescription = "Forward icon", contentDescription = "Forward icon",
@@ -169,7 +171,10 @@ class MainActivity : ComponentActivity() {
contentDescription = "Date icon", contentDescription = "Date icon",
Modifier.height(40.dp).padding(0.dp, 0.dp, 10.dp, 0.dp), Modifier.height(40.dp).padding(0.dp, 0.dp, 10.dp, 0.dp),
tint = MaterialTheme.colorScheme.primary) tint = MaterialTheme.colorScheme.primary)
Text(Utils.Date.format(currentDate.value), Text(Utils.Date.format(
Utils.Date.addDays(currentDate.value,
pagerState.currentPage-currentDayOfWeek.intValue)
),
color = MaterialTheme.colorScheme.primary, color = MaterialTheme.colorScheme.primary,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
style = MaterialTheme.typography.bodyLarge) style = MaterialTheme.typography.bodyLarge)
@@ -177,7 +182,12 @@ class MainActivity : ComponentActivity() {
} }
Box(Modifier.height(40.dp).width(40.dp) Box(Modifier.height(40.dp).width(40.dp)
.shadow(elevation = 6.dp, shape = RoundedCornerShape(50)) .shadow(elevation = 6.dp, shape = RoundedCornerShape(50))
.background(MaterialTheme.colorScheme.surface), .background(MaterialTheme.colorScheme.surface)
.clickable {
animationScope.launch {
pagerState.animateScrollToPage(pagerState.currentPage+1)
}
},
) { ) {
Icon(Icons.AutoMirrored.Filled.KeyboardArrowRight, Icon(Icons.AutoMirrored.Filled.KeyboardArrowRight,
contentDescription = "Forward icon", contentDescription = "Forward icon",
@@ -187,12 +197,20 @@ class MainActivity : ComponentActivity() {
} }
} }
HorizontalDivider(Modifier.padding(20.dp, 0.dp)) HorizontalDivider(Modifier.padding(20.dp, 0.dp))
HorizontalPager(state = pagerState) { _ -> HorizontalPager(state = pagerState) { page ->
LessonCards(lessons.value) val todayLessons = lessons.value.filter { lesson ->
lesson.dayOfWeek-1 == Utils.Date.getDayOfWeek(
Utils.Date.addDays(currentDate.value, page-currentDayOfWeek.intValue)) &&
lesson.week == Utils.Date.getWeekOfStudyYear(
Utils.Date.addDays(currentDate.value, page-currentDayOfWeek.intValue))
}.sortedBy { lesson -> lesson.beginTime }
if(todayLessons.isEmpty())
EmptyDay(Modifier)
else
LessonCards(todayLessons)
} }
} }
} }
} }
} }
} }

View File

@@ -2,6 +2,7 @@ package com.example.ssau_schedule
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.graphics.Rect import android.graphics.Rect
import android.util.Log
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
@@ -11,6 +12,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalView import androidx.compose.ui.platform.LocalView
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.time.LocalDate
import java.util.Calendar import java.util.Calendar
class Utils { class Utils {
@@ -50,12 +52,31 @@ class Utils {
fun storeFormat(date: java.util.Date): String = StoreDateFormat.format(date) fun storeFormat(date: java.util.Date): String = StoreDateFormat.format(date)
fun format(date: java.util.Date): String = DateFormat.format(date) fun format(date: java.util.Date): String = DateFormat.format(date)
fun getDateOfWeek(data: java.util.Date): Int { fun getDayOfWeek(date: java.util.Date): Int {
val calendar = Calendar.getInstance() val calendar = Calendar.getInstance()
calendar.minimalDaysInFirstWeek = 6 calendar.time = date
calendar.firstDayOfWeek = Calendar.MONDAY return (calendar.get(Calendar.DAY_OF_WEEK)+5)%7
calendar.time = data }
return calendar.get(Calendar.DAY_OF_WEEK)-1 private fun getWeekOfYear(date: java.util.Date): Int {
val calendar = Calendar.getInstance()
calendar.time = date
return calendar.get(Calendar.WEEK_OF_YEAR) -
(if(calendar.get(Calendar.DAY_OF_WEEK) == 1) 1 else 0)
}
fun getWeekOfStudyYear(date: java.util.Date): Int {
val calendar = Calendar.getInstance()
calendar.time = java.util.Date()
val year = calendar.get(Calendar.YEAR)
calendar.time = parse("${year}-09-01")
return getWeekOfYear(date) - (calendar.get(Calendar.WEEK_OF_YEAR) -
(if(calendar.get(Calendar.DAY_OF_WEEK) == 1) 1 else 0))
}
fun addDays(date: java.util.Date, days: Int): java.util.Date {
val calendar = Calendar.getInstance()
calendar.time = date
calendar.add(Calendar.DAY_OF_MONTH, days)
return java.util.Date(calendar.timeInMillis)
} }
} }
} }

View File

@@ -0,0 +1,41 @@
package com.example.ssau_schedule.components
import androidx.compose.foundation.border
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.ssau_schedule.ui.theme.LessonColors
@Composable
fun EmptyDay(modifier: Modifier) {
Box(Modifier.fillMaxHeight().fillMaxWidth()) {
Row(modifier.fillMaxWidth()
.padding(14.dp, 8.dp)
.shadow(elevation = 6.dp, shape = RoundedCornerShape(12.dp))
.background(
if(isSystemInDarkTheme()) LessonColors.Background.Dark.Unknown
else LessonColors.Background.Light.Unknown
),
) {
AutoResizeText("Сегодня нет занятий",
modifier = modifier.fillMaxWidth().padding(14.dp),
fontSizeRange = FontSizeRange(10.sp, 24.sp),
color = MaterialTheme.colorScheme.secondary,
style = MaterialTheme.typography.titleLarge,
textAlign = TextAlign.Center)
}
}
}

View File

@@ -1,6 +1,5 @@
package com.example.ssau_schedule.components package com.example.ssau_schedule.components
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@@ -12,8 +11,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -63,9 +62,11 @@ fun LessonCard(modifier: Modifier, lesson: Lesson) {
@Composable @Composable
fun LessonCards(lessons: List<Lesson>) { fun LessonCards(lessons: List<Lesson>) {
Column(Modifier.verticalScroll(ScrollState(0))) { Box(Modifier.fillMaxHeight().fillMaxWidth()) {
lessons.forEach { lesson -> LazyColumn {
LessonCard(Modifier, lesson) items(lessons.count()) {
LessonCard(Modifier, lessons[it])
}
} }
} }
} }