diff --git a/.idea/appInsightsSettings.xml b/.idea/appInsightsSettings.xml
index cecc928..cb7184b 100644
--- a/.idea/appInsightsSettings.xml
+++ b/.idea/appInsightsSettings.xml
@@ -15,27 +15,8 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 6367d4f..26cf3bc 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -33,13 +33,14 @@ android {
applicationId = "ru.n08i40k.polytechnic.next"
minSdk = 26
targetSdk = 35
- versionCode = 15
- versionName = "1.8.0"
+ versionCode = 16
+ versionName = "2.0.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
+ versionNameSuffix = "prod"
}
buildTypes {
@@ -112,7 +113,10 @@ dependencies {
implementation(libs.accompanist.swiperefresh)
+ // json
implementation(libs.kotlinx.serialization.json)
+ implementation(libs.kotlinx.datetime)
+
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
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 e255faa..15a767b 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/PolytechnicApplication.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/PolytechnicApplication.kt
@@ -12,7 +12,6 @@ import javax.inject.Inject
@HiltAndroidApp
class PolytechnicApplication : Application() {
- @Suppress("unused")
@Inject
lateinit var container: AppContainer
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/data/schedule/impl/FakeScheduleRepository.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/data/schedule/impl/FakeScheduleRepository.kt
index 2f678fc..e063068 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/data/schedule/impl/FakeScheduleRepository.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/data/schedule/impl/FakeScheduleRepository.kt
@@ -4,6 +4,10 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.withContext
+import kotlinx.datetime.Instant
+import kotlinx.datetime.LocalDateTime
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toInstant
import ru.n08i40k.polytechnic.next.data.MyResult
import ru.n08i40k.polytechnic.next.data.schedule.ScheduleRepository
import ru.n08i40k.polytechnic.next.model.Day
@@ -11,6 +15,25 @@ import ru.n08i40k.polytechnic.next.model.Group
import ru.n08i40k.polytechnic.next.model.Lesson
import ru.n08i40k.polytechnic.next.model.LessonTime
import ru.n08i40k.polytechnic.next.model.LessonType
+import ru.n08i40k.polytechnic.next.model.SubGroup
+import ru.n08i40k.polytechnic.next.utils.now
+
+private fun genLocalDateTime(hour: Int, minute: Int): Instant {
+ return LocalDateTime(2024, 1, 1, hour, minute, 0, 0).toInstant(TimeZone.currentSystemDefault())
+}
+
+private fun genBreak(start: Instant, end: Instant): Lesson {
+ return Lesson(
+ type = LessonType.BREAK,
+ defaultRange = null,
+ name = null,
+ time = LessonTime(
+ start,
+ end
+ ),
+ subGroups = listOf()
+ )
+}
class FakeScheduleRepository : ScheduleRepository {
@Suppress("SpellCheckingInspection")
@@ -19,132 +42,102 @@ class FakeScheduleRepository : ScheduleRepository {
name = "ИС-214/23", days = arrayListOf(
Day(
name = "Понедельник",
- nonNullIndices = arrayListOf(0, 1, 2, 3, 4, 5),
- defaultIndices = arrayListOf(2, 3, 4, 5),
- customIndices = arrayListOf(0, 1),
- lessons = arrayListOf(
+ date = LocalDateTime.now().toInstant(TimeZone.currentSystemDefault()),
+ lessons = listOf(
Lesson(
- type = LessonType.CUSTOM,
- defaultIndex = -1,
+ type = LessonType.ADDITIONAL,
+ defaultRange = null,
name = "Линейка",
- time = LessonTime(510, 520),
- cabinets = arrayListOf(),
- teacherNames = arrayListOf(),
+ time = LessonTime(
+ genLocalDateTime(8, 30),
+ genLocalDateTime(8, 40),
+ ),
+ subGroups = listOf()
+ ),
+ genBreak(
+ genLocalDateTime(8, 40),
+ genLocalDateTime(8, 45),
),
Lesson(
- type = LessonType.CUSTOM,
- defaultIndex = -1,
+ type = LessonType.ADDITIONAL,
+ defaultRange = null,
name = "Разговор о важном",
- time = LessonTime(525, 555),
- cabinets = arrayListOf(),
- teacherNames = arrayListOf(),
+ time = LessonTime(
+ genLocalDateTime(8, 45),
+ genLocalDateTime(9, 15),
+ ),
+ subGroups = listOf()
+ ),
+ genBreak(
+ genLocalDateTime(9, 15),
+ genLocalDateTime(9, 25),
),
Lesson(
type = LessonType.DEFAULT,
- defaultIndex = 1,
- name = "Элементы высшей математики",
- time = LessonTime(565, 645),
- cabinets = arrayListOf("31", "12"),
- teacherNames = arrayListOf("Цацаева Т.Н."),
- ),
- Lesson(
- type = LessonType.DEFAULT,
- defaultIndex = 2,
- name = "Операционные системы и среды",
- time = LessonTime(655, 735),
- cabinets = arrayListOf("42", "52"),
- teacherNames = arrayListOf("Сергачева А.О.", "Не Сергачева А.О."),
- ),
- Lesson(
- type = LessonType.DEFAULT,
- defaultIndex = 3,
- name = "Физическая культура",
- time = LessonTime(755, 835),
- cabinets = arrayListOf("c/3"),
- teacherNames = arrayListOf("Васюнин В.Г.", "Не Васюнин В.Г."),
- ),
- Lesson(
- type = LessonType.DEFAULT,
- defaultIndex = 4,
+ defaultRange = listOf(1, 1),
name = "МДК.05.01 Проектирование и дизайн информационных систем",
- time = LessonTime(845, 925),
- cabinets = arrayListOf("43"),
- teacherNames = arrayListOf("Ивашова А.Н."),
+ time = LessonTime(
+ genLocalDateTime(9, 25),
+ genLocalDateTime(10, 45),
+ ),
+ subGroups = listOf(
+ SubGroup(
+ teacher = "Ивашова А.Н.",
+ number = 1,
+ cabinet = "43"
+ )
+ )
),
- null,
- null,
- )
- ), Day(
- name = "Вторник",
- nonNullIndices = arrayListOf(0, 1, 2),
- defaultIndices = arrayListOf(0, 1, 2),
- customIndices = arrayListOf(),
- lessons = arrayListOf(
- Lesson(
- type = LessonType.DEFAULT,
- defaultIndex = 1,
- name = "Стандартизация, сертификация и техническое документоведение",
- time = LessonTime(525, 605),
- cabinets = arrayListOf("42"),
- teacherNames = arrayListOf("Сергачева А.О."),
+ genBreak(
+ genLocalDateTime(10, 45),
+ genLocalDateTime(10, 55),
),
Lesson(
type = LessonType.DEFAULT,
- defaultIndex = 2,
- name = "Элементы высшей математики",
- time = LessonTime(620, 700),
- cabinets = arrayListOf("31"),
- teacherNames = arrayListOf("Цацаева Т.Н."),
- ),
- Lesson(
- type = LessonType.DEFAULT,
- defaultIndex = 3,
+ defaultRange = listOf(2, 2),
name = "Основы проектирования баз данных",
- time = LessonTime(720, 800),
- cabinets = arrayListOf("21"),
- teacherNames = arrayListOf("Чинарева Е.А."),
+ time = LessonTime(
+ genLocalDateTime(10, 55),
+ genLocalDateTime(12, 15),
+ ),
+ subGroups = listOf(
+ SubGroup(
+ teacher = "Чинарева Е.А.",
+ number = 1,
+ cabinet = "21"
+ ),
+ SubGroup(
+ teacher = "Ивашова А.Н.",
+ number = 2,
+ cabinet = "44"
+ ),
+ )
+ ),
+ genBreak(
+ genLocalDateTime(12, 15),
+ genLocalDateTime(12, 35),
),
- null,
- null,
- null,
- null,
- null,
- )
- ), Day(
- name = "Среда",
- nonNullIndices = arrayListOf(0, 1, 2),
- defaultIndices = arrayListOf(0, 1, 2),
- customIndices = arrayListOf(),
- lessons = arrayListOf(
Lesson(
type = LessonType.DEFAULT,
- defaultIndex = 1,
+ defaultRange = listOf(3, 3),
name = "Операционные системы и среды",
- time = LessonTime(525, 605),
- cabinets = arrayListOf("42"),
- teacherNames = arrayListOf("Сергачева А.О."),
+ time = LessonTime(
+ genLocalDateTime(12, 35),
+ genLocalDateTime(13, 55),
+ ),
+ subGroups = listOf(
+ SubGroup(
+ teacher = "Сергачева А.О.",
+ number = 1,
+ cabinet = "42"
+ ),
+ SubGroup(
+ teacher = "Воронцева Н.В.",
+ number = 2,
+ cabinet = "41"
+ ),
+ )
),
- Lesson(
- type = LessonType.DEFAULT,
- defaultIndex = 2,
- name = "Элементы высшей математики",
- time = LessonTime(620, 700),
- cabinets = arrayListOf("31"),
- teacherNames = arrayListOf("Цацаева Т.Н."),
- ),
- Lesson(
- type = LessonType.DEFAULT,
- defaultIndex = 3,
- name = "МДК.05.01 Проектирование и дизайн информационных систем",
- time = LessonTime(720, 800),
- cabinets = arrayListOf("43"),
- teacherNames = arrayListOf("Ивашова А.Н."),
- ),
- null,
- null,
- null,
- null,
- null,
)
)
)
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/data/users/impl/FakeProfileRepository.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/data/users/impl/FakeProfileRepository.kt
index fb8f920..cf03dfe 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/data/users/impl/FakeProfileRepository.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/data/users/impl/FakeProfileRepository.kt
@@ -13,7 +13,13 @@ class FakeProfileRepository : ProfileRepository {
companion object {
val exampleProfile =
- Profile("66db32d24030a07e02d974c5", "n08i40k", "ИС-214/23", UserRole.STUDENT)
+ Profile(
+ "66db32d24030a07e02d974c5",
+ "128735612876",
+ "n08i40k",
+ "ИС-214/23",
+ UserRole.STUDENT
+ )
}
override suspend fun getProfile(): MyResult {
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 b031ea9..9029ad6 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
@@ -1,30 +1,33 @@
package ru.n08i40k.polytechnic.next.model
import android.os.Parcelable
+import kotlinx.datetime.Instant
+import kotlinx.datetime.LocalDateTime
import kotlinx.parcelize.Parcelize
+import kotlinx.parcelize.RawValue
import kotlinx.serialization.Serializable
-import ru.n08i40k.polytechnic.next.utils.getDayMinutes
-import java.util.Calendar
+import ru.n08i40k.polytechnic.next.utils.dateTime
+import ru.n08i40k.polytechnic.next.utils.dayMinutes
+import ru.n08i40k.polytechnic.next.utils.now
+
@Parcelize
@Suppress("unused", "MemberVisibilityCanBePrivate")
@Serializable
class Day(
val name: String,
- val nonNullIndices: ArrayList,
- val defaultIndices: ArrayList,
- val customIndices: ArrayList,
- val lessons: ArrayList
+ val date: @RawValue Instant,
+ val lessons: List
) : Parcelable {
- fun distanceToNextByMinutes(from: Int): Pair? {
+ fun distanceToNextByLocalDateTime(from: LocalDateTime): Pair? {
val toIdx = lessons
- .map { if (it?.time == null) null else it.time.start }
- .indexOfFirst { if (it == null) false else it > from }
+ .map { it.time.start }
+ .indexOfFirst { it.dateTime > from }
if (toIdx == -1)
return null
- return Pair(toIdx, lessons[toIdx]!!.time.start - from)
+ return Pair(toIdx, lessons[toIdx].time.start.dayMinutes - from.dayMinutes)
}
fun distanceToNextByIdx(from: Int? = null): Pair? {
@@ -35,24 +38,22 @@ class Day(
val fromTime =
if (from != null)
- fromLesson!!.time.end
+ fromLesson!!.time.end.dateTime
else
- Calendar.getInstance()
- .get(Calendar.HOUR_OF_DAY) * 60 + Calendar.getInstance()
- .get(Calendar.MINUTE)
+ LocalDateTime.now()
- return distanceToNextByMinutes(fromTime)
+ return distanceToNextByLocalDateTime(fromTime)
}
// current
val currentIdx: Int?
get() {
- val minutes = Calendar.getInstance().getDayMinutes()
+ val now = LocalDateTime.now()
- for (lessonIdx in nonNullIndices) {
- val lesson = lessons[lessonIdx]!!
+ for (lessonIdx in lessons.indices) {
+ val lesson = lessons[lessonIdx]
- if (lesson.time.start <= minutes && minutes < lesson.time.end)
+ if (lesson.time.start.dateTime <= now && now < lesson.time.end.dateTime)
return lessonIdx
}
@@ -67,36 +68,36 @@ class Day(
val currentKV: Pair?
get() {
val idx = currentIdx ?: return null
- return Pair(idx, lessons[idx]!!)
+ return Pair(idx, lessons[idx])
}
// first
val firstIdx: Int?
- get() = nonNullIndices.getOrNull(0)
+ get() = if (lessons.isEmpty()) null else 0
val first: Lesson?
get() {
- return lessons[firstIdx ?: return null]!!
+ return lessons[firstIdx ?: return null]
}
val firstKV: Pair?
get() {
val idx = firstIdx ?: return null
- return Pair(idx, lessons[idx]!!)
+ return Pair(idx, lessons[idx])
}
// last
val lastIdx: Int?
- get() = nonNullIndices.getOrNull(nonNullIndices.size - 1)
+ get() = if (lessons.isEmpty()) null else lessons.size - 1
val last: Lesson?
get() {
- return lessons[lastIdx ?: return null]!!
+ return lessons[lastIdx ?: return null]
}
val lastKV: Pair?
get() {
val idx = lastIdx ?: return null
- return Pair(idx, lessons[idx]!!)
+ return Pair(idx, lessons[idx])
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/model/Group.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/model/Group.kt
index 9594035..0e6a42b 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/model/Group.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/model/Group.kt
@@ -10,7 +10,7 @@ import java.util.Calendar
@Serializable
data class Group(
val name: String,
- val days: ArrayList
+ val days: List
) : Parcelable {
val currentIdx: Int?
get() {
@@ -27,7 +27,7 @@ data class Group(
return days.getOrNull(currentIdx ?: return null)
}
- val currentKV: Pair?
+ val currentKV: Pair?
get() {
val idx = currentIdx ?: return null
return Pair(idx, days[idx])
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/model/Lesson.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/model/Lesson.kt
index 3237c38..afbdd2f 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/model/Lesson.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/model/Lesson.kt
@@ -5,26 +5,30 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import ru.n08i40k.polytechnic.next.R
+import ru.n08i40k.polytechnic.next.utils.dayMinutes
import ru.n08i40k.polytechnic.next.utils.limit
@Parcelize
@Serializable
data class Lesson(
val type: LessonType,
- val defaultIndex: Int,
- val name: String,
+ val defaultRange: List?,
+ val name: String?,
val time: LessonTime,
- val cabinets: ArrayList,
- val teacherNames: ArrayList
+ val subGroups: List
) : Parcelable {
val duration: Int
get() {
- return time.end - time.start
+ val startMinutes = time.start.dayMinutes
+ val endMinutes = time.end.dayMinutes
+
+ return endMinutes - startMinutes
}
fun getNameAndCabinetsShort(context: Context): String {
- val limitedName = name limit 15
+ val limitedName = name!! limit 15
+ val cabinets = subGroups.map { it.cabinet }
if (cabinets.isEmpty())
return limitedName
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 e3513b5..458e386 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
@@ -1,9 +1,24 @@
package ru.n08i40k.polytechnic.next.model
import android.os.Parcelable
+import kotlinx.datetime.Instant
+import kotlinx.datetime.LocalDateTime
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toInstant
import kotlinx.parcelize.Parcelize
+import kotlinx.parcelize.RawValue
import kotlinx.serialization.Serializable
@Parcelize
@Serializable
-data class LessonTime(val start: Int, val end: Int) : Parcelable
\ No newline at end of file
+data class LessonTime(
+ val start: @RawValue Instant,
+ val end: @RawValue Instant
+) : Parcelable {
+ companion object {
+ fun fromLocalDateTime(start: LocalDateTime, end: LocalDateTime): LessonTime {
+ val timeZone = TimeZone.currentSystemDefault()
+ 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/model/LessonType.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/model/LessonType.kt
index 9af9e4d..ffc06cf 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/model/LessonType.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/model/LessonType.kt
@@ -11,5 +11,7 @@ private class LessonTypeIntSerializer : EnumAsIntSerializer(
@Serializable(with = LessonTypeIntSerializer::class)
enum class LessonType(val value: Int) {
- DEFAULT(0), CUSTOM(1)
+ DEFAULT(0),
+ ADDITIONAL(1),
+ BREAK(2)
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/model/Profile.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/model/Profile.kt
index cff0dbf..f34eb01 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/model/Profile.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/model/Profile.kt
@@ -5,6 +5,7 @@ import kotlinx.serialization.Serializable
@Serializable
data class Profile(
val id: String,
+ val accessToken: String,
val username: String,
val group: String,
val role: UserRole
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/model/SubGroup.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/model/SubGroup.kt
new file mode 100644
index 0000000..75368ad
--- /dev/null
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/model/SubGroup.kt
@@ -0,0 +1,13 @@
+package ru.n08i40k.polytechnic.next.model
+
+import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
+import kotlinx.serialization.Serializable
+
+@Parcelize
+@Serializable
+data class SubGroup(
+ val number: Int,
+ val cabinet: String,
+ val teacher: String
+) : Parcelable
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/NetworkValues.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/NetworkValues.kt
index c22dd08..9fd2884 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/NetworkValues.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/NetworkValues.kt
@@ -1,5 +1,5 @@
package ru.n08i40k.polytechnic.next.network
object NetworkValues {
- const val API_HOST = "https://polytechnic.n08i40k.ru:5050/api/v1/"
+ const val API_HOST = "https://192.168.0.103:5050/api/"
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/CachedRequest.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/CachedRequest.kt
index 6e88d97..1bce6a2 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/CachedRequest.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/CachedRequest.kt
@@ -16,8 +16,7 @@ import ru.n08i40k.polytechnic.next.network.request.schedule.ScheduleUpdate
import ru.n08i40k.polytechnic.next.network.tryFuture
import ru.n08i40k.polytechnic.next.network.tryGet
import java.util.logging.Logger
-import kotlin.io.encoding.Base64
-import kotlin.io.encoding.ExperimentalEncodingApi
+import java.util.regex.Pattern
open class CachedRequest(
context: Context,
@@ -34,36 +33,43 @@ open class CachedRequest(
}, errorListener) {
private val appContainer: AppContainer = (context as PolytechnicApplication).container
- @OptIn(ExperimentalEncodingApi::class)
- suspend fun getMainPage(): MyResult {
- return withContext(Dispatchers.IO) {
- val mainPageFuture = RequestFuture.newFuture()
- val request = StringRequest(
- Method.GET,
- "https://politehnikum-eng.ru/index/raspisanie_zanjatij/0-409",
- mainPageFuture,
- mainPageFuture
- )
- NetworkConnection.getInstance(context).addToRequestQueue(request)
-
- when (val response = tryGet(mainPageFuture)) {
- is MyResult.Failure -> response
- is MyResult.Success -> {
- val encodedMainPage = Base64.Default.encode(response.data.encodeToByteArray())
- MyResult.Success(encodedMainPage)
- }
- }
- }
+ companion object {
+ private const val REGEX: String = ""
+ val pattern: Pattern = Pattern.compile(REGEX, Pattern.MULTILINE)
}
+ private suspend fun getXlsUrl(): MyResult = withContext(Dispatchers.IO) {
+ val mainPageFuture = RequestFuture.newFuture()
+ val request = StringRequest(
+ Method.GET,
+ "https://politehnikum-eng.ru/index/raspisanie_zanjatij/0-409",
+ mainPageFuture,
+ mainPageFuture
+ )
+ NetworkConnection.getInstance(context).addToRequestQueue(request)
+
+ val response = tryGet(mainPageFuture)
+ if (response is MyResult.Failure)
+ return@withContext response
+
+ val pageData = (response as MyResult.Success).data
+
+ val matcher = pattern.matcher(pageData)
+ if (!matcher.find())
+ return@withContext MyResult.Failure(RuntimeException("Required url not found!"))
+
+ MyResult.Success("https://politehnikum-eng.ru" + matcher.group(1))
+ }
+
+
private suspend fun updateMainPage(): MyResult {
return withContext(Dispatchers.IO) {
- when (val mainPage = getMainPage()) {
- is MyResult.Failure -> mainPage
+ when (val xlsUrl = getXlsUrl()) {
+ is MyResult.Failure -> xlsUrl
is MyResult.Success -> {
tryFuture {
ScheduleUpdate(
- ScheduleUpdate.RequestDto(mainPage.data),
+ ScheduleUpdate.RequestDto(xlsUrl.data),
context,
it,
it
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthChangePassword.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthChangePassword.kt
index 88f4bf3..73029fd 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthChangePassword.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthChangePassword.kt
@@ -15,7 +15,7 @@ class AuthChangePassword(
) : AuthorizedRequest(
context,
Method.POST,
- "auth/change-password",
+ "v1/auth/change-password",
{ listener.onResponse(null) },
errorListener,
canBeUnauthorized = true
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthSignIn.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthSignIn.kt
index 4c03021..3469e30 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthSignIn.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthSignIn.kt
@@ -5,34 +5,25 @@ import com.android.volley.Response
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
+import ru.n08i40k.polytechnic.next.model.Profile
import ru.n08i40k.polytechnic.next.network.RequestBase
class AuthSignIn(
private val data: RequestDto,
context: Context,
- listener: Response.Listener,
+ listener: Response.Listener,
errorListener: Response.ErrorListener?
) : RequestBase(
context,
Method.POST,
- "auth/sign-in",
+ "v2/auth/sign-in",
{ listener.onResponse(Json.decodeFromString(it)) },
errorListener
) {
@Serializable
data class RequestDto(val username: String, val password: String)
- @Serializable
- data class ResponseDto(val id: String, val accessToken: String, val group: String)
-
override fun getBody(): ByteArray {
return Json.encodeToString(data).toByteArray()
}
-
- override fun getHeaders(): MutableMap {
- val headers = super.getHeaders()
- headers["version"] = "2"
-
- return headers
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthSignUp.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthSignUp.kt
index ee01ee7..edc3382 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthSignUp.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/auth/AuthSignUp.kt
@@ -5,18 +5,19 @@ import com.android.volley.Response
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
+import ru.n08i40k.polytechnic.next.model.Profile
import ru.n08i40k.polytechnic.next.model.UserRole
import ru.n08i40k.polytechnic.next.network.RequestBase
class AuthSignUp(
private val data: RequestDto,
context: Context,
- listener: Response.Listener,
+ listener: Response.Listener,
errorListener: Response.ErrorListener?
) : RequestBase(
context,
Method.POST,
- "auth/sign-up",
+ "v2/auth/sign-up",
{ listener.onResponse(Json.decodeFromString(it)) },
errorListener
) {
@@ -28,9 +29,6 @@ class AuthSignUp(
val role: UserRole
)
- @Serializable
- data class ResponseDto(val id: String, val accessToken: String)
-
override fun getBody(): ByteArray {
return Json.encodeToString(data).toByteArray()
}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/fcm/FcmSetToken.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/fcm/FcmSetToken.kt
index 684a7b2..5b5bfac 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/fcm/FcmSetToken.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/fcm/FcmSetToken.kt
@@ -11,7 +11,7 @@ class FcmSetToken(
errorListener: Response.ErrorListener?,
) : AuthorizedRequest(
context, Method.POST,
- "fcm/set-token/$token",
+ "v1/fcm/set-token/$token",
{ listener.onResponse(Unit) },
errorListener,
true
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/fcm/FcmUpdateCallback.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/fcm/FcmUpdateCallback.kt
index aefdb45..9d11699 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/fcm/FcmUpdateCallback.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/fcm/FcmUpdateCallback.kt
@@ -11,7 +11,7 @@ class FcmUpdateCallback(
errorListener: Response.ErrorListener?,
) : AuthorizedRequest(
context, Method.POST,
- "fcm/update-callback/$version",
+ "v1/fcm/update-callback/$version",
{ listener.onResponse(Unit) },
errorListener,
true
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileChangeGroup.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileChangeGroup.kt
index 6b3cd45..851a49c 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileChangeGroup.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileChangeGroup.kt
@@ -15,7 +15,7 @@ class ProfileChangeGroup(
) : AuthorizedRequest(
context,
Method.POST,
- "users/change-group",
+ "v1/users/change-group",
{ listener.onResponse(null) },
errorListener
) {
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileChangeUsername.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileChangeUsername.kt
index d32c79c..3cd81a0 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileChangeUsername.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileChangeUsername.kt
@@ -15,7 +15,7 @@ class ProfileChangeUsername(
) : AuthorizedRequest(
context,
Method.POST,
- "users/change-username",
+ "v1/users/change-username",
{ listener.onResponse(null) },
errorListener
) {
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileMe.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileMe.kt
index 766f904..03ce8d4 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileMe.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/profile/ProfileMe.kt
@@ -13,7 +13,7 @@ class ProfileMe(
) : AuthorizedRequest(
context,
Method.GET,
- "users/me",
+ "v2/users/me",
{ listener.onResponse(Json.decodeFromString(it)) },
errorListener
)
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGet.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGet.kt
index c6619d4..2954e58 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGet.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGet.kt
@@ -13,8 +13,8 @@ class ScheduleGet(
errorListener: Response.ErrorListener? = null
) : CachedRequest(
context,
- Method.POST,
- "schedule/get-group",
+ Method.GET,
+ "v2/schedule/group",
{ listener.onResponse(Json.decodeFromString(it)) },
errorListener
) {
@@ -25,6 +25,6 @@ class ScheduleGet(
data class ResponseDto(
val updatedAt: String,
val group: Group,
- val lastChangedDays: ArrayList,
+ val updated: ArrayList,
)
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGetCacheStatus.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGetCacheStatus.kt
index c06fdee..a15db8e 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGetCacheStatus.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGetCacheStatus.kt
@@ -13,7 +13,7 @@ class ScheduleGetCacheStatus(
) : AuthorizedRequest(
context,
Method.GET,
- "schedule/cache-status",
+ "v2/schedule/cache-status",
{ listener.onResponse(Json.decodeFromString(it)) },
errorListener
) {
@@ -24,11 +24,4 @@ class ScheduleGetCacheStatus(
val lastCacheUpdate: Long,
val lastScheduleUpdate: Long,
)
-
- override fun getHeaders(): MutableMap {
- val headers = super.getHeaders()
- headers["version"] = "1"
-
- return headers
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGetGroupNames.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGetGroupNames.kt
index 5cbf15e..e4b28f7 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGetGroupNames.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleGetGroupNames.kt
@@ -13,7 +13,7 @@ class ScheduleGetGroupNames(
) : RequestBase(
context,
Method.GET,
- "schedule/get-group-names",
+ "v2/schedule/group-names",
{ listener.onResponse(Json.decodeFromString(it)) },
errorListener
) {
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleUpdate.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleUpdate.kt
index e6ea89c..22dae1a 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleUpdate.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/schedule/ScheduleUpdate.kt
@@ -14,22 +14,13 @@ class ScheduleUpdate(
errorListener: Response.ErrorListener? = null
) : AuthorizedRequest(
context,
- Method.POST,
- "schedule/update-site-main-page",
+ Method.PATCH,
+ "v2/schedule/update-download-url",
{ listener.onResponse(Json.decodeFromString(it)) },
errorListener
) {
@Serializable
- data class RequestDto(val mainPage: String)
+ data class RequestDto(val url: String)
- override fun getBody(): ByteArray {
- return Json.encodeToString(data).toByteArray()
- }
-
- override fun getHeaders(): MutableMap {
- val headers = super.getHeaders()
- headers["version"] = "1"
-
- return headers
- }
-}
\ No newline at end of file
+ override fun getBody(): ByteArray = Json.encodeToString(data).toByteArray()
+}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerClear.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerClear.kt
index 0079532..26a8d9f 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerClear.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerClear.kt
@@ -13,7 +13,7 @@ class ScheduleReplacerClear(
) : AuthorizedRequest(
context,
Method.POST,
- "schedule-replacer/clear",
+ "v1/schedule-replacer/clear",
{ listener.onResponse(Json.decodeFromString(it)) },
errorListener
) {
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerGet.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerGet.kt
index 7796deb..1180068 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerGet.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerGet.kt
@@ -13,7 +13,7 @@ class ScheduleReplacerGet(
) : AuthorizedRequest(
context,
Method.GET,
- "schedule-replacer/get",
+ "v1/schedule-replacer/get",
{ listener.onResponse(Json.decodeFromString(it)) },
errorListener
)
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerSet.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerSet.kt
index 5bbf5f7..e3216a3 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerSet.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/scheduleReplacer/ScheduleReplacerSet.kt
@@ -14,7 +14,7 @@ class ScheduleReplacerSet(
) : AuthorizedMultipartRequest(
context,
Method.POST,
- "schedule-replacer/set",
+ "v1/schedule-replacer/set",
{ listener.onResponse(null) },
errorListener
) {
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/service/CurrentLessonViewService.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/service/CurrentLessonViewService.kt
index 56aa1f2..92ef359 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/service/CurrentLessonViewService.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/service/CurrentLessonViewService.kt
@@ -10,6 +10,7 @@ import android.os.IBinder
import android.os.Looper
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat.startForegroundService
+import kotlinx.datetime.LocalDateTime
import ru.n08i40k.polytechnic.next.NotificationChannels
import ru.n08i40k.polytechnic.next.PolytechnicApplication
import ru.n08i40k.polytechnic.next.R
@@ -17,6 +18,7 @@ import ru.n08i40k.polytechnic.next.data.MyResult
import ru.n08i40k.polytechnic.next.model.Day
import ru.n08i40k.polytechnic.next.model.Group
import ru.n08i40k.polytechnic.next.model.Lesson
+import ru.n08i40k.polytechnic.next.utils.dayMinutes
import ru.n08i40k.polytechnic.next.utils.fmtAsClock
import ru.n08i40k.polytechnic.next.utils.getDayMinutes
import java.util.Calendar
@@ -64,7 +66,7 @@ class CurrentLessonViewService : Service() {
override fun run() {
val logger = Logger.getLogger("CLV.updateRunnable")
- if (day == null || day!!.nonNullIndices.isEmpty()) {
+ if (day == null || day!!.lessons.isEmpty()) {
logger.warning("Stopping, because day is null or empty!")
stopSelf()
return
@@ -99,15 +101,16 @@ class CurrentLessonViewService : Service() {
return
}
- val firstLessonIdx = day!!.distanceToNextByMinutes(0)?.first
- ?: throw NullPointerException("Is this even real?")
- val distanceToFirst = day!!.lessons[firstLessonIdx]!!.time!!.start - currentMinutes
+ val firstLessonIdx =
+ day!!.distanceToNextByLocalDateTime(LocalDateTime(0, 0, 0, 0, 0))?.first
+ ?: throw NullPointerException("Is this even real?")
+ val distanceToFirst = day!!.lessons[firstLessonIdx]!!.time!!.start.dayMinutes - currentMinutes
val currentLessonDelay =
if (currentLesson == null) // Если эта пара - перемена, то конец перемены через (результат getDistanceToNext)
nextLessonEntry!!.second
else // Если эта пара - обычная пара, то конец пары через (конец этой пары - текущее кол-во минут)
- currentLesson.time!!.end - currentMinutes
+ currentLesson.time!!.end.dayMinutes - currentMinutes
val currentLessonName =
currentLesson?.getNameAndCabinetsShort(this@CurrentLessonViewService)
@@ -144,7 +147,7 @@ class CurrentLessonViewService : Service() {
getString(
R.string.lesson_going_notification_description,
currentLessonName,
- nextLessonTotal.fmtAsClock(),
+ nextLessonTotal.dayMinutes.fmtAsClock(),
nextLessonName,
)
)
@@ -183,7 +186,7 @@ class CurrentLessonViewService : Service() {
}
val currentDay = group.current
- if (currentDay == null || currentDay.nonNullIndices.isEmpty()) {
+ if (currentDay == null || currentDay.lessons.isEmpty()) {
logger.warning("Stopping, because current day is null or empty")
stopSelf()
return
@@ -191,7 +194,7 @@ class CurrentLessonViewService : Service() {
val nowMinutes = Calendar.getInstance().getDayMinutes()
if (nowMinutes < ((5 * 60) + 30)
- || currentDay.last!!.time.end < nowMinutes
+ || currentDay.last!!.time.end.dayMinutes < nowMinutes
) {
logger.warning("Stopping, because service started outside of acceptable time range!")
stopSelf()
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/service/MyFirebaseMessagingService.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/service/MyFirebaseMessagingService.kt
index 1e5bc52..36d9f26 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/service/MyFirebaseMessagingService.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/service/MyFirebaseMessagingService.kt
@@ -28,7 +28,7 @@ import ru.n08i40k.polytechnic.next.work.FcmSetTokenWorker
import java.time.Duration
class MyFirebaseMessagingService : FirebaseMessagingService() {
- val scope = CoroutineScope(Job() + Dispatchers.Main)
+ private val scope = CoroutineScope(Job() + Dispatchers.Main)
override fun onNewToken(token: String) {
super.onNewToken(token)
@@ -53,7 +53,6 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
@DrawableRes iconId: Int,
title: String,
contentText: String,
- priority: Int,
id: Any?,
intent: Intent? = null
) {
@@ -70,7 +69,7 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
.setSmallIcon(iconId)
.setContentTitle(title)
.setContentText(contentText)
- .setPriority(priority)
+ .setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.build()
@@ -103,7 +102,6 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
else
R.string.schedule_update_default
),
- NotificationCompat.PRIORITY_DEFAULT,
message.data["etag"]
)
}
@@ -121,7 +119,6 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
R.drawable.download,
getString(R.string.app_update_title, message.data["version"]),
getString(R.string.app_update_description),
- NotificationCompat.PRIORITY_DEFAULT,
message.data["version"],
Intent(Intent.ACTION_VIEW, Uri.parse(message.data["downloadLink"]))
)
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/icons/appicons/filled/Download.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/icons/appicons/filled/Download.kt
index 2f21b4e..1700439 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/icons/appicons/filled/Download.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/icons/appicons/filled/Download.kt
@@ -29,7 +29,12 @@ val FilledGroup.Download: ImageVector
) {
moveTo(3.0f, 12.3f)
verticalLineToRelative(7.0f)
- arcToRelative(2.0f, 2.0f, 0.0f, false, false, 2.0f, 2.0f)
+ arcToRelative(2.0f, 2.0f, 0.0f,
+ isMoreThanHalf = false,
+ isPositiveArc = false,
+ dx1 = 2.0f,
+ dy1 = 2.0f
+ )
horizontalLineTo(19.0f)
arcToRelative(2.0f, 2.0f, 0.0f, false, false, 2.0f, -2.0f)
verticalLineToRelative(-7.0f)
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/DayCard.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/DayCard.kt
index f23d3b4..0759eb5 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/DayCard.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/DayCard.kt
@@ -2,14 +2,11 @@ package ru.n08i40k.polytechnic.next.ui.main.schedule
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
-import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.MaterialTheme
@@ -20,7 +17,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
@@ -56,7 +52,7 @@ private fun getCurrentLessonIdx(day: Day?): Flow {
fun DayCard(
modifier: Modifier = Modifier,
day: Day? = FakeScheduleRepository.exampleGroup.days[0],
- current: Boolean = true
+ distance: Int = 0
) {
val defaultCardColors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer,
@@ -75,7 +71,7 @@ fun DayCard(
modifier = modifier,
colors = CardDefaults.cardColors(
containerColor =
- if (current) MaterialTheme.colorScheme.primaryContainer
+ if (distance == 0) MaterialTheme.colorScheme.primaryContainer
else MaterialTheme.colorScheme.secondaryContainer
),
border = BorderStroke(1.dp, MaterialTheme.colorScheme.inverseSurface)
@@ -85,6 +81,7 @@ fun DayCard(
modifier = Modifier.fillMaxWidth(),
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
+ style = MaterialTheme.typography.titleLarge,
text = stringResource(R.string.day_null)
)
return@Card
@@ -96,66 +93,55 @@ fun DayCard(
text = day.name,
)
- val currentLessonIdx by getCurrentLessonIdx(if (current) day else null)
+ if (distance >= -1 && distance <= 1) {
+ Text(
+ modifier = Modifier.fillMaxWidth(),
+ fontWeight = FontWeight.Bold,
+ textAlign = TextAlign.Center,
+ style = MaterialTheme.typography.bodyMedium,
+ text = stringResource(when (distance) {
+ -1 -> R.string.yesterday
+ 0 -> R.string.today
+ 1 -> R.string.tommorow
+ else -> throw RuntimeException()
+ }),
+ )
+ }
+
+ val currentLessonIdx by getCurrentLessonIdx(if (distance == 0) day else null)
.collectAsStateWithLifecycle(0)
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(0.5.dp)
) {
- if (day.nonNullIndices.isEmpty()) {
+ if (day.lessons.isEmpty()) {
Text("Can't get schedule!")
return@Column
}
- for (i in day.nonNullIndices.first()..day.nonNullIndices.last()) {
- val lesson = day.lessons[i]!!
+ for (lessonIdx in day.lessons.indices) {
+ val lesson = day.lessons[lessonIdx]
val cardColors = when (lesson.type) {
LessonType.DEFAULT -> defaultCardColors
- LessonType.CUSTOM -> customCardColors
+ LessonType.ADDITIONAL -> customCardColors
+ LessonType.BREAK -> noneCardColors
}
val mutableExpanded = remember { mutableStateOf(false) }
- val lessonBoxModifier = remember {
+ Box(
Modifier
- .padding(PaddingValues(2.5.dp, 0.dp))
.clickable { mutableExpanded.value = true }
.background(cardColors.containerColor)
- }
-
- Box(
- modifier =
- if (i == currentLessonIdx) lessonBoxModifier.border(
- border = BorderStroke(
- 3.5.dp,
- Color(
- cardColors.containerColor.red * 0.5F,
- cardColors.containerColor.green * 0.5F,
- cardColors.containerColor.blue * 0.5F,
- 1F
- )
- )
- )
- else lessonBoxModifier
) {
- LessonRow(
- day, lesson, cardColors
- )
- }
- if (i != day.nonNullIndices.last()) {
- Box(
- modifier = Modifier
- .padding(PaddingValues(2.5.dp, 0.dp))
- .background(noneCardColors.containerColor)
- ) {
- FreeLessonRow(
- lesson,
- day.lessons[day.nonNullIndices[day.nonNullIndices.indexOf(i) + 1]]!!,
- noneCardColors
- )
- }
+ val now = lessonIdx == currentLessonIdx
+
+ if (lesson.type === LessonType.BREAK)
+ FreeLessonRow(lesson, lesson, cardColors, now)
+ else
+ LessonRow(day, lesson, cardColors, now)
}
if (mutableExpanded.value)
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 f614e06..3462b08 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
@@ -27,10 +27,10 @@ import java.util.logging.Level
import kotlin.math.absoluteValue
private fun isCurrentWeek(group: Group): Boolean {
- if (group.days.size == 0 || group.days[0] == null)
+ if (group.days.isEmpty())
return true
- val dateString = group.days[0]!!.name
+ val dateString = group.days[0].name
val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy", Locale("ru"))
val datePart = dateString.split(" ").getOrNull(1) ?: return true
@@ -49,10 +49,12 @@ private fun isCurrentWeek(group: Group): Boolean {
@Composable
fun DayPager(group: Group = FakeScheduleRepository.exampleGroup) {
val currentDay = (Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 2)
- val calendarDay = currentDay
- .coerceAtLeast(0)
- .coerceAtMost(group.days.size - 1)
- val pagerState = rememberPagerState(initialPage = calendarDay, pageCount = { group.days.size })
+ val calendarDay = if (currentDay == -1) 6 else currentDay
+
+ val pagerState = rememberPagerState(
+ initialPage = calendarDay
+ .coerceAtMost(group.days.size - 1),
+ pageCount = { group.days.size })
Column {
if (!isCurrentWeek(group)) {
@@ -65,7 +67,9 @@ fun DayPager(group: Group = FakeScheduleRepository.exampleGroup) {
state = pagerState,
contentPadding = PaddingValues(horizontal = 20.dp),
verticalAlignment = Alignment.Top,
- modifier = Modifier.height(600.dp).padding(top = 5.dp)
+ modifier = Modifier
+ .height(600.dp)
+ .padding(top = 5.dp)
) { page ->
DayCard(
modifier = Modifier.graphicsLayer {
@@ -82,7 +86,7 @@ fun DayPager(group: Group = FakeScheduleRepository.exampleGroup) {
)
},
day = group.days[page],
- current = currentDay == page
+ distance = page - currentDay
)
}
}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/LessonView.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/LessonView.kt
index 182a680..a179df6 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/LessonView.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/main/schedule/LessonView.kt
@@ -1,12 +1,13 @@
package ru.n08i40k.polytechnic.next.ui.main.schedule
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material3.Card
import androidx.compose.material3.CardColors
@@ -26,11 +27,15 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
+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.Day
import ru.n08i40k.polytechnic.next.model.Lesson
import ru.n08i40k.polytechnic.next.model.LessonTime
+import ru.n08i40k.polytechnic.next.model.LessonType
+import ru.n08i40k.polytechnic.next.model.SubGroup
+import ru.n08i40k.polytechnic.next.utils.dayMinutes
import ru.n08i40k.polytechnic.next.utils.fmtAsClock
private enum class LessonTimeFormat {
@@ -58,28 +63,36 @@ private fun fmtTime(start: Int, end: Int, format: LessonTimeFormat): ArrayList = mutableStateOf(true)
) {
Dialog(onDismissRequest = { mutableExpanded.value = false }) {
+ if (lesson.type === LessonType.BREAK) {
+ mutableExpanded.value = false
+ return@Dialog
+ }
+
Card {
Column(Modifier.padding(10.dp)) {
- Text(lesson.name)
+ Text(lesson.name!!)
- if (lesson.teacherNames.isNotEmpty()) {
- val teachers = buildString {
- append(stringResource(if (lesson.teacherNames.count() > 1) R.string.lesson_teachers else R.string.lesson_teacher))
+ for (subGroup in lesson.subGroups) {
+ val subGroups = buildString {
+ append("[")
+ append(subGroup.number)
+ append("] ")
+ append(subGroup.teacher)
append(" - ")
- append(lesson.teacherNames.joinToString(", "))
+ append(subGroup.cabinet)
}
- Text(teachers)
+ Text(subGroups)
}
val duration = buildString {
append(stringResource(R.string.lesson_duration))
append(" - ")
val duration =
- lesson.time.end - lesson.time.start
+ lesson.time.end.dayMinutes - lesson.time.start.dayMinutes
append(duration / 60)
append(stringResource(R.string.hours))
@@ -88,15 +101,6 @@ fun LessonExtraInfo(
append(stringResource(R.string.minutes))
}
Text(duration)
-
- if (lesson.cabinets.isNotEmpty()) {
- val cabinets = buildString {
- append(stringResource(R.string.cabinets))
- append(" - ")
- append(lesson.cabinets.joinToString(", "))
- }
- Text(cabinets)
- }
}
}
}
@@ -105,47 +109,74 @@ fun LessonExtraInfo(
@Preview(showBackground = true)
@Composable
private fun LessonViewRow(
- idx: Int = 1,
- time: LessonTime? = LessonTime(0, 60),
+ range: List? = listOf(1, 3),
+ time: LessonTime = LessonTime.fromLocalDateTime(
+ LocalDateTime(2024, 1, 1, 0, 0),
+ LocalDateTime(2024, 1, 1, 1, 0),
+ ),
timeFormat: LessonTimeFormat = LessonTimeFormat.FROM_TO,
name: String = "Test",
- teacherNames: ArrayList = arrayListOf(
- "Хомченко Н.Е. (1 подggggggggggggggggggggggggggggggggggggggгруппа)",
- "Хомченко Н.Е. (2 подгруппа)"
- ),
- cabinets: ArrayList = arrayListOf("14", "31"),
+ subGroups: List = listOf(),
cardColors: CardColors = CardDefaults.cardColors(),
- verticalPadding: Dp = 10.dp
+ verticalPadding: Dp = 10.dp,
+ now: Boolean = true,
) {
val contentColor =
- if (timeFormat == LessonTimeFormat.FROM_TO) cardColors.contentColor else cardColors.disabledContentColor
+ if (timeFormat == LessonTimeFormat.FROM_TO) cardColors.contentColor
+ else cardColors.disabledContentColor
- val teacherNamesRepl = teacherNames.map { it.replace("подгруппа", "подгр.") }
+ val rangeSize = if (range == null) 1 else (range[1] - range[0] + 1) * 2
- Row(
- modifier = Modifier.padding(10.dp, verticalPadding),
- verticalAlignment = Alignment.CenterVertically,
+ Box(
+ if (now) Modifier.border(
+ BorderStroke(
+ 3.5.dp,
+ Color(
+ cardColors.containerColor.red * 0.5F,
+ cardColors.containerColor.green * 0.5F,
+ cardColors.containerColor.blue * 0.5F,
+ 1F
+ )
+ )
+ ) else Modifier
) {
- Text(
- text = if (idx == -1) "1" else idx.toString(),
- fontFamily = FontFamily.Monospace,
- fontWeight = FontWeight.Bold,
- color = if (idx == -1) Color(0) else contentColor
- )
+ Row(
+ modifier = Modifier.padding(10.dp, verticalPadding * rangeSize),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ val rangeString = run {
+ if (range == null)
+ " "
+ else
+ buildString {
+ val same = range[0] == range[1]
- Spacer(Modifier.width(7.5.dp))
-
- if (time != null) {
- val formattedTime: ArrayList = fmtTime(time.start, time.end, timeFormat)
+ append(if (same) " " else range[0])
+ append(if (same) range[0] else "-")
+ append(if (same) " " else range[1])
+ }
+ }
+ Text(
+ text = rangeString,
+ fontFamily = FontFamily.Monospace,
+ fontWeight = FontWeight.Bold,
+ color = contentColor
+ )
Column(
- modifier = Modifier.fillMaxWidth(0.25f),
+ modifier = Modifier.fillMaxWidth(0.20f),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
+ val formattedTime: ArrayList =
+ fmtTime(time.start.dayMinutes, time.end.dayMinutes, timeFormat)
+
Text(
- text = formattedTime[0], fontFamily = FontFamily.Monospace, color = contentColor
+ text = formattedTime[0],
+ fontFamily = FontFamily.Monospace,
+ color = contentColor
)
+
if (formattedTime.count() > 1) {
Text(
text = formattedTime[1],
@@ -154,54 +185,47 @@ private fun LessonViewRow(
)
}
}
- }
- Spacer(Modifier.width(7.5.dp))
-
- Column(
- verticalArrangement = Arrangement.Center
- ) {
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween
- ) {
- Column(modifier = Modifier.weight(1f)) {
- Text(
- text = name,
- fontWeight = FontWeight.Medium,
- maxLines = 1,
- overflow = TextOverflow.Ellipsis,
- color = contentColor
- )
-
- for (teacherName in teacherNamesRepl) {
+ Column(verticalArrangement = Arrangement.Center) {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Column(modifier = Modifier.weight(1f)) {
Text(
- text = teacherName,
+ text = name,
+ fontWeight = FontWeight.Medium,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = contentColor
)
+
+ for (subGroup in subGroups) {
+ Text(
+ text = subGroup.teacher,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ color = contentColor
+ )
+ }
+ }
+
+ Column(modifier = Modifier.wrapContentWidth()) {
+ if (subGroups.size != 1)
+ Text(text = "")
+ for (subGroup in subGroups) {
+ Text(
+ text = subGroup.cabinet,
+ maxLines = 1,
+ fontFamily = FontFamily.Monospace,
+ color = contentColor
+ )
+ }
}
}
- Column(modifier = Modifier.wrapContentWidth()) {
- if (cabinets.size <= teacherNamesRepl.size) {
- Text(
- text = "",
- maxLines = 1
- )
- }
- for (listIdx: Int in 0..= 10)
+ PaskhalkoDialog()
+
Column(
modifier = Modifier
.fillMaxWidth()
.padding(10.dp)
+ .clickable { ++paskhalkoCounter }
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/theme/Theme.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/theme/Theme.kt
index 00e0de7..9cda800 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/theme/Theme.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/theme/Theme.kt
@@ -323,7 +323,7 @@ fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
- content: @Composable() () -> Unit
+ content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/utils/Extensions.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/utils/Extensions.kt
index 5a8ae1a..936b10d 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/utils/Extensions.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/utils/Extensions.kt
@@ -1,5 +1,10 @@
package ru.n08i40k.polytechnic.next.utils
+import kotlinx.datetime.Clock
+import kotlinx.datetime.Instant
+import kotlinx.datetime.LocalDateTime
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toLocalDateTime
import java.util.Calendar
infix fun T?.or(data: T): T {
@@ -30,4 +35,18 @@ infix fun String.limit(count: Int): String {
}
fun Calendar.getDayMinutes(): Int =
- this.get(Calendar.HOUR_OF_DAY) * 60 + this.get(Calendar.MINUTE)
\ No newline at end of file
+ this.get(Calendar.HOUR_OF_DAY) * 60 + this.get(Calendar.MINUTE)
+
+val Instant.dayMinutes: Int
+ get() = this.toLocalDateTime(TimeZone.currentSystemDefault()).dayMinutes
+
+val LocalDateTime.dayMinutes: Int
+ get() = this.hour * 60 + this.minute
+
+val Instant.dateTime: LocalDateTime
+ get() = this.toLocalDateTime(TimeZone.currentSystemDefault())
+
+fun LocalDateTime.Companion.now(): LocalDateTime {
+ val clock = Clock.System.now()
+ return clock.toLocalDateTime(TimeZone.currentSystemDefault())
+}
\ 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 22decaf..571b0a7 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
@@ -5,7 +5,6 @@ import androidx.work.Worker
import androidx.work.WorkerParameters
import kotlinx.coroutines.runBlocking
import ru.n08i40k.polytechnic.next.PolytechnicApplication
-import ru.n08i40k.polytechnic.next.service.CurrentLessonViewService
class LinkUpdateWorker(context: Context, params: WorkerParameters) :
Worker(context, params) {
diff --git a/app/src/main/res/drawable-mdpi/paskhalko.jpg b/app/src/main/res/drawable-mdpi/paskhalko.jpg
new file mode 100644
index 0000000..6b00040
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/paskhalko.jpg differ
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index d856840..775e28d 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -73,4 +73,7 @@
Пользователь с таким именем уже зарегистрирован!
Группа с таким названием не существует!
Нет подключения к интернету!
+ Сегодня
+ Вчера
+ Завтра
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8f4dbff..3b802c4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -73,4 +73,7 @@
A user with this name is already registered!
A group with this name does not exist!
No internet connection!
+ Today
+ Yesterday
+ Tommorow
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 1f3678b..fda4145 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,6 +1,6 @@
[versions]
accompanistSwiperefresh = "0.36.0"
-agp = "8.7.0"
+agp = "8.7.1"
firebaseBom = "33.4.0"
hiltAndroid = "2.52"
hiltAndroidCompiler = "2.52"
@@ -12,12 +12,12 @@ junitVersion = "1.2.1"
espressoCore = "3.6.1"
kotlinxSerializationJson = "1.7.3"
lifecycleRuntimeKtx = "2.8.6"
-activityCompose = "1.9.2"
-composeBom = "2024.09.03"
+activityCompose = "1.9.3"
+composeBom = "2024.10.00"
protobufLite = "3.0.1"
volley = "1.2.1"
datastore = "1.1.1"
-navigationCompose = "2.8.2"
+navigationCompose = "2.8.3"
googleFirebaseCrashlytics = "3.0.2"
workRuntime = "2.9.1"
@@ -40,9 +40,10 @@ androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
-androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest", version = "1.7.3" }
+androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest", version = "1.7.4" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
+kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version = "0.6.1" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
protobuf-lite = { module = "com.google.protobuf:protobuf-lite", version.ref = "protobufLite" }
volley = { group = "com.android.volley", name = "volley", version.ref = "volley" }