diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml index cb7184b..6830952 100644 --- a/.idea/appInsightsSettings.xml +++ b/.idea/appInsightsSettings.xml @@ -17,6 +17,20 @@ diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 26cf3bc..ff7463c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -33,14 +33,13 @@ android { applicationId = "ru.n08i40k.polytechnic.next" minSdk = 26 targetSdk = 35 - versionCode = 16 - versionName = "2.0.0" + versionCode = 18 + versionName = "2.0.2" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true } - versionNameSuffix = "prod" } buildTypes { diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/IntentRequestCodes.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/IntentRequestCodes.kt deleted file mode 100644 index 1ce37e8..0000000 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/IntentRequestCodes.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ru.n08i40k.polytechnic.next - -object IntentRequestCodes { - const val ALARM_CLV = 1337 -} \ No newline at end of file diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/PolytechnicApplication.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/PolytechnicApplication.kt index 15a767b..1da63bf 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/PolytechnicApplication.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/PolytechnicApplication.kt @@ -7,7 +7,6 @@ import android.os.Build import androidx.core.content.ContextCompat import dagger.hilt.android.HiltAndroidApp import ru.n08i40k.polytechnic.next.data.AppContainer -import ru.n08i40k.polytechnic.next.utils.or import javax.inject.Inject @HiltAndroidApp @@ -18,7 +17,7 @@ class PolytechnicApplication : Application() { fun getAppVersion(): String { return applicationContext.packageManager .getPackageInfo(this.packageName, 0) - .versionName or "1.0.0" + .versionName!! } fun hasNotificationPermission(): Boolean { diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/model/Day.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/model/Day.kt index 9029ad6..1b6dc7c 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/model/Day.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/model/Day.kt @@ -4,8 +4,9 @@ import android.os.Parcelable import kotlinx.datetime.Instant import kotlinx.datetime.LocalDateTime import kotlinx.parcelize.Parcelize -import kotlinx.parcelize.RawValue +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import ru.n08i40k.polytechnic.next.utils.InstantAsLongSerializer import ru.n08i40k.polytechnic.next.utils.dateTime import ru.n08i40k.polytechnic.next.utils.dayMinutes import ru.n08i40k.polytechnic.next.utils.now @@ -16,9 +17,18 @@ import ru.n08i40k.polytechnic.next.utils.now @Serializable class Day( val name: String, - val date: @RawValue Instant, + @Serializable(with = InstantAsLongSerializer::class) + @SerialName("date") + private val dateMillis: Long, val lessons: List ) : Parcelable { + constructor(name: String, date: Instant, lessons: List) : this( + name, date.toEpochMilliseconds(), lessons + ) + + val date: Instant + get() = Instant.fromEpochMilliseconds(dateMillis) + fun distanceToNextByLocalDateTime(from: LocalDateTime): Pair? { val toIdx = lessons .map { it.time.start } diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/model/LessonTime.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/model/LessonTime.kt index 458e386..6eb1a8d 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/model/LessonTime.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/model/LessonTime.kt @@ -6,19 +6,37 @@ import kotlinx.datetime.LocalDateTime import kotlinx.datetime.TimeZone import kotlinx.datetime.toInstant import kotlinx.parcelize.Parcelize -import kotlinx.parcelize.RawValue +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import ru.n08i40k.polytechnic.next.utils.InstantAsLongSerializer @Parcelize @Serializable data class LessonTime( - val start: @RawValue Instant, - val end: @RawValue Instant + @Serializable(with = InstantAsLongSerializer::class) + @SerialName("start") + private val startMillis: Long, + @Serializable(with = InstantAsLongSerializer::class) + @SerialName("end") + private val endMillis: Long ) : Parcelable { + constructor(start: Instant, end: Instant) : this( + start.toEpochMilliseconds(), + end.toEpochMilliseconds() + ) + + val start: Instant + get() = Instant.fromEpochMilliseconds(startMillis) + val end: Instant + get() = Instant.fromEpochMilliseconds(endMillis) + companion object { fun fromLocalDateTime(start: LocalDateTime, end: LocalDateTime): LessonTime { val timeZone = TimeZone.currentSystemDefault() - return LessonTime(start.toInstant(timeZone), end.toInstant(timeZone)) + return LessonTime( + start.toInstant(timeZone), + end.toInstant(timeZone) + ) } } } \ No newline at end of file diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/PolytechnicApp.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/PolytechnicApp.kt index 160eeb9..f487e7e 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/PolytechnicApp.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/PolytechnicApp.kt @@ -17,7 +17,8 @@ fun PolytechnicApp() { val navController = rememberNavController() NavHost( - navController = navController, startDestination = "auth" + navController = navController, + startDestination = "auth" ) { composable(route = "auth") { AuthScreen(navController) diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/MainScreen.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/MainScreen.kt index c340d7d..39aaa91 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/MainScreen.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/MainScreen.kt @@ -157,7 +157,10 @@ private fun LinkButton( verticalAlignment = Alignment.CenterVertically ) { BadgedBox(badge = { if (badged) Badge() }) { - Icon(imageVector = icon, contentDescription = text) + Icon( + imageVector = icon, + contentDescription = text + ) } Spacer(Modifier.width(5.dp)) Text(text) @@ -189,7 +192,10 @@ private fun TopNavBar( actions = { IconButton(onClick = { dropdownExpanded = true }) { BadgedBox(badge = { if (updateAvailable) Badge() }) { - Icon(imageVector = Icons.Filled.Menu, contentDescription = "TopAppBar Menu") + Icon( + imageVector = Icons.Filled.Menu, + contentDescription = "top app bar menu" + ) } } DropdownMenu( diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/DayPager.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/DayPager.kt index 3462b08..2cde061 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/DayPager.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/DayPager.kt @@ -14,35 +14,23 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.util.lerp +import kotlinx.datetime.LocalDateTime import ru.n08i40k.polytechnic.next.R import ru.n08i40k.polytechnic.next.data.schedule.impl.FakeScheduleRepository import ru.n08i40k.polytechnic.next.model.Group import ru.n08i40k.polytechnic.next.ui.widgets.NotificationCard -import java.time.LocalDate -import java.time.format.DateTimeFormatter -import java.time.temporal.WeekFields +import ru.n08i40k.polytechnic.next.utils.dateTime +import ru.n08i40k.polytechnic.next.utils.now import java.util.Calendar -import java.util.Locale import java.util.logging.Level import kotlin.math.absoluteValue -private fun isCurrentWeek(group: Group): Boolean { - if (group.days.isEmpty()) - return true +private fun isScheduleOutdated(group: Group): Boolean { + val nowDateTime = LocalDateTime.now() + val lastDay = group.days.lastOrNull() ?: return true + val lastLesson = lastDay.last ?: return true - val dateString = group.days[0].name - - val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy", Locale("ru")) - val datePart = dateString.split(" ").getOrNull(1) ?: return true - - val date = LocalDate.parse(datePart, formatter) - val currentDate = LocalDate.now() - - val weekField = WeekFields.of(Locale.getDefault()).weekOfWeekBasedYear() - val currentWeek = currentDate.get(weekField) - val dateWeek = date.get(weekField) - - return dateWeek >= currentWeek + return nowDateTime > lastLesson.time.end.dateTime } @Preview @@ -57,7 +45,7 @@ fun DayPager(group: Group = FakeScheduleRepository.exampleGroup) { pageCount = { group.days.size }) Column { - if (!isCurrentWeek(group)) { + if (isScheduleOutdated(group)) { NotificationCard( level = Level.WARNING, title = stringResource(R.string.outdated_schedule) diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/Paskhalko.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/Paskhalko.kt index 30b087e..ca94cdd 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/Paskhalko.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/Paskhalko.kt @@ -11,6 +11,9 @@ import ru.n08i40k.polytechnic.next.R @Composable internal fun PaskhalkoDialog() { Dialog(onDismissRequest = {}) { - Image(painterResource(R.drawable.paskhalko), contentDescription = "Paskhalko") + Image( + painter = painterResource(R.drawable.paskhalko), + contentDescription = "paskhalko" + ) } } \ No newline at end of file diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/ExpandableCard.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/ExpandableCard.kt index 9f62a99..03d7ad6 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/ExpandableCard.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/ExpandableCard.kt @@ -147,7 +147,7 @@ private fun ExpandableCardArrow( Icon( modifier = Modifier.rotate(rotationDegree), imageVector = Icons.Filled.ArrowDropDown, - contentDescription = "Expandable Arrow" + contentDescription = "expandable arrow" ) } diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/GroupSelector.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/GroupSelector.kt index 0e8dba4..3f06d4c 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/GroupSelector.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/GroupSelector.kt @@ -76,7 +76,7 @@ fun GroupSelector( value = value ?: groups.getOrElse(1) { "TODO" }!!, leadingIcon = { Icon( - imageVector = Icons.Filled.Email, + Icons.Filled.Email, contentDescription = "group" ) }, diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/NotificationCard.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/NotificationCard.kt index 9d52a81..08bca4f 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/NotificationCard.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/NotificationCard.kt @@ -51,8 +51,14 @@ fun NotificationCard( else -> AppIcons.Filled.Info } - Icon(imageVector = icon, contentDescription = "Level") - Icon(imageVector = icon, contentDescription = "Level") + Icon( + imageVector = icon, + contentDescription = "level" + ) + Icon( + imageVector = icon, + contentDescription = "level" + ) } Text( text = title, diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/RoleSelector.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/RoleSelector.kt index 23635e3..d767069 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/RoleSelector.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/RoleSelector.kt @@ -62,7 +62,12 @@ fun RoleSelector( onDismissRequest = { expanded = false }) { AcceptableUserRoles.forEach { DropdownMenuItem( - leadingIcon = { Icon(it.icon, contentDescription = "Role icon") }, + leadingIcon = { + Icon( + imageVector = it.icon, + contentDescription = "role icon" + ) + }, text = { Text(stringResource(it.stringId)) }, onClick = { expanded = false diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/utils/InstantAsLongSerializer.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/utils/InstantAsLongSerializer.kt new file mode 100644 index 0000000..c1db46a --- /dev/null +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/utils/InstantAsLongSerializer.kt @@ -0,0 +1,22 @@ +package ru.n08i40k.polytechnic.next.utils + +import kotlinx.datetime.Instant +import kotlinx.serialization.KSerializer +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +class InstantAsLongSerializer : KSerializer { + override val descriptor: SerialDescriptor = + PrimitiveSerialDescriptor("Instant", PrimitiveKind.STRING) + + override fun serialize(encoder: Encoder, value: Long) { + encoder.encodeString(Instant.fromEpochMilliseconds(value).toString()) + } + + override fun deserialize(decoder: Decoder): Long { + return Instant.parse(decoder.decodeString()).toEpochMilliseconds() + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/work/LinkUpdateWorker.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/work/LinkUpdateWorker.kt index 571b0a7..2c2e7b2 100644 --- a/app/src/main/java/ru/n08i40k/polytechnic/next/work/LinkUpdateWorker.kt +++ b/app/src/main/java/ru/n08i40k/polytechnic/next/work/LinkUpdateWorker.kt @@ -16,8 +16,6 @@ class LinkUpdateWorker(context: Context, params: WorkerParameters) : .getGroup() } -// CurrentLessonViewService.startService(applicationContext) - return Result.success() } } \ No newline at end of file