diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index 18df225..a6e82c7 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -7,10 +7,10 @@
-
-
+
+
-
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index e7eb857..a591bae 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -46,8 +46,8 @@ android {
applicationId = "ru.n08i40k.polytechnic.next"
minSdk = 26
targetSdk = 35
- versionCode = 27
- versionName = "3.1.0"
+ versionCode = 28
+ versionName = "3.1.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
@@ -158,7 +158,7 @@ dependencies {
protobuf {
protoc {
- artifact = "com.google.protobuf:protoc:4.29.3"
+ artifact = "com.google.protobuf:protoc:21.0-rc-1"
}
plugins {
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/Application.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/Application.kt
index ae87950..47d1d36 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/Application.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/Application.kt
@@ -18,7 +18,8 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import ru.n08i40k.polytechnic.next.app.AppContainer
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
+import ru.n08i40k.polytechnic.next.proto.settings_v0
import ru.n08i40k.polytechnic.next.utils.Observable
import ru.n08i40k.polytechnic.next.worker.UpdateFCMTokenWorker
import ru.n08i40k.polytechnic.next.worker.UpdateLinkWorker
@@ -97,8 +98,35 @@ class Application : Application() {
override fun onCreate() {
super.onCreate()
+ runBlocking { fixupSettings() }
+
VKID.init(this)
setupFirebase()
}
+
+ private suspend fun fixupSettings() {
+ val accessToken = this.settings_v0.data.map { it.accessToken }.first()
+
+ if (accessToken.isEmpty())
+ return
+
+ val userId = this.settings_v0.data.map { it.userId }.first()
+ val group = this.settings_v0.data.map { it.group }.first()
+ val version = this.settings_v0.data.map { it.version }.first()
+ val fcmToken = this.settings_v0.data.map { it.fcmToken }.first()
+
+ this.settings.updateData {
+ it
+ .toBuilder()
+ .setUserId(userId)
+ .setAccessToken(accessToken)
+ .setGroup(group)
+ .setVersion(version)
+ .setFcmToken(fcmToken)
+ .build()
+ }
+
+ this.settings_v0.updateData { it.toBuilder().clear().build() }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/MainActivity.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/MainActivity.kt
index 9bf7ba2..24942c2 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/MainActivity.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/MainActivity.kt
@@ -22,7 +22,7 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import ru.n08i40k.polytechnic.next.app.NotificationChannels
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
import ru.n08i40k.polytechnic.next.ui.PolytechnicApp
import ru.n08i40k.polytechnic.next.ui.theme.AppTheme
import ru.n08i40k.polytechnic.next.utils.app
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 2d091da..5369cae 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,6 +5,7 @@ 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
@@ -17,6 +18,8 @@ data class Lesson(
val group: String? = null,
val subGroups: List
) : Parcelable {
+ val duration: Int get() = time.end.dayMinutes - time.start.dayMinutes
+
fun getShortName(context: Context): String {
val name =
if (type == LessonType.BREAK)
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/AuthorizedRequest.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/AuthorizedRequest.kt
index 9b4ed9f..0da64eb 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/AuthorizedRequest.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/network/request/AuthorizedRequest.kt
@@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import ru.n08i40k.polytechnic.next.app.AppContainer
import ru.n08i40k.polytechnic.next.network.RequestBase
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
open class AuthorizedRequest(
val appContainer: AppContainer,
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/proto/CacheSerializer.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/proto/CacheSerializer.kt
new file mode 100644
index 0000000..2555ddb
--- /dev/null
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/proto/CacheSerializer.kt
@@ -0,0 +1,29 @@
+package ru.n08i40k.polytechnic.next.proto
+
+import android.content.Context
+import androidx.datastore.core.CorruptionException
+import androidx.datastore.core.DataStore
+import androidx.datastore.core.Serializer
+import androidx.datastore.dataStore
+import com.google.protobuf.InvalidProtocolBufferException
+import ru.n08i40k.polytechnic.next.Cache
+import java.io.InputStream
+import java.io.OutputStream
+
+object CacheSerializer : Serializer {
+ override val defaultValue: Cache = Cache.getDefaultInstance()
+
+ override suspend fun readFrom(input: InputStream): Cache =
+ try {
+ Cache.parseFrom(input)
+ } catch (exception: InvalidProtocolBufferException) {
+ throw CorruptionException("Cannot read proto.", exception)
+ }
+
+ override suspend fun writeTo(t: Cache, output: OutputStream) = t.writeTo(output)
+}
+
+val Context.cache: DataStore by dataStore(
+ fileName = "cache.pb",
+ serializer = CacheSerializer
+)
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/settings/SettingsSerializer.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/proto/SettingsSerializer.kt
similarity index 89%
rename from app/src/main/java/ru/n08i40k/polytechnic/next/settings/SettingsSerializer.kt
rename to app/src/main/java/ru/n08i40k/polytechnic/next/proto/SettingsSerializer.kt
index 54a9ffa..164e45e 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/settings/SettingsSerializer.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/proto/SettingsSerializer.kt
@@ -1,4 +1,4 @@
-package ru.n08i40k.polytechnic.next.settings
+package ru.n08i40k.polytechnic.next.proto
import android.content.Context
import androidx.datastore.core.CorruptionException
@@ -23,7 +23,7 @@ object SettingsSerializer : Serializer {
override suspend fun writeTo(t: Settings, output: OutputStream) = t.writeTo(output)
}
-val Context.settings: DataStore by dataStore(
+val Context.settings_v0: DataStore by dataStore(
fileName = "settings.pb",
serializer = SettingsSerializer
)
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/proto/SettingsV2Serializer.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/proto/SettingsV2Serializer.kt
new file mode 100644
index 0000000..0d4aa7b
--- /dev/null
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/proto/SettingsV2Serializer.kt
@@ -0,0 +1,29 @@
+package ru.n08i40k.polytechnic.next.proto
+
+import android.content.Context
+import androidx.datastore.core.CorruptionException
+import androidx.datastore.core.DataStore
+import androidx.datastore.core.Serializer
+import androidx.datastore.dataStore
+import com.google.protobuf.InvalidProtocolBufferException
+import ru.n08i40k.polytechnic.next.SettingsV2
+import java.io.InputStream
+import java.io.OutputStream
+
+object SettingsV2Serializer : Serializer {
+ override val defaultValue: SettingsV2 = SettingsV2.getDefaultInstance()
+
+ override suspend fun readFrom(input: InputStream): SettingsV2 =
+ try {
+ SettingsV2.parseFrom(input)
+ } catch (exception: InvalidProtocolBufferException) {
+ throw CorruptionException("Cannot read proto.", exception)
+ }
+
+ override suspend fun writeTo(t: SettingsV2, output: OutputStream) = t.writeTo(output)
+}
+
+val Context.settings: DataStore by dataStore(
+ fileName = "settings-v2.pb",
+ serializer = SettingsV2Serializer
+)
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/NetworkCacheRepository.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/NetworkCacheRepository.kt
index 66a6ff1..2af78c8 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/NetworkCacheRepository.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/NetworkCacheRepository.kt
@@ -1,12 +1,12 @@
package ru.n08i40k.polytechnic.next.repository.cache
-import ru.n08i40k.polytechnic.next.CachedResponse
-import ru.n08i40k.polytechnic.next.UpdateDates
+import ru.n08i40k.polytechnic.next.CacheDate
+import ru.n08i40k.polytechnic.next.CacheResponse
interface NetworkCacheRepository {
suspend fun put(url: String, data: String)
- suspend fun get(url: String): CachedResponse?
+ suspend fun get(url: String): CacheResponse?
suspend fun clear()
@@ -14,7 +14,7 @@ interface NetworkCacheRepository {
suspend fun setHash(hash: String)
- suspend fun getUpdateDates(): UpdateDates
+ suspend fun getUpdateDates(): CacheDate
suspend fun setUpdateDates(cache: Long, schedule: Long)
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/impl/LocalNetworkCacheRepository.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/impl/LocalNetworkCacheRepository.kt
index 05b79ef..4ac1f1b 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/impl/LocalNetworkCacheRepository.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/impl/LocalNetworkCacheRepository.kt
@@ -5,17 +5,18 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
-import ru.n08i40k.polytechnic.next.CachedResponse
-import ru.n08i40k.polytechnic.next.UpdateDates
+import ru.n08i40k.polytechnic.next.CacheDate
+import ru.n08i40k.polytechnic.next.CacheResponse
import ru.n08i40k.polytechnic.next.app.AppContainer
+import ru.n08i40k.polytechnic.next.proto.cache
import ru.n08i40k.polytechnic.next.repository.cache.NetworkCacheRepository
-import ru.n08i40k.polytechnic.next.settings.settings
import javax.inject.Inject
class LocalNetworkCacheRepository
@Inject constructor(private val appContainer: AppContainer) : NetworkCacheRepository {
- private val cacheMap: MutableMap = mutableMapOf()
- private var updateDates: UpdateDates = UpdateDates.newBuilder().build()
+ private val cacheMap: MutableMap = mutableMapOf()
+ private var cacheDate: CacheDate = CacheDate.newBuilder().build()
+
private var hash: String? = null
private val context get() = appContainer.context
@@ -26,14 +27,14 @@ class LocalNetworkCacheRepository
runBlocking {
cacheMap.putAll(
context
- .settings
+ .cache
.data
- .map { settings -> settings.cacheStorageMap }.first()
+ .map { it.storageMap }.first()
)
}
}
- override suspend fun get(url: String): CachedResponse? {
+ override suspend fun get(url: String): CacheResponse? {
// Если кешированного ответа нет, то возвращаем null
// Если хеши не совпадают и локальный хеш присутствует, то возвращаем null
@@ -49,7 +50,7 @@ class LocalNetworkCacheRepository
if (hash == null)
throw IllegalStateException("Не установлен хеш!")
- cacheMap[url] = CachedResponse
+ cacheMap[url] = CacheResponse
.newBuilder()
.setHash(this.hash)
.setData(data)
@@ -83,21 +84,21 @@ class LocalNetworkCacheRepository
}
}
- override suspend fun getUpdateDates(): UpdateDates {
- return this.updateDates
+ override suspend fun getUpdateDates(): CacheDate {
+ return this.cacheDate
}
override suspend fun setUpdateDates(cache: Long, schedule: Long) {
- updateDates = UpdateDates
+ cacheDate = CacheDate
.newBuilder()
.setCache(cache)
.setSchedule(schedule).build()
withContext(Dispatchers.IO) {
- context.settings.updateData {
+ context.cache.updateData {
it
.toBuilder()
- .setUpdateDates(updateDates)
+ .setDate(cacheDate)
.build()
}
}
@@ -106,10 +107,10 @@ class LocalNetworkCacheRepository
private suspend fun save() {
withContext(Dispatchers.IO) {
- context.settings.updateData {
+ context.cache.updateData {
it
.toBuilder()
- .putAllCacheStorage(cacheMap)
+ .putAllStorage(cacheMap)
.build()
}
}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/impl/MockNetworkCacheRepository.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/impl/MockNetworkCacheRepository.kt
index 188dd53..4daec0b 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/impl/MockNetworkCacheRepository.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/repository/cache/impl/MockNetworkCacheRepository.kt
@@ -1,11 +1,11 @@
package ru.n08i40k.polytechnic.next.repository.cache.impl
-import ru.n08i40k.polytechnic.next.CachedResponse
-import ru.n08i40k.polytechnic.next.UpdateDates
+import ru.n08i40k.polytechnic.next.CacheDate
+import ru.n08i40k.polytechnic.next.CacheResponse
import ru.n08i40k.polytechnic.next.repository.cache.NetworkCacheRepository
class MockNetworkCacheRepository : NetworkCacheRepository {
- override suspend fun get(url: String): CachedResponse? {
+ override suspend fun get(url: String): CacheResponse? {
return null
}
@@ -19,8 +19,8 @@ class MockNetworkCacheRepository : NetworkCacheRepository {
override suspend fun setHash(hash: String) {}
- override suspend fun getUpdateDates(): UpdateDates {
- return UpdateDates.newBuilder().build()
+ override suspend fun getUpdateDates(): CacheDate {
+ return CacheDate.newBuilder().build()
}
override suspend fun setUpdateDates(cache: Long, schedule: Long) {}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/repository/profile/impl/RemoteProfileRepository.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/repository/profile/impl/RemoteProfileRepository.kt
index 3047465..15a148d 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/repository/profile/impl/RemoteProfileRepository.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/repository/profile/impl/RemoteProfileRepository.kt
@@ -7,8 +7,9 @@ import ru.n08i40k.polytechnic.next.model.Profile
import ru.n08i40k.polytechnic.next.network.request.fcm.FcmSetToken
import ru.n08i40k.polytechnic.next.network.request.profile.ProfileMe
import ru.n08i40k.polytechnic.next.network.tryFuture
+import ru.n08i40k.polytechnic.next.proto.cache
+import ru.n08i40k.polytechnic.next.proto.settings
import ru.n08i40k.polytechnic.next.repository.profile.ProfileRepository
-import ru.n08i40k.polytechnic.next.settings.settings
import ru.n08i40k.polytechnic.next.utils.MyResult
import ru.n08i40k.polytechnic.next.utils.app
@@ -40,7 +41,14 @@ class RemoteProfileRepository(private val container: AppContainer) : ProfileRepo
override suspend fun signOut() {
val context = container.context
- container.context.settings.updateData {
+ context.settings.updateData {
+ it
+ .toBuilder()
+ .clear()
+ .build()
+ }
+
+ context.cache.updateData {
it
.toBuilder()
.clear()
@@ -48,12 +56,5 @@ class RemoteProfileRepository(private val container: AppContainer) : ProfileRepo
}
context.app.events.signOut.next(Unit)
-
-// context.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)
-// val pm = context.packageManager
-// val intent = pm.getLaunchIntentForPackage(context.packageName)
-// val mainIntent = Intent.makeRestartActivityTask(intent?.component)
-// context.startActivity(mainIntent)
-// Runtime.getRuntime().exit(0)
}
}
\ 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 c5e05bb..f542b75 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
@@ -37,7 +37,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import ru.n08i40k.polytechnic.next.Application
import ru.n08i40k.polytechnic.next.R
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
import ru.n08i40k.polytechnic.next.ui.screen.MainScreen
import ru.n08i40k.polytechnic.next.ui.screen.auth.AuthScreen
import ru.n08i40k.polytechnic.next.utils.app
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/GroupViewModel.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/GroupViewModel.kt
index e3d9c4e..3f56007 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/GroupViewModel.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/GroupViewModel.kt
@@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
-import ru.n08i40k.polytechnic.next.UpdateDates
+import ru.n08i40k.polytechnic.next.CacheDate
import ru.n08i40k.polytechnic.next.app.AppContainer
import ru.n08i40k.polytechnic.next.model.GroupOrTeacher
import ru.n08i40k.polytechnic.next.utils.MyResult
@@ -25,7 +25,7 @@ sealed interface GroupUiState {
data class HasData(
val group: GroupOrTeacher,
- val updateDates: UpdateDates,
+ val cacheDate: CacheDate,
val lastUpdateAt: Long,
override val isLoading: Boolean
) : GroupUiState
@@ -33,7 +33,7 @@ sealed interface GroupUiState {
private data class GroupViewModelState(
val group: GroupOrTeacher? = null,
- val updateDates: UpdateDates? = null,
+ val updateDates: CacheDate? = null,
val lastUpdateAt: Long = 0,
val isLoading: Boolean = false
) {
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/SearchViewModel.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/SearchViewModel.kt
index 0aab3ac..26be373 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/SearchViewModel.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/SearchViewModel.kt
@@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
-import ru.n08i40k.polytechnic.next.UpdateDates
+import ru.n08i40k.polytechnic.next.CacheDate
import ru.n08i40k.polytechnic.next.app.AppContainer
import ru.n08i40k.polytechnic.next.model.GroupOrTeacher
import ru.n08i40k.polytechnic.next.utils.MyResult
@@ -25,7 +25,7 @@ sealed interface SearchUiState {
data class HasData(
val teacher: GroupOrTeacher,
- val updateDates: UpdateDates,
+ val cacheDate: CacheDate,
val lastUpdateAt: Long,
override val isLoading: Boolean
) : SearchUiState
@@ -33,7 +33,7 @@ sealed interface SearchUiState {
private data class SearchViewModelState(
val teacher: GroupOrTeacher? = null,
- val updateDates: UpdateDates? = null,
+ val updateDates: CacheDate? = null,
val lastUpdateAt: Long = 0,
val isLoading: Boolean = false
) {
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/TeacherViewModel.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/TeacherViewModel.kt
index 664cfe6..32c6624 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/TeacherViewModel.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/model/TeacherViewModel.kt
@@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
-import ru.n08i40k.polytechnic.next.UpdateDates
+import ru.n08i40k.polytechnic.next.CacheDate
import ru.n08i40k.polytechnic.next.app.AppContainer
import ru.n08i40k.polytechnic.next.model.GroupOrTeacher
import ru.n08i40k.polytechnic.next.utils.MyResult
@@ -24,7 +24,7 @@ sealed interface TeacherUiState {
data class HasData(
val teacher: GroupOrTeacher,
- val updateDates: UpdateDates,
+ val cacheDate: CacheDate,
val lastUpdateAt: Long,
override val isLoading: Boolean
) : TeacherUiState
@@ -32,7 +32,7 @@ sealed interface TeacherUiState {
private data class TeacherViewModelState(
val teacher: GroupOrTeacher? = null,
- val updateDates: UpdateDates? = null,
+ val updateDates: CacheDate? = null,
val lastUpdateAt: Long = 0,
val isLoading: Boolean = false
) {
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/MainScreen.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/MainScreen.kt
index 108f8a4..a05833f 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/MainScreen.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/MainScreen.kt
@@ -38,7 +38,7 @@ import kotlinx.coroutines.runBlocking
import ru.n08i40k.polytechnic.next.Application
import ru.n08i40k.polytechnic.next.R
import ru.n08i40k.polytechnic.next.model.UserRole
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
import ru.n08i40k.polytechnic.next.ui.AppRoute
import ru.n08i40k.polytechnic.next.ui.icons.AppIcons
import ru.n08i40k.polytechnic.next.ui.icons.appicons.Filled
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/AuthScreen.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/AuthScreen.kt
index 9440c8a..5c1f136 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/AuthScreen.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/AuthScreen.kt
@@ -35,6 +35,8 @@ import androidx.navigation.compose.rememberNavController
import com.google.android.gms.tasks.OnCompleteListener
import com.google.android.gms.tasks.Task
import com.google.firebase.messaging.FirebaseMessaging
+import kotlinx.coroutines.runBlocking
+import ru.n08i40k.polytechnic.next.proto.cache
import ru.n08i40k.polytechnic.next.ui.AppRoute
import ru.n08i40k.polytechnic.next.ui.helper.PushSnackbar
import ru.n08i40k.polytechnic.next.ui.helper.SnackbarBox
@@ -61,8 +63,7 @@ private fun FormWrapper(
with(localDensity) {
onWidthChange(it.size.width.toDp())
}
- }
- /*.animateContentSize()*/,
+ },
content = content
)
}
@@ -84,6 +85,8 @@ private fun AuthForm(parentNavController: NavController, pushSnackbar: PushSnack
}
val finish: () -> Unit = {
+ runBlocking { context.cache.updateData { it.toBuilder().clear().build() } }
+
parentNavController.navigate(AppRoute.MAIN.route) {
popUpTo(AppRoute.AUTH.route) { inclusive = true }
}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signin/ManualPage.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signin/ManualPage.kt
index 88278b4..2ad1e85 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signin/ManualPage.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signin/ManualPage.kt
@@ -40,7 +40,7 @@ import kotlinx.coroutines.runBlocking
import ru.n08i40k.polytechnic.next.R
import ru.n08i40k.polytechnic.next.network.request.auth.AuthSignIn
import ru.n08i40k.polytechnic.next.network.unwrapException
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
import ru.n08i40k.polytechnic.next.ui.helper.PushSnackbar
import ru.n08i40k.polytechnic.next.ui.helper.data.rememberInputValue
import java.util.logging.Logger
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signin/VKOneTap.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signin/VKOneTap.kt
index ca47f65..891c7d3 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signin/VKOneTap.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signin/VKOneTap.kt
@@ -8,7 +8,7 @@ import androidx.compose.ui.tooling.preview.Preview
import kotlinx.coroutines.runBlocking
import ru.n08i40k.polytechnic.next.network.request.auth.AuthSignInVK
import ru.n08i40k.polytechnic.next.network.unwrapException
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
import ru.n08i40k.polytechnic.next.ui.widgets.OneTapComplete
import java.util.logging.Logger
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signup/ManualPage.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signup/ManualPage.kt
index d074776..66ba855 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signup/ManualPage.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signup/ManualPage.kt
@@ -42,7 +42,7 @@ import ru.n08i40k.polytechnic.next.R
import ru.n08i40k.polytechnic.next.model.UserRole
import ru.n08i40k.polytechnic.next.network.request.auth.AuthSignUp
import ru.n08i40k.polytechnic.next.network.unwrapException
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
import ru.n08i40k.polytechnic.next.ui.helper.PushSnackbar
import ru.n08i40k.polytechnic.next.ui.helper.data.rememberInputValue
import ru.n08i40k.polytechnic.next.ui.widgets.selector.GroupSelector
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signup/VKPage.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signup/VKPage.kt
index d9b7f76..d8ebd1e 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signup/VKPage.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/auth/signup/VKPage.kt
@@ -41,7 +41,7 @@ import ru.n08i40k.polytechnic.next.R
import ru.n08i40k.polytechnic.next.model.UserRole
import ru.n08i40k.polytechnic.next.network.request.auth.AuthSignUpVK
import ru.n08i40k.polytechnic.next.network.unwrapException
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
import ru.n08i40k.polytechnic.next.ui.helper.PushSnackbar
import ru.n08i40k.polytechnic.next.ui.helper.data.rememberInputValue
import ru.n08i40k.polytechnic.next.ui.widgets.selector.GroupSelector
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/GroupScheduleScreen.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/GroupScheduleScreen.kt
index 8cb10f8..a96c482 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/GroupScheduleScreen.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/GroupScheduleScreen.kt
@@ -65,7 +65,7 @@ fun GroupScheduleScreen(viewModel: GroupViewModel) {
Column {
val data = uiState as GroupUiState.HasData
- UpdateInfo(data.lastUpdateAt, data.updateDates)
+ UpdateInfo(data.lastUpdateAt, data.cacheDate)
Spacer(Modifier.height(10.dp))
SchedulePager(data.group)
}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/TeacherScheduleScreen.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/TeacherScheduleScreen.kt
index 448ef92..9a753b2 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/TeacherScheduleScreen.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/TeacherScheduleScreen.kt
@@ -65,7 +65,7 @@ fun TeacherScheduleScreen(viewModel: TeacherViewModel) {
Column {
val data = uiState as TeacherUiState.HasData
- UpdateInfo(data.lastUpdateAt, data.updateDates)
+ UpdateInfo(data.lastUpdateAt, data.cacheDate)
Spacer(Modifier.height(10.dp))
SchedulePager(data.teacher)
}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/TeacherSearchScreen.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/TeacherSearchScreen.kt
index 6271186..8428dbc 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/TeacherSearchScreen.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/TeacherSearchScreen.kt
@@ -85,7 +85,7 @@ fun TeacherSearchScreen(viewModel: SearchViewModel) {
Column {
val data = uiState as SearchUiState.HasData
- UpdateInfo(data.lastUpdateAt, data.updateDates)
+ UpdateInfo(data.lastUpdateAt, data.cacheDate)
Spacer(Modifier.height(10.dp))
SchedulePager(data.teacher)
}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/UpdateInfo.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/UpdateInfo.kt
index 435bcde..981288f 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/UpdateInfo.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/screen/schedule/UpdateInfo.kt
@@ -19,8 +19,8 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import ru.n08i40k.polytechnic.next.CacheDate
import ru.n08i40k.polytechnic.next.R
-import ru.n08i40k.polytechnic.next.UpdateDates
import ru.n08i40k.polytechnic.next.ui.widgets.ExpandableCard
import ru.n08i40k.polytechnic.next.ui.widgets.ExpandableCardTitle
import ru.n08i40k.polytechnic.next.utils.*
@@ -32,15 +32,15 @@ val expanded = mutableStateOf(false)
@Composable
fun UpdateInfo(
lastUpdateAt: Long = 0,
- updateDates: UpdateDates = UpdateDates.newBuilder().build()
+ cacheDate: CacheDate = CacheDate.newBuilder().build()
) {
var expanded by remember { expanded }
val format = "HH:mm:ss dd.MM.yyyy"
val currentDate = Date(lastUpdateAt).toString(format)
- val cacheUpdateDate = Date(updateDates.cache).toString(format)
- val scheduleUpdateDate = Date(updateDates.schedule).toString(format)
+ val cacheUpdateDate = Date(cacheDate.cache).toString(format)
+ val scheduleUpdateDate = Date(cacheDate.schedule).toString(format)
ExpandableCard(
expanded = expanded,
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/DayCard.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/DayCard.kt
index a34803c..3963018 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/DayCard.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/DayCard.kt
@@ -18,9 +18,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
@@ -34,6 +32,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.datetime.LocalDateTime
import ru.n08i40k.polytechnic.next.R
import ru.n08i40k.polytechnic.next.model.Day
+import ru.n08i40k.polytechnic.next.model.Lesson
import ru.n08i40k.polytechnic.next.model.LessonType
import ru.n08i40k.polytechnic.next.repository.schedule.impl.MockScheduleRepository
import ru.n08i40k.polytechnic.next.utils.dateTime
@@ -80,7 +79,8 @@ private fun getCurrentLessonIdx(day: Day?): Flow {
@Composable
fun DayCard(
modifier: Modifier = Modifier,
- day: Day = MockScheduleRepository.exampleTeacher.days[0]
+ day: Day = MockScheduleRepository.exampleTeacher.days[0],
+ onLessonClick: (Lesson) -> Unit = {},
) {
val offset = remember(day) { getDayOffset(day) }
@@ -119,9 +119,9 @@ fun DayCard(
style = MaterialTheme.typography.titleLarge
)
- if (day.street != null) {
+ day.street?.let {
Text(
- day.street,
+ it,
Modifier.fillMaxWidth(),
textAlign = TextAlign.Center,
)
@@ -177,12 +177,9 @@ fun DayCard(
LessonType.EXAM_DEFAULT -> examCardColors
}
- // TODO: Вернуть ExtraInfo
- var extraInfo by remember { mutableStateOf(false) }
-
Box(
Modifier
- .clickable { extraInfo = true }
+ .clickable { onLessonClick(lesson) }
.background(cardColors.containerColor)
) {
val modifier =
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/ExtraInfoDialog.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/ExtraInfoDialog.kt
new file mode 100644
index 0000000..4562be0
--- /dev/null
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/ExtraInfoDialog.kt
@@ -0,0 +1,150 @@
+package ru.n08i40k.polytechnic.next.ui.widgets.schedule
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Card
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.PreviewParameterProvider
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.max
+import androidx.compose.ui.window.Dialog
+import ru.n08i40k.polytechnic.next.R
+import ru.n08i40k.polytechnic.next.model.Lesson
+import ru.n08i40k.polytechnic.next.model.LessonType
+import ru.n08i40k.polytechnic.next.repository.schedule.impl.MockScheduleRepository
+import ru.n08i40k.polytechnic.next.utils.dayMinutes
+import ru.n08i40k.polytechnic.next.utils.fmtAsClock
+
+class LessonPreviewParameterProvider : PreviewParameterProvider {
+ override val values: Sequence
+ get() {
+ val lessons = MockScheduleRepository.exampleGroup.days[0].lessons
+
+ return sequenceOf(
+ lessons[0],
+ lessons[2],
+ lessons[4],
+ lessons[6],
+ )
+ }
+}
+
+@Preview
+@Composable
+private fun ExtraInfoDialogPreview(
+ @PreviewParameter(LessonPreviewParameterProvider::class) lesson: Lesson
+) {
+ ExtraInfoDialog(lesson) { }
+}
+
+@Composable
+fun ExtraInfoDialog(
+ lesson: Lesson,
+ onDismiss: () -> Unit
+) {
+ Dialog(onDismiss) {
+ Card {
+ Column(Modifier.padding(10.dp)) {
+ var minWidth by remember { mutableStateOf(Dp.Unspecified) }
+ val density = LocalDensity.current
+
+ @Composable
+ fun kvText(title: String, text: String) {
+ Row(
+ Modifier.alpha(if (minWidth == Dp.Unspecified) 0f else 1f),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ title,
+ Modifier
+ .onGloballyPositioned {
+ with(density) {
+ val dp = it.size.width.toDp()
+
+ minWidth =
+ if (minWidth == Dp.Unspecified)
+ dp
+ else
+ max(minWidth, dp)
+ }
+ }
+ .size(minWidth, Dp.Unspecified),
+ fontWeight = FontWeight.Bold,
+ fontFamily = FontFamily.Monospace,
+ textAlign = TextAlign.Right,
+ )
+
+ Text(text)
+ }
+ }
+
+ kvText(stringResource(R.string.extra_info_lesson_name), lesson.name ?: "")
+ when (lesson.type) {
+ LessonType.BREAK -> throw IllegalArgumentException()
+ LessonType.DEFAULT -> null
+ LessonType.ADDITIONAL -> null
+ LessonType.CONSULTATION -> R.string.lesson_type_consultation
+ LessonType.INDEPENDENT_WORK -> R.string.lesson_type_independent_work
+ LessonType.EXAM -> R.string.lesson_type_exam
+ LessonType.EXAM_WITH_GRADE -> R.string.lesson_type_exam_with_grade
+ LessonType.EXAM_DEFAULT -> R.string.lesson_type_exam_default
+ }?.let {
+ kvText(stringResource(R.string.extra_info_type), stringResource(it))
+ }
+
+ if (lesson.subGroups.size == 1) {
+ kvText(
+ stringResource(R.string.extra_info_teacher),
+ stringResource(
+ R.string.extra_info_teacher_second,
+ lesson.subGroups[0].teacher,
+ lesson.subGroups[0].cabinet
+ )
+ )
+ } else {
+ for (subGroup in lesson.subGroups) {
+ kvText(
+ stringResource(R.string.extra_info_teacher),
+ stringResource(
+ R.string.extra_info_teacher_second_subgroup,
+ subGroup.teacher,
+ subGroup.cabinet,
+ subGroup.number
+ )
+ )
+ }
+ }
+
+ kvText(
+ stringResource(R.string.extra_info_duration),
+ stringResource(
+ R.string.extra_info_duration_second,
+ lesson.time.start.dayMinutes.fmtAsClock(),
+ lesson.time.end.dayMinutes.fmtAsClock(),
+ lesson.duration / 60,
+ lesson.duration % 60
+ )
+ )
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/SchedulePager.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/SchedulePager.kt
index 13996aa..0b0d065 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/SchedulePager.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/ui/widgets/schedule/SchedulePager.kt
@@ -7,6 +7,10 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
@@ -17,10 +21,13 @@ import androidx.compose.ui.util.lerp
import kotlinx.datetime.LocalDateTime
import ru.n08i40k.polytechnic.next.R
import ru.n08i40k.polytechnic.next.model.GroupOrTeacher
+import ru.n08i40k.polytechnic.next.model.Lesson
+import ru.n08i40k.polytechnic.next.model.LessonType
import ru.n08i40k.polytechnic.next.repository.schedule.impl.MockScheduleRepository
import ru.n08i40k.polytechnic.next.ui.widgets.NotificationCard
import ru.n08i40k.polytechnic.next.utils.dateTime
import ru.n08i40k.polytechnic.next.utils.now
+import java.lang.ref.WeakReference
import java.util.logging.Level
import kotlin.math.absoluteValue
@@ -40,6 +47,8 @@ fun SchedulePager(schedule: GroupOrTeacher = MockScheduleRepository.exampleTeach
pageCount = { schedule.days.size }
)
+ var dialogLesson by remember { mutableStateOf?>(null) }
+
Column {
if (isScheduleOutdated(schedule))
NotificationCard(Level.WARNING, stringResource(R.string.outdated_schedule))
@@ -69,7 +78,14 @@ fun SchedulePager(schedule: GroupOrTeacher = MockScheduleRepository.exampleTeach
)
},
schedule.days[page]
- )
+ ) { dialogLesson = WeakReference(it) }
}
}
+
+ dialogLesson?.get()?.let { lesson ->
+ if (lesson.type == LessonType.BREAK)
+ return@let
+
+ ExtraInfoDialog(lesson) { dialogLesson = null }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/worker/UpdateFCMTokenWorker.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/worker/UpdateFCMTokenWorker.kt
index d89cd93..4fea6dc 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/worker/UpdateFCMTokenWorker.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/worker/UpdateFCMTokenWorker.kt
@@ -13,7 +13,7 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import ru.n08i40k.polytechnic.next.app.appContainer
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
import ru.n08i40k.polytechnic.next.utils.MyResult
import java.time.Duration
import java.util.logging.Logger
diff --git a/app/src/main/java/ru/n08i40k/polytechnic/next/worker/UpdateLinkWorker.kt b/app/src/main/java/ru/n08i40k/polytechnic/next/worker/UpdateLinkWorker.kt
index cd0687f..bf3471a 100644
--- a/app/src/main/java/ru/n08i40k/polytechnic/next/worker/UpdateLinkWorker.kt
+++ b/app/src/main/java/ru/n08i40k/polytechnic/next/worker/UpdateLinkWorker.kt
@@ -8,7 +8,7 @@ import androidx.work.WorkerParameters
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import ru.n08i40k.polytechnic.next.app.appContainer
-import ru.n08i40k.polytechnic.next.settings.settings
+import ru.n08i40k.polytechnic.next.proto.settings
import java.util.concurrent.TimeUnit
import java.util.logging.Logger
diff --git a/app/src/main/proto/cache.proto b/app/src/main/proto/cache.proto
new file mode 100644
index 0000000..35a1c4b
--- /dev/null
+++ b/app/src/main/proto/cache.proto
@@ -0,0 +1,19 @@
+syntax = "proto3";
+
+option java_package = "ru.n08i40k.polytechnic.next";
+option java_multiple_files = true;
+
+message CacheResponse {
+ string hash = 1;
+ string data = 2;
+}
+
+message CacheDate {
+ int64 cache = 1;
+ int64 schedule = 2;
+}
+
+message Cache {
+ map storage = 4;
+ CacheDate date = 5;
+}
\ No newline at end of file
diff --git a/app/src/main/proto/settings-v2.proto b/app/src/main/proto/settings-v2.proto
new file mode 100644
index 0000000..74bb531
--- /dev/null
+++ b/app/src/main/proto/settings-v2.proto
@@ -0,0 +1,15 @@
+syntax = "proto3";
+
+option java_package = "ru.n08i40k.polytechnic.next";
+option java_multiple_files = true;
+
+message SettingsV2 {
+ string user_id = 1;
+ string access_token = 2;
+ string group = 3;
+
+ string version = 5;
+ string suppressed_version = 6;
+
+ string fcm_token = 7;
+}
\ No newline at end of file
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 6871a69..fc0edf5 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -100,4 +100,11 @@
Ура, можно идти домой! Наверное :(
Текущая пара
Отображает текущую пару или перемену в уведомлении
+ "Название: "
+ "Преподаватель: "
+ %1$s в %2$s каб.
+ %1$s в %2$s каб. [подгруппа - %3$d]
+ "Длительность: "
+ С %1$s до %2$s (%3$d ч. %4$d мин.)
+ "Тип: "
\ 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 130a269..97b3e65 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -100,4 +100,11 @@
ya ne budu eto perevidit\'
Current lesson
View the current lesson and breaks in notification
+ "Name: "
+ "Teacher: "
+ %1$s in %2$s cab.
+ %1$s in %2$s cab. [subgroup - %3$d]
+ "Duration: "
+ From %1$s to %2$s (%3$d h. %4$d min.)
+ "Type: "
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 5289a6d..ea60927 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,27 +1,28 @@
[versions]
-agp = "8.8.1"
-desugar_jdk_libs = "2.1.4"
+agp = "8.8.2"
+desugar_jdk_libs = "2.1.5"
kotlin = "2.1.10"
coreKtx = "1.15.0"
junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
lifecycleRuntimeKtx = "2.8.7"
-activityCompose = "1.10.0"
-composeBom = "2025.02.00"
+activityCompose = "1.10.1"
+composeBom = "2025.03.00"
accompanistSwiperefresh = "0.36.0"
-firebaseBom = "33.9.0"
+firebaseBom = "33.10.0"
hiltAndroid = "2.55"
hiltAndroidCompiler = "2.55"
hiltNavigationCompose = "1.2.0"
kotlinxSerializationJson = "1.8.0"
protobufLite = "3.0.1"
volley = "1.2.1"
-datastore = "1.1.2"
+datastore = "1.1.3"
navigationCompose = "2.8.9"
googleFirebaseCrashlytics = "3.0.3"
workRuntime = "2.10.0"
-vkid = "2.3.1"
+#noinspection GradleDependency
+vkid = "2.2.2"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -59,8 +60,8 @@ volley = { group = "com.android.volley", name = "volley", version.ref = "volley"
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" }
-firebase-analytics = { module = "com.google.firebase:firebase-analytics", version = "22.2.0" }
-firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics", version = "19.4.0" }
+firebase-analytics = { module = "com.google.firebase:firebase-analytics", version = "22.3.0" }
+firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics", version = "19.4.1" }
firebase-messaging = { group = "com.google.firebase", name = "firebase-messaging", version = "24.1.0" }
firebase-config = { group = "com.google.firebase", name = "firebase-config", version = "22.1.0" }
vk-vkid = {group = "com.vk.id", name = "vkid", version.ref = "vkid" }