mirror of
https://github.com/n08i40k/polytechnic-android.git
synced 2025-12-06 09:47:48 +03:00
2.0.2
Исправлено отображение уведомления о просмотре устаревшего расписания. Исправлен запуск сервиса постоянного уведомления.
This commit is contained in:
14
.idea/appInsightsSettings.xml
generated
14
.idea/appInsightsSettings.xml
generated
@@ -17,6 +17,20 @@
|
||||
</option>
|
||||
<option name="signal" value="SIGNAL_UNSPECIFIED" />
|
||||
<option name="timeIntervalDays" value="THIRTY_DAYS" />
|
||||
<option name="versions">
|
||||
<list>
|
||||
<VersionSetting>
|
||||
<option name="buildVersion" value="17" />
|
||||
<option name="displayName" value="2.0.1 (17)" />
|
||||
<option name="displayVersion" value="2.0.1" />
|
||||
</VersionSetting>
|
||||
<VersionSetting>
|
||||
<option name="buildVersion" value="16" />
|
||||
<option name="displayName" value="2.0.0prod (16)" />
|
||||
<option name="displayVersion" value="2.0.0prod" />
|
||||
</VersionSetting>
|
||||
</list>
|
||||
</option>
|
||||
<option name="visibilityType" value="ALL" />
|
||||
</InsightsFilterSettings>
|
||||
</value>
|
||||
|
||||
4
.idea/runConfigurations.xml
generated
4
.idea/runConfigurations.xml
generated
@@ -5,8 +5,12 @@
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package ru.n08i40k.polytechnic.next
|
||||
|
||||
object IntentRequestCodes {
|
||||
const val ALARM_CLV = 1337
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<Lesson>
|
||||
) : Parcelable {
|
||||
constructor(name: String, date: Instant, lessons: List<Lesson>) : this(
|
||||
name, date.toEpochMilliseconds(), lessons
|
||||
)
|
||||
|
||||
val date: Instant
|
||||
get() = Instant.fromEpochMilliseconds(dateMillis)
|
||||
|
||||
fun distanceToNextByLocalDateTime(from: LocalDateTime): Pair<Int, Int>? {
|
||||
val toIdx = lessons
|
||||
.map { it.time.start }
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,8 @@ fun PolytechnicApp() {
|
||||
val navController = rememberNavController()
|
||||
|
||||
NavHost(
|
||||
navController = navController, startDestination = "auth"
|
||||
navController = navController,
|
||||
startDestination = "auth"
|
||||
) {
|
||||
composable(route = "auth") {
|
||||
AuthScreen(navController)
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -147,7 +147,7 @@ private fun ExpandableCardArrow(
|
||||
Icon(
|
||||
modifier = Modifier.rotate(rotationDegree),
|
||||
imageVector = Icons.Filled.ArrowDropDown,
|
||||
contentDescription = "Expandable Arrow"
|
||||
contentDescription = "expandable arrow"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ fun GroupSelector(
|
||||
value = value ?: groups.getOrElse(1) { "TODO" }!!,
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Email,
|
||||
Icons.Filled.Email,
|
||||
contentDescription = "group"
|
||||
)
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<Long> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,6 @@ class LinkUpdateWorker(context: Context, params: WorkerParameters) :
|
||||
.getGroup()
|
||||
}
|
||||
|
||||
// CurrentLessonViewService.startService(applicationContext)
|
||||
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user