From 983249091a3b8ef9fd1c029fd206bf5c328e63da Mon Sep 17 00:00:00 2001 From: sweetbread Date: Tue, 19 Mar 2024 00:27:57 +0300 Subject: [PATCH] Init commit --- .gitignore | 15 ++ .idea/.gitignore | 3 + .idea/codeStyles/Project.xml | 123 +++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/compiler.xml | 6 + .idea/deploymentTargetDropDown.xml | 19 ++ .idea/gradle.xml | 19 ++ .idea/kotlinc.xml | 6 + .idea/migrations.xml | 10 + .idea/misc.xml | 9 + .idea/vcs.xml | 6 + app/.gitignore | 1 + app/build.gradle.kts | 88 ++++++++ app/proguard-rules.pro | 21 ++ .../sweetbread/unn/ExampleInstrumentedTest.kt | 24 +++ app/src/main/AndroidManifest.xml | 31 +++ app/src/main/ic_launcher-playstore.png | Bin 0 -> 17711 bytes app/src/main/java/ru/sweetbread/unn/ui/API.kt | 187 ++++++++++++++++ .../ru/sweetbread/unn/ui/composes/Schedule.kt | 199 ++++++++++++++++++ .../sweetbread/unn/ui/layout/LoginActivity.kt | 145 +++++++++++++ .../sweetbread/unn/ui/layout/MainActivity.kt | 181 ++++++++++++++++ .../java/ru/sweetbread/unn/ui/theme/Color.kt | 67 ++++++ .../java/ru/sweetbread/unn/ui/theme/Theme.kt | 96 +++++++++ .../java/ru/sweetbread/unn/ui/theme/Type.kt | 34 +++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 6 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 6 + app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1414 bytes .../mipmap-hdpi/ic_launcher_foreground.webp | Bin 0 -> 790 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 3132 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 878 bytes .../mipmap-mdpi/ic_launcher_foreground.webp | Bin 0 -> 534 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 2018 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1862 bytes .../mipmap-xhdpi/ic_launcher_foreground.webp | Bin 0 -> 1052 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 4376 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2682 bytes .../mipmap-xxhdpi/ic_launcher_foreground.webp | Bin 0 -> 1550 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 6638 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3588 bytes .../ic_launcher_foreground.webp | Bin 0 -> 2062 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 9348 bytes app/src/main/res/values-land/dimens.xml | 3 + app/src/main/res/values-ru/strings.xml | 6 + app/src/main/res/values-w1240dp/dimens.xml | 3 + app/src/main/res/values-w600dp/dimens.xml | 3 + app/src/main/res/values/colors.xml | 10 + app/src/main/res/values/dimens.xml | 5 + .../res/values/ic_launcher_background.xml | 4 + app/src/main/res/values/strings.xml | 9 + app/src/main/res/values/themes.xml | 5 + build.gradle.kts | 5 + gradle.properties | 23 ++ gradle/libs.versions.toml | 61 ++++++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 185 ++++++++++++++++ gradlew.bat | 89 ++++++++ settings.gradle.kts | 23 ++ 58 files changed, 1747 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/compiler.xml create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/kotlinc.xml create mode 100644 .idea/migrations.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle.kts create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/ru/sweetbread/unn/ExampleInstrumentedTest.kt create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/ic_launcher-playstore.png create mode 100644 app/src/main/java/ru/sweetbread/unn/ui/API.kt create mode 100644 app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt create mode 100644 app/src/main/java/ru/sweetbread/unn/ui/layout/LoginActivity.kt create mode 100644 app/src/main/java/ru/sweetbread/unn/ui/layout/MainActivity.kt create mode 100644 app/src/main/java/ru/sweetbread/unn/ui/theme/Color.kt create mode 100644 app/src/main/java/ru/sweetbread/unn/ui/theme/Theme.kt create mode 100644 app/src/main/java/ru/sweetbread/unn/ui/theme/Type.kt create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/values-land/dimens.xml create mode 100644 app/src/main/res/values-ru/strings.xml create mode 100644 app/src/main/res/values-w1240dp/dimens.xml create mode 100644 app/src/main/res/values-w600dp/dimens.xml create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/dimens.xml create mode 100644 app/src/main/res/values/ic_launcher_background.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 build.gradle.kts create mode 100644 gradle.properties create mode 100644 gradle/libs.versions.toml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle.kts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..7643783 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,123 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..39bf74d --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..0897082 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..fdf8d99 --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml new file mode 100644 index 0000000..f8051a6 --- /dev/null +++ b/.idea/migrations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..8978d23 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..dc563e8 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,88 @@ +plugins { + alias(libs.plugins.androidApplication) + alias(libs.plugins.jetbrainsKotlinAndroid) +} + +android { + namespace = "ru.sweetbread.unn" + compileSdk = 34 + + defaultConfig { + applicationId = "ru.sweetbread.unn" + minSdk = 26 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = "1.8" + } + buildFeatures { + compose = true + viewBinding = true + } + composeOptions { + kotlinCompilerExtensionVersion = "1.5.1" + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } +} + +dependencies { + coreLibraryDesugaring(libs.desugar.jdk.libs) + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(libs.androidx.appcompat) + implementation(libs.material) + implementation(libs.androidx.annotation) + implementation(libs.androidx.constraintlayout) + implementation(libs.androidx.lifecycle.livedata.ktx) + implementation(libs.androidx.lifecycle.viewmodel.ktx) + implementation(libs.androidx.activity) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.ui.test.junit4) + debugImplementation(libs.androidx.ui.tooling) + debugImplementation(libs.androidx.ui.test.manifest) + implementation(libs.androidx.core.splashscreen) + + + implementation(libs.androidx.navigation.compose) + + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.cio) + implementation(libs.ktor.client.logging) + + implementation(libs.androidx.datastore.preferences) + implementation(libs.splitties.funpack.android.base.with.views.dsl) + + implementation(libs.compose) + +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/ru/sweetbread/unn/ExampleInstrumentedTest.kt b/app/src/androidTest/java/ru/sweetbread/unn/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..a5be119 --- /dev/null +++ b/app/src/androidTest/java/ru/sweetbread/unn/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package ru.sweetbread.unn + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("ru.sweetbread.unn", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8c8e329 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..7686ad5183a49422475a2b9adfa91498974bc6e4 GIT binary patch literal 17711 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 JMCH+o{|93s%w_-p literal 0 HcmV?d00001 diff --git a/app/src/main/java/ru/sweetbread/unn/ui/API.kt b/app/src/main/java/ru/sweetbread/unn/ui/API.kt new file mode 100644 index 0000000..2ba7ed0 --- /dev/null +++ b/app/src/main/java/ru/sweetbread/unn/ui/API.kt @@ -0,0 +1,187 @@ +package ru.sweetbread.unn.ui + +import io.ktor.client.request.forms.submitForm +import io.ktor.client.request.get +import io.ktor.client.request.parameter +import io.ktor.client.statement.bodyAsText +import io.ktor.http.parameters +import org.json.JSONArray +import org.json.JSONObject +import ru.sweetbread.unn.ui.layout.LoginData +import ru.sweetbread.unn.ui.layout.client +import java.time.LocalDate +import java.time.LocalTime +import java.time.format.DateTimeFormatter + +private lateinit var PHPSESSID: String +lateinit var ME: User + +const val portalURL = "https://portal.unn.ru" +const val ruzapiURL = "$portalURL/ruzapi" + +enum class Type(val s: String) { + Student("student"), + Group("group"), + Lecturer("lecturer"), + Auditorium("auditorium") +} + +enum class LecturerRank(val s: String) { + Lecturer("Lecturer"), + SLecturer("Senior Lecturer") +} + +class ScheduleUnit(val oid: Int, + val auditorium: Auditorium, + val date: LocalDate, + val discipline: Discipline, + val kindOfWork: KindOfWork, + val lecturers: ArrayList, + val stream: String, + val begin: LocalTime, + val end: LocalTime) + +class Auditorium( val name: String, + val oid: Int, + val floor: Int, + val building: Building) +class Building( val name: String, + val gid: Int, + val oid: Int) + +class Discipline( val name: String, + val oid: Int, + val type: Int) + +class KindOfWork( val name: String, + val oid: Int, + val uid: String, + val complexity: Int) + +class Lecturer( val name: String, + val rank: LecturerRank, + val email: String, + val oid: Int, + val uid: String) + +class User (val id: String, + val uns: String, + val type: Type, + val email: String, + val name: String, + val info: String) + +/** + * Authorize user by [login] and [password] + * + * Also defines local vars [PHPSESSID] and [ME] + */ +suspend fun auth(login: String = LoginData.login, password: String = LoginData.password, forced: Boolean = false): Boolean { + if (!forced) { + if (::PHPSESSID.isInitialized and ::ME.isInitialized) + return true + } + val r = client.submitForm("$portalURL/auth/?login=yes", + formParameters = parameters { + append("AUTH_FORM", "Y") + append("TYPE", "AUTH") + append("backurl", "/") + append("USER_LOGIN", login) + append("USER_PASSWORD", password) + } + ) + if (r.status.value == 302) { + PHPSESSID = """PHPSESSID=([\w\d]+)""".toRegex().find(r.headers["Set-Cookie"]!!)!!.groupValues[1] + getMyself(login) + return true + } + return false +} + +/** + * Save info about current [User] in memory + */ +private suspend fun getMyself(login: String) { + val r = client.get("$ruzapiURL/studentinfo") { + parameter("uns", login.substring(1)) + } + val json = JSONObject(r.bodyAsText()) + ME = User( + id = json.getString("id"), + uns = json.getString("uns"), + type = when(json.getString("type")) { + "lecturer" -> Type.Lecturer // ig,,, + else -> Type.Student + }, + email = json.getString("email"), + name = json.getString("fio"), + info = json.getString("info") + ) +} + +suspend fun getSchedule(type: Type = Type.Student, id: String = ME.id, start: LocalDate, finish: LocalDate): ArrayList { + val unnDatePattern = DateTimeFormatter.ofPattern("yyyy.MM.dd") + + val r = client.get("$ruzapiURL/schedule/${type.s}/$id") { + parameter("start", start.format(unnDatePattern)) + parameter("finish", finish.format(unnDatePattern)) + parameter("lng", "1") + } + val json = JSONArray(r.bodyAsText()) + + val out = arrayListOf() + for (i in 0 until json.length()) { + val unit = json.getJSONObject(i) + val lecturesJson = unit.getJSONArray("listOfLecturers") + val lecturers = arrayListOf() + + for (j in 0 until lecturesJson.length()) { + val lecturer = lecturesJson.getJSONObject(j) + lecturers.add( + Lecturer( + name = lecturer.getString("lecturer"), + email = lecturer.getString("lecturerEmail"), + oid = lecturer.getInt("lecturerOid"), + uid = lecturer.getString("lecturerUID"), + rank = when (lecturer.getString("lecturer_rank")) { + "СТПРЕП" -> LecturerRank.SLecturer + else -> LecturerRank.Lecturer + } + ) + ) + } + + out.add( + ScheduleUnit( + oid = unit.getInt("lessonOid"), + auditorium = Auditorium( + name = unit.getString("auditorium"), + oid = unit.getInt("auditoriumOid"), + floor = unit.getInt("auditoriumfloor"), + building = Building( + name = unit.getString("building"), + gid = unit.getInt("buildingGid"), + oid = unit.getInt("buildingOid") + ) + ), + date = LocalDate.parse(unit.getString("date"), unnDatePattern), + discipline = Discipline( + name = unit.getString("discipline"), + oid = unit.getInt("disciplineOid"), + type = unit.getInt("disciplinetypeload") + ), + kindOfWork = KindOfWork( + name = unit.getString("kindOfWork"), + complexity = unit.getInt("kindOfWorkComplexity"), + oid = unit.getInt("kindOfWorkOid"), + uid = unit.getString("kindOfWorkUid") + ), + lecturers = lecturers, + stream = unit.getString("stream"), + begin = LocalTime.parse(unit.getString("beginLesson"), DateTimeFormatter.ofPattern("HH:mm")), + end = LocalTime.parse(unit.getString("endLesson"), DateTimeFormatter.ofPattern("HH:mm")) + ) + ) + } + return out +} diff --git a/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt b/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt new file mode 100644 index 0000000..23a549a --- /dev/null +++ b/app/src/main/java/ru/sweetbread/unn/ui/composes/Schedule.kt @@ -0,0 +1,199 @@ +package ru.sweetbread.unn.ui.composes + +import android.util.Log +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.LinearProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex +import com.kizitonwose.calendar.compose.WeekCalendar +import com.kizitonwose.calendar.compose.weekcalendar.rememberWeekCalendarState +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import ru.sweetbread.unn.ui.Auditorium +import ru.sweetbread.unn.ui.Building +import ru.sweetbread.unn.ui.Discipline +import ru.sweetbread.unn.ui.KindOfWork +import ru.sweetbread.unn.ui.Lecturer +import ru.sweetbread.unn.ui.LecturerRank +import ru.sweetbread.unn.ui.ScheduleUnit +import ru.sweetbread.unn.ui.getSchedule +import ru.sweetbread.unn.ui.theme.UNNTheme +import java.time.DayOfWeek +import java.time.LocalDate +import java.time.LocalTime +import java.time.format.DateTimeFormatter + +@Composable +fun Schedule() { + val state = rememberWeekCalendarState( + firstDayOfWeek = DayOfWeek.MONDAY + ) + + Column { + var curDate by remember { mutableStateOf(LocalDate.now()) } + WeekCalendar( + state = state, + dayContent = { + Box( + modifier = Modifier + .padding(vertical = 16.dp) + .aspectRatio(1f) // This is important for square sizing! + .offset(2.dp) + .background(if (it.date == curDate) MaterialTheme.colorScheme.primaryContainer else MaterialTheme.colorScheme.secondaryContainer) + .clickable( + onClick = { + curDate = it.date + } + ), + contentAlignment = Alignment.Center, + ) { + Text( + text = it.date.dayOfMonth.toString(), + fontWeight = if (it.date == LocalDate.now()) FontWeight.Bold else null + ) + } + } + ) + ScheduleDay(date = curDate) + } +} + +@Composable +fun ScheduleDay(modifier: Modifier = Modifier, date: LocalDate) { + val scope = rememberCoroutineScope() + var loadedDate by remember { mutableStateOf(LocalDate.MIN) } + val lessons = remember { mutableListOf() } + + if (loadedDate == date) { + Log.d("Loaded", "${date.format(DateTimeFormatter.ISO_DATE)} ${lessons.size}") + LazyColumn (modifier) { + items(lessons) { + ScheduleItem(unit = it) + } + } + } else { + LinearProgressIndicator( + modifier = Modifier + .fillMaxWidth() + .padding(8.dp), + color = MaterialTheme.colorScheme.surfaceVariant, + trackColor = MaterialTheme.colorScheme.secondary, + ) + LaunchedEffect(date != loadedDate) { + scope.launch(Dispatchers.IO) { + lessons.clear() + lessons.addAll(getSchedule(start = date, finish = date)) + loadedDate = date + } + } + } +} + +@Composable +fun ScheduleItem(modifier: Modifier = Modifier, unit: ScheduleUnit) { + Row ( + modifier + .fillMaxWidth() + .padding(4.dp) + .clip(RoundedCornerShape(8.dp)) + .background(MaterialTheme.colorScheme.primaryContainer) + .padding(8.dp) + ){ + Column (Modifier.weight(1f)) { + Text( + text = unit.discipline.name, + fontWeight = FontWeight.Bold, + modifier = Modifier.zIndex(1f), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + Text(text = unit.kindOfWork.name, maxLines = 1, overflow = TextOverflow.Ellipsis) + Row (Modifier) { + Text(text = unit.auditorium.name, fontWeight = FontWeight.Bold, modifier = Modifier.padding(end = 4.dp)) + Text(text = unit.auditorium.building.name, maxLines = 1, overflow = TextOverflow.Ellipsis) + } + } + + Column { + val begin = unit.begin.format(DateTimeFormatter.ofPattern("HH:mm")) + val end = unit.end.format(DateTimeFormatter.ofPattern("HH:mm")) + Text(begin.toString(), fontWeight = FontWeight.Bold) + Text(end.toString()) + } + } +} + +@Preview +@Composable +fun ScheduleItemPreview() { + val unit = ScheduleUnit( + oid = 1, + Auditorium( + name = "с/з 1(110)", + oid = 3752, + floor = 0, + building = Building( + name = "Корпус 6", + gid = 30, + oid = 155 + ), + ), + date = LocalDate.of(2024, 3, 11), + discipline = Discipline( + name = "Физическая культура и спорт (элективная дисциплина)", + oid = 67895, + type = 0 + ), + kindOfWork = KindOfWork( + name = "Практика (семинарские занятия)", + oid = 261, + uid = "281474976710661", + complexity = 1 + ), + lecturers = arrayListOf( + Lecturer( + name = "Фамилия Имя Отчество", + rank = LecturerRank.SLecturer, + email = "", + oid = 28000, + uid = "51000" + ) + ), + stream = "3823Б1ПР1|3823Б1ПР2|3823Б1ПР3|3823Б1ПР4|3823Б1ПР5-В-OUP", + begin = LocalTime.of(10, 50), + end = LocalTime.of(12, 20) + ) + + UNNTheme { + Surface(color = MaterialTheme.colorScheme.background) { + ScheduleItem(unit = unit) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/sweetbread/unn/ui/layout/LoginActivity.kt b/app/src/main/java/ru/sweetbread/unn/ui/layout/LoginActivity.kt new file mode 100644 index 0000000..e8915bf --- /dev/null +++ b/app/src/main/java/ru/sweetbread/unn/ui/layout/LoginActivity.kt @@ -0,0 +1,145 @@ +package ru.sweetbread.unn.ui.layout + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarDuration +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.launch +import ru.sweetbread.unn.R +import ru.sweetbread.unn.ui.auth +import ru.sweetbread.unn.ui.theme.UNNTheme +import splitties.activities.start + +class LoginActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + UNNTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + val snackbarHostState = remember { SnackbarHostState() } + val scope = rememberCoroutineScope() + + Scaffold( + snackbarHost = { + SnackbarHost(hostState = snackbarHostState) + } + ) { innerPadding -> + LoginPanel(Modifier.padding(innerPadding), { login, password -> + LoginData.login = login + LoginData.password = password + start() + }, { + scope.launch { + + snackbarHostState + .showSnackbar( + message = "Error", + duration = SnackbarDuration.Long + ) + } + }) + } + } + } + } + } +} + +@Composable +fun LoginPanel( + modifier: Modifier = Modifier, + ok: (login: String, password: String) -> Unit, + error: () -> Unit +) { + var login by rememberSaveable { mutableStateOf("") } + var password by rememberSaveable { mutableStateOf("") } + var loading by remember { mutableStateOf(false) } + val scope = rememberCoroutineScope() + + Box(Modifier.fillMaxSize(), Alignment.BottomCenter) { + Column( + modifier + .padding(32.dp, 0.dp) + .clip(RoundedCornerShape(10.dp, 10.dp)) + .background(MaterialTheme.colorScheme.primaryContainer) + .padding(16.dp) + ) { + TextField( + modifier = Modifier.padding(8.dp), + value = login, + onValueChange = { login = it }, + singleLine = true, + label = { Text(stringResource(R.string.prompt_login)) } + ) + + TextField( + modifier = Modifier.padding(8.dp), + value = password, + onValueChange = { password = it }, + singleLine = true, + label = { Text(stringResource(R.string.prompt_password)) }, + visualTransformation = PasswordVisualTransformation(), + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password) + ) + + Button(modifier = Modifier + .fillMaxWidth() + .padding(8.dp), onClick = { + loading = true + scope.launch { + if (auth(login, password)) { + ok(login, password) + } else { + error() + } + loading = false + } + + }) { + Text(stringResource(R.string.sign_in)) + } + } + } +} + +@Preview(showBackground = true) +@Composable +fun LoginPreview() { + UNNTheme { + LoginPanel(ok = { _, _ -> }, error = {}) + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/sweetbread/unn/ui/layout/MainActivity.kt b/app/src/main/java/ru/sweetbread/unn/ui/layout/MainActivity.kt new file mode 100644 index 0000000..f09c5bb --- /dev/null +++ b/app/src/main/java/ru/sweetbread/unn/ui/layout/MainActivity.kt @@ -0,0 +1,181 @@ +package ru.sweetbread.unn.ui.layout + +import android.os.Bundle +import android.util.Log +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AccountBox +import androidx.compose.material.icons.filled.DateRange +import androidx.compose.material.icons.filled.Home +import androidx.compose.material3.Icon +import androidx.compose.material3.LinearProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex +import androidx.navigation.NavType +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import androidx.navigation.navArgument +import com.kizitonwose.calendar.compose.WeekCalendar +import com.kizitonwose.calendar.compose.weekcalendar.rememberWeekCalendarState +import io.ktor.client.HttpClient +import io.ktor.client.plugins.HttpRequestRetry +import io.ktor.client.plugins.HttpTimeout +import io.ktor.client.plugins.cache.HttpCache +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import ru.sweetbread.unn.ui.Auditorium +import ru.sweetbread.unn.ui.Building +import ru.sweetbread.unn.ui.Discipline +import ru.sweetbread.unn.ui.KindOfWork +import ru.sweetbread.unn.ui.Lecturer +import ru.sweetbread.unn.ui.LecturerRank +import ru.sweetbread.unn.ui.ScheduleUnit +import ru.sweetbread.unn.ui.auth +import ru.sweetbread.unn.ui.getSchedule +import ru.sweetbread.unn.ui.theme.UNNTheme +import splitties.activities.start +import splitties.preferences.Preferences +import splitties.toast.toast +import java.time.DayOfWeek +import java.time.LocalDate +import java.time.LocalTime +import java.time.format.DateTimeFormatter +import io.ktor.client.plugins.logging.* +import ru.sweetbread.unn.ui.Type +import ru.sweetbread.unn.ui.composes.Schedule +import ru.sweetbread.unn.ui.composes.ScheduleDay + +object LoginData : Preferences("loginData") { + var login by stringPref("login", "") + var password by stringPref("password", "") +} + +val client = HttpClient { + install(HttpCache) + install(Logging) { + logger = object : Logger { + override fun log(message: String) { + Log.i("Ktor", message) + } + } + level = LogLevel.ALL + } + install(HttpTimeout) { + socketTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS + } + install(HttpRequestRetry) { + retryOnServerErrors(maxRetries = 3) + exponentialDelay() + modifyRequest { request -> + request.headers.append("x-retry-count", retryCount.toString()) + } + } +} + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + + if (LoginData.login.isEmpty() or LoginData.password.isEmpty()) start() + runBlocking { + if (!auth()) start() + } + + setContent { + UNNTheme { + Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { + val navController = rememberNavController() + var route by remember { mutableStateOf("home") } + + Scaffold( + bottomBar = { + NavigationBar { + NavigationBarItem( + onClick = { toast("Not implemented") }, + icon = { + Icon( + Icons.Filled.Home, + contentDescription = "Home" + ) + }, + selected = route.startsWith("home") + ) + + NavigationBarItem( + onClick = { + navController.navigate("journal/schedule") + route = "journal/schedule" }, + icon = { + Icon( + Icons.Filled.DateRange, + contentDescription = "Schedule" + ) + }, + selected = route.startsWith("journal/") + ) + + NavigationBarItem( + onClick = { toast("Not implemented") }, + icon = { + Icon( + Icons.Filled.AccountBox, + contentDescription = "Account" + ) + }, + selected = false + ) + } + } + ) {innerPadding -> + Box(Modifier.padding(innerPadding)) { + NavHost(navController, startDestination = "home/blogposts") { + composable("home/blogposts") { + Text("Not implemented") + } + composable("journal/schedule") { + Schedule() + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ru/sweetbread/unn/ui/theme/Color.kt b/app/src/main/java/ru/sweetbread/unn/ui/theme/Color.kt new file mode 100644 index 0000000..1c48e39 --- /dev/null +++ b/app/src/main/java/ru/sweetbread/unn/ui/theme/Color.kt @@ -0,0 +1,67 @@ +package ru.sweetbread.unn.ui.theme +import androidx.compose.ui.graphics.Color + +val md_theme_light_primary = Color(0xFF345CA8) +val md_theme_light_onPrimary = Color(0xFFFFFFFF) +val md_theme_light_primaryContainer = Color(0xFFD9E2FF) +val md_theme_light_onPrimaryContainer = Color(0xFF001A43) +val md_theme_light_secondary = Color(0xFF575E71) +val md_theme_light_onSecondary = Color(0xFFFFFFFF) +val md_theme_light_secondaryContainer = Color(0xFFDBE2F9) +val md_theme_light_onSecondaryContainer = Color(0xFF141B2C) +val md_theme_light_tertiary = Color(0xFF725573) +val md_theme_light_onTertiary = Color(0xFFFFFFFF) +val md_theme_light_tertiaryContainer = Color(0xFFFCD7FB) +val md_theme_light_onTertiaryContainer = Color(0xFF2A132D) +val md_theme_light_error = Color(0xFFBA1A1A) +val md_theme_light_errorContainer = Color(0xFFFFDAD6) +val md_theme_light_onError = Color(0xFFFFFFFF) +val md_theme_light_onErrorContainer = Color(0xFF410002) +val md_theme_light_background = Color(0xFFFEFBFF) +val md_theme_light_onBackground = Color(0xFF1B1B1F) +val md_theme_light_surface = Color(0xFFFEFBFF) +val md_theme_light_onSurface = Color(0xFF1B1B1F) +val md_theme_light_surfaceVariant = Color(0xFFE1E2EC) +val md_theme_light_onSurfaceVariant = Color(0xFF44464F) +val md_theme_light_outline = Color(0xFF757780) +val md_theme_light_inverseOnSurface = Color(0xFFF2F0F4) +val md_theme_light_inverseSurface = Color(0xFF303034) +val md_theme_light_inversePrimary = Color(0xFFAFC6FF) +val md_theme_light_shadow = Color(0xFF000000) +val md_theme_light_surfaceTint = Color(0xFF345CA8) +val md_theme_light_outlineVariant = Color(0xFFC5C6D0) +val md_theme_light_scrim = Color(0xFF000000) + +val md_theme_dark_primary = Color(0xFFAFC6FF) +val md_theme_dark_onPrimary = Color(0xFF002D6C) +val md_theme_dark_primaryContainer = Color(0xFF15448F) +val md_theme_dark_onPrimaryContainer = Color(0xFFD9E2FF) +val md_theme_dark_secondary = Color(0xFFBFC6DC) +val md_theme_dark_onSecondary = Color(0xFF293042) +val md_theme_dark_secondaryContainer = Color(0xFF3F4759) +val md_theme_dark_onSecondaryContainer = Color(0xFFDBE2F9) +val md_theme_dark_tertiary = Color(0xFFDFBBDE) +val md_theme_dark_onTertiary = Color(0xFF402743) +val md_theme_dark_tertiaryContainer = Color(0xFF583E5A) +val md_theme_dark_onTertiaryContainer = Color(0xFFFCD7FB) +val md_theme_dark_error = Color(0xFFFFB4AB) +val md_theme_dark_errorContainer = Color(0xFF93000A) +val md_theme_dark_onError = Color(0xFF690005) +val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6) +val md_theme_dark_background = Color(0xFF1B1B1F) +val md_theme_dark_onBackground = Color(0xFFE3E2E6) +val md_theme_dark_surface = Color(0xFF1B1B1F) +val md_theme_dark_onSurface = Color(0xFFE3E2E6) +val md_theme_dark_surfaceVariant = Color(0xFF44464F) +val md_theme_dark_onSurfaceVariant = Color(0xFFC5C6D0) +val md_theme_dark_outline = Color(0xFF8F9099) +val md_theme_dark_inverseOnSurface = Color(0xFF1B1B1F) +val md_theme_dark_inverseSurface = Color(0xFFE3E2E6) +val md_theme_dark_inversePrimary = Color(0xFF345CA8) +val md_theme_dark_shadow = Color(0xFF000000) +val md_theme_dark_surfaceTint = Color(0xFFAFC6FF) +val md_theme_dark_outlineVariant = Color(0xFF44464F) +val md_theme_dark_scrim = Color(0xFF000000) + + +val seed = Color(0xFF1C4893) diff --git a/app/src/main/java/ru/sweetbread/unn/ui/theme/Theme.kt b/app/src/main/java/ru/sweetbread/unn/ui/theme/Theme.kt new file mode 100644 index 0000000..b57743a --- /dev/null +++ b/app/src/main/java/ru/sweetbread/unn/ui/theme/Theme.kt @@ -0,0 +1,96 @@ +package ru.sweetbread.unn.ui.theme + +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + + +private val LightColors = lightColorScheme( + primary = md_theme_light_primary, + onPrimary = md_theme_light_onPrimary, + primaryContainer = md_theme_light_primaryContainer, + onPrimaryContainer = md_theme_light_onPrimaryContainer, + secondary = md_theme_light_secondary, + onSecondary = md_theme_light_onSecondary, + secondaryContainer = md_theme_light_secondaryContainer, + onSecondaryContainer = md_theme_light_onSecondaryContainer, + tertiary = md_theme_light_tertiary, + onTertiary = md_theme_light_onTertiary, + tertiaryContainer = md_theme_light_tertiaryContainer, + onTertiaryContainer = md_theme_light_onTertiaryContainer, + error = md_theme_light_error, + errorContainer = md_theme_light_errorContainer, + onError = md_theme_light_onError, + onErrorContainer = md_theme_light_onErrorContainer, + background = md_theme_light_background, + onBackground = md_theme_light_onBackground, + surface = md_theme_light_surface, + onSurface = md_theme_light_onSurface, + surfaceVariant = md_theme_light_surfaceVariant, + onSurfaceVariant = md_theme_light_onSurfaceVariant, + outline = md_theme_light_outline, + inverseOnSurface = md_theme_light_inverseOnSurface, + inverseSurface = md_theme_light_inverseSurface, + inversePrimary = md_theme_light_inversePrimary, + surfaceTint = md_theme_light_surfaceTint, + outlineVariant = md_theme_light_outlineVariant, + scrim = md_theme_light_scrim, +) + + +private val DarkColors = darkColorScheme( + primary = md_theme_dark_primary, + onPrimary = md_theme_dark_onPrimary, + primaryContainer = md_theme_dark_primaryContainer, + onPrimaryContainer = md_theme_dark_onPrimaryContainer, + secondary = md_theme_dark_secondary, + onSecondary = md_theme_dark_onSecondary, + secondaryContainer = md_theme_dark_secondaryContainer, + onSecondaryContainer = md_theme_dark_onSecondaryContainer, + tertiary = md_theme_dark_tertiary, + onTertiary = md_theme_dark_onTertiary, + tertiaryContainer = md_theme_dark_tertiaryContainer, + onTertiaryContainer = md_theme_dark_onTertiaryContainer, + error = md_theme_dark_error, + errorContainer = md_theme_dark_errorContainer, + onError = md_theme_dark_onError, + onErrorContainer = md_theme_dark_onErrorContainer, + background = md_theme_dark_background, + onBackground = md_theme_dark_onBackground, + surface = md_theme_dark_surface, + onSurface = md_theme_dark_onSurface, + surfaceVariant = md_theme_dark_surfaceVariant, + onSurfaceVariant = md_theme_dark_onSurfaceVariant, + outline = md_theme_dark_outline, + inverseOnSurface = md_theme_dark_inverseOnSurface, + inverseSurface = md_theme_dark_inverseSurface, + inversePrimary = md_theme_dark_inversePrimary, + surfaceTint = md_theme_dark_surfaceTint, + outlineVariant = md_theme_dark_outlineVariant, + scrim = md_theme_dark_scrim, +) + +@Composable +fun UNNTheme( + useDarkTheme: Boolean = isSystemInDarkTheme(), + content: @Composable() () -> Unit +) { + val dynamicColor = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S + val colors = when { + dynamicColor && useDarkTheme -> dynamicDarkColorScheme(LocalContext.current) + dynamicColor && !useDarkTheme -> dynamicLightColorScheme(LocalContext.current) + useDarkTheme -> DarkColors + else -> LightColors + } + + MaterialTheme( + colorScheme = colors, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/ru/sweetbread/unn/ui/theme/Type.kt b/app/src/main/java/ru/sweetbread/unn/ui/theme/Type.kt new file mode 100644 index 0000000..ae3988f --- /dev/null +++ b/app/src/main/java/ru/sweetbread/unn/ui/theme/Type.kt @@ -0,0 +1,34 @@ +package ru.sweetbread.unn.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..65291b9 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..65291b9 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..0a0496c252e81009102ec0e9ab3d294c9c91b841 GIT binary patch literal 1414 zcmV;11$p{XNk&F~1pok7MM6+kP&iC-1pojqN5Byf^@f7BZJ2~V?EN8#hzX#rCVmD2 zUAVQir;)xchL-x^-He$Tq^Va#h>5QmyFZpn_h- z-Qkl2_Ou1#NV1ho0Jwy}iPLvn-y{Ewa9VBKvYg-D6{#fOz#@l8rn3T-f}Gp7jqUlfwr$(CW81cE+x%?Z``+h#DO1_Db;1)=b}BoaZQF^% z007IT|9=ysvu)cpgTi3|fMuJnZQGoU8cF{dwr%5x8sO@e8Q6aZej?$Vv?UcaBpgV# zs1=<%gw(PW(vDo$YseRyb}hTM9i(AxH_SFkec@?|es0ky#44q@<9K zC8eg!a|4iER7vu*ek-ZMfh9?ypK1M~r(LR?R00sw`fgcfRtW~mY4ojjJ8AFnfkg^W z1Ld^3RRhpt={2!R@YK^T>k?r+xu%-r0Z=2Wo}A2LoptW$sGFO4BSx>gRzQ2wx{{D*plL7L%w|TtsPlw?-&(>LJaY*S+o<77NCeY(GV^7RzT^p{16Cv2t9MRwkI=xn!*Y+{L7T=7E=Le(xum3 z&Tvpf$uKiSM*bKrzDTDpM??siUbGuY5-CkQSn> z@tV}(vvj&*O0+mDJw)BI59)SRIZAblLqu{AM%CMl5MlLwh*PE0VC%rQz*=3jT~W13 z%rRQg!IhIHTh!=wZN!g3R-=ul2!V7;Xm5G2k*(p{lZVi!a7*@aWJ~h!{!gLLLrSm& za)efn5Z}Af-JE08pH?NC23`8SL=m$E@05C9xZsj`nZ|S23RlvE$enss*d8o z(%C%L-Fa&u$0<(fciCRn`K`k7Pe zrNx%KL7?b%z&zGHwMqQ+<+O>22*y}?PObZodYfrO8Bea6b^lslHE$_n$uYF=C%3>EwRDX^rc?sj?s;+sWQ)$c(8^r~N< z@2#iTq`fe!UObs^(%$Im(!26smhufPG^?vR;Q>)VuKE}n&9gbS5AM`D*`RH7;aqK_ z4Udj?=J$#NbdT9-oqX_ccYLv4_CjC+fQWt&0X`rBNCHyE``HC}p+C|$lL5z6os}N_ UWOnGExyIXHd1tM@Er@+o3~}P!2LJ#7 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..7011e78d8871d5ac36573da12dde6bc34a4f8caf GIT binary patch literal 790 zcmV+x1L^!yNk&Ev0{{S5MM6+kP&iBi0{{Rop+G1QwaAtv$&r-(|DX1URW*Ixi-x>A zw3da22nhfHkZqI9wr$(CZQHhO+qP}nwr$^LCLmAz|G38Bpx~v=Q;Bv{4&M6!I&1^d zh4IEw7a}?Z9+;KEq$K2o=TW;w!K0s&=y_Q_*)w@*^hPmhAd|9$3g-TtV@JTm-&+wp5gvfAq6LN)ldU{l`DGn5u99Oknvkl=aMAWJTjmB6%n}lSAWgg`^~KJq=_& zv$s{@3*;S;a2&@!!qfX#(E^fyF*c0kO#h`%72n||LFi==tKgv%nO$U5wDKe&=Eo53 z5l6e#pGTX$GXHvTzzFEQ_ z4<&64^Ikp+@l;};5x4|`Qc(L%bO)@Fl)okI9izPj0%K!8&+uLg1+YobUU#>QtdeI< zw_)siNnp^Irpt|Q`>r&Jr2;-lo_>7Y-Io6>BQlHHU$r<76oO~zpu77ef~@nYhN5o& zt#CqJfKITx-uDj64p`|QomJiKpM6E#aY8wUkdjQRFF*%9%&4!_)}xDQE3K z)*iQVbqgWOha>UgdF#*0!Y4>iW z%VJjERO|nDZ7JIfQRSR-&N=5WdFJK(-aY4BatF~;4w@n;>fUp1I27=!f(FoBO$||= z8s1t*5At<@Wj%#Lv(_Q>FcO>Ll7pv@QRobIdLX9)HlctVi+IxqYAQfeLoDIQDS@0k zK2?x&4!a8ETeprYNfJc|@2V%!v#0@`-kJ)I*=voZ0OZDEY2?Y{i9KX+=)60ifT;k~ ztzhIxTrS{BNVaX8c6QT$J5o>S_5{eywtc-5=5+lhxVyW%ySux)ySux) zYnA{1JGMYNN+!q%nFE&z7=g-R6S{aRWP^0LZeS%dG^g-=;YPb{)Qj|X7ua|B|sAD_(bLM zStI$Oiu`%vCPhxqd#?4JDrN3|uL7{_c(QyzmB_Dh86AvxN+WsDh#^!K7#89cjb-wH zvjE?U7ux|AjmR(5tP?gKb>Tv&ig zCkri-WsL-a)-g^a=B$oVvHEX-6+6d)s!B|B%t5DkovJ-|wb`nA zoCW>voRJ^Gs2}0qzd7e zzAe~PD$fO@lnMwCnt4j^4;n0O!#|`60L9G8W1ie1#{O}=ue`F|NNn|FaZR9l8bsmjMBVLeOvdvQp=hY&^iQxC)rrY3PemYwC)t92uj3kl};)Y@Q$_L}I}& z@{f8MKq_Z8_(@};YM6N(z+?)0fB?hC5BleseRWudY*hP`gaCsbHvtr{Gpt4v0V+>g z18%WJ%g|!wTb|#u;9f z<(YExa9L@>%Ob5?5jY_hs!fOzX=)y-5s`op@`^<=tPq<3lnTcQ!OX;HsaJCZpt1q@ zCMMyDN@u-bfZkWdg6?^i=GCsP-#Q1VCG_Xz=p7+Gm? z1w(1Q5zHsHC`x?&NaQSKQMRZ>cy{9Br38E*1asDa#3P#4TjL)}zPy49qkjZS*=}qH z0DstD^|6ogFM)O-k(Q-ipArnY;QKxSn5%Wzp-eBOGaK{AQOpDc@EG)DP=>uJIpf-T zZE*T6e^wgtAyLk+l3=1RtG*C`&G%swfU&~5ULzi>DQ)+vK*X1}-CjlEaRAq5r>eJb zwA(3mF}2y+V3107&F3R8+kiy?y29MCL>MqefgTqDWyqWM7}?{N4MpKa`ymw&Lfgi7 z-Gvrl6M$x+M&c|~78tBN3{WOQr~-Kb;rNH{XMqaZ9~7aO7m1{-G7+40KPlU z!$w@;a7(#fGIKHRk0Ef^lgJ1Gc4Utm%5zHRk08lqX)yPrz0T!aA3zHM*ejfwrc5sc z{c?}8D4jPD5Won7UQL1!N}5({<_SW6SV^#Cmr}Mw0FD*_un54^sg$MBw4O`etl~uA z_It%bM3HW~o<+*p*zqWfDBK;3ryfXX#3VCs=dGY27vd9uc7oGPF`(#?atW;Ld*e`? zN_P^jh#_C}xC)fg=^%?D-#GNT@gj>iVqBI6`#kntPvbQ|1O@RIIs$MNXH++3dM??c z*4RIez@xr|1v^|K@OQ1Znq3Nw|D&334I!DAc-m3_2W#cs8LkP(6k&8Me-9se9>UrU zvrHddG9sk|`{o-Rg-3o#shx=xLeeiK>ePrYX+Fv3TA{MAKB{zeW%!4(O!f#GRuTD> zmDXdL&6Q6>OE`?by`v|9KuIvGl<6Ugbk+ODqwtS1omdd+3xs%sz^FbS)dnnV5Ios5kxdIYDG;BgvSdZx!SD}s5^%7b= zjD5UhAb?Oo_Bfer)dTY9r7=Gog?a1MGr_1g5W{nKMao>SEAJ=Y3&TAjd^Xd*lFfDB z7zPXCpl%%ZVQW%p!&ku#xa5c%!#@-fGmit9E=S3^+)2$LjWbH)j?%c3edT(wt|!Sv zfMB+1w^IeBJ|NCzN!olJ?QLz@ICl{=Mlg5rl7RpM3${Ni-mfzNZF+BTU?a`sA`6SL z0LLc3)tlSGa!(LX)>WB+IR~%xZ_LuzGs3Vp{OgRB08)ARpT$hp01#h4=yZ}PCT&r; z%$>467&geHA3gU9QL6oXVEIp3#?d45fld1Z58>s z!|7084eh(9>wy-LPS@Kq5rBV!^V+%G*{_lrfi|hRXtmW?DCXGhEXopg)}#7N7G=%1 zvG2F;|6h*C$KTG_2p}@k{3@!_SR$DbV2Q(&U9=<3H-?OUFEIH9gG`orO{QI6#uGqv zUoQ&Y*vByk0VHOgKc-e#OJp`_1Taf%tfrorCNgc%i}Afkm5U}_%mgvnDzBJvcAJ?V z^E~485KXsl?Tm}7m{M;(Xf|mG(7xE$cx4&-rZ{&z$SMs&nfzWX`D7)?$*d^Kn6Deu zj(#0+xrnYi+TDPg0Fo13R&E7Zbs7*tPi{=vyyqQx`NQdW_Z!did$@?Udn5tG+x$0l zJ5;izD&rxuiC87F^5}N8WTnl2UGIk@T}0m-cRyh#fG`16=ITGymIVENhs-8ok;uwB zN`iWyee~2o0M$P-9%AW@dJm?dzPf@0kQ?K9YTve=%v4whMHrItXmKW!7cEjxW=DS+ zIjlM0b`LQg*n>1h+PaN~QZIIZrhOhiV?I>uBclIEQAbegd`DKphN;E|suId4J-)ponx zLtJh-M#5q5G-* zYX@wxE#h|DrV*ce{1*^FewSgs+on_R&SK^sJU6$ke~)%475n*lbyyPgZAsd_lw14p z-tX@eBy0u`g}uwLg3=&`X7F%Z@&2c4UcTP#)WA; Wm%!5yB(&piLEo#_=dWMudWbPEf8y)_ literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..5f07e410a8ee33378c0d7809d8e7ef09a33a1e86 GIT binary patch literal 878 zcmV-!1CjhvNk&Fy0{{S5MM6+kP&iCk0{{RoFTe{Bcjh*dBt@!2?ZKq?_f2Dx7P=ms zfZRrsBPn)I`)}y|R(2I(N3yM2>F4j^_DL=zM7*ToE_)!yww*>glA9S4z$h>bPN~-& zUaxsK3=-J@MPc^_K>~@SOah6dAj3ZY7hq6;5EPJ!02UWF?LB}3viYwYp}2rZP7tAF z0tBe9e*joOCWb&nHf}^F<@N_ChD*-KBoj6wlWd#_B#Y8d>f;}vWFq=|2sa{U2$3^f zEWiNmJ)9V9`iYWB4vNSGWYgb6DE~VG$wC3bjp2d_1qcfO29gCJ22flS0W1y{AP_(c z7AjFpq?p&xG7T*fDpMgX!ayUMEmncQzmMgz&(-ELug{YW5^LWD+6TmCPXqrd(C?s)4moq7m| zB)W^o?&Irsxu!)f`**d8o6F6Jk1d6?YugOT>2*)9ZF|EtV>{W{wr$%S)XaJ}b|&69 zgZNK%b$8Xo-}>!0qW=>h{4QNy?x4N-V1_F_fB}xs;M4aI6<4b1$O2>2YTJvnVO6*Ji8An6Z?Zxlxi~-@R)JB!$qt zWwq;>!P(vvQ~CBoBa@;e(PSi#*i=9K5##bzm7aBKVQW~OFKI5}O^db5?%-_ivORn)xMko8_|T+V zbVQ0@N6-GJXE E09Sdar~m)} literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..96b0555ade1f87557516838da2d2bfb44f88732e GIT binary patch literal 534 zcmV+x0_puyNk&Ev0ssJ4MM6+kP&iBh0ssInYrq;1l}K_U$&sY`|EGEAndqv`-0Q$c z3ttf-2>`${lCrjK+qP|c_hs9*ZQHhO+cwU|a02qQf4p2IYqsvflYfwHy~EiUO2(WL zgOFpy56Mx&1ld-g5EX9|q;Af#*!pjQ2l`!L7Ucr+_KLQkCfLH+0Nro!K73JI?~+k1 z#?p3&*R_7gSgYe-p+5XpJU!jQL!#vrXCrrO`7#25egH``nh&4{8yQ~9&ZxM%o}q`yMG~?$R2QRC$v?Z7 z_=;??h@a_8$p5*5PgchYHi96S$hyEJH2AAU`>0l+1-h}*Tp$zkx*T4xQ3WS(O`YTt zJzoDfEElCSP=*Hxbd{%=L4wG!SD5P|_A;u!G?K7*yUQ;@Kk&_#V>U<=Y*Y|_P!14y zLOqUrmyP-W=&jZa)Ez{`tTm4F0LjmXd~3e7_1~@rX5R-0TOS~O#*{5WQFBK@)e_4s zG&s-CFq6E{wb1%UC7Xn%{f@SdWHZ44HMj6-NpscKzt?ONhT^+!{c`=^>5KP2z4e`b zcFM>96UHxuvRBgISExsDfZZaJ4|e(@2Gp9IX4?UZvZ1Nruql};&VB^G9`0*Hs YWdZ08uzR>H)Ov&T(TrsJi1Rdg0ImKB0RR91 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..19d045c69a65f3f4d7d7cc4841489418893b0ad1 GIT binary patch literal 2018 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 W$#m7-*7Zmsh2R9-{D1TR&AtG7toqUb literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..305a8f7d002077e18d7fb45705e877799a27cfd1 GIT binary patch literal 4376 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..f7ea60aedace7c3348b49b0cf9a4a2a5e2e3092d GIT binary patch literal 1550 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 KB?sd6T?7CcA>V@l literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..bdefa3f09987836cc65419bf4dd90fb52998567c GIT binary patch literal 2062 zcmV+p2=Vt)Nk&En2mkIYh!6lEcq0fw;o7z{lJus~8r!yQqjzlEwr$(CZQEw|jy-L67v5h` zRbSHe=IifUCZhin0EYh!{~P`{{BQW*@W0`I!~cf=4gVYd|DTusg$oxh+@}5tw`)+_ zW3B%pNFNv&xa0I)^u~92C0~W1Lx&y@3i^y*JW%TSj*mg_mwTm=qI5HvOuE)KIQZ_c zfhLnQ%3HK<2x2uIQ}&|!enqp(pY%;;osC4-Pi7rE;Q{g6*%3`F^2VHf`1r5LXwffN z%i#KActf)yVKNR}9g8aY;d*L7M!8a;*_OAco-c@RHZ{vHNfhgdtD&eVZxAu$@^G{K zDA4x=YR(}<3}4eHz0_#BAqJC?Pl)((KygW7s~Mu>A<2K( zh5zNU!tkHrKf`~9{|x^b{xke%_|F*Hy1!a1;eWL#r(~DU9lf!jq^j=;E~fa0X<^Rfen~6z=+KHw0zKG7|3? z;41~3u34ct5}kyr2#L?B8J?4{SJ&z}l58SHuqnfM5_luCHY1Vbx6Hy-*g;|nLn9ja zqlpF?SJ-F-fq0)GafTrk5wx`nP*dm$5*;C6Yxsn?uL+a?kQk(zPr#axh%ewt8Ak>k z_eT%*Rlw?-arCyYNcOQwz-lH^z#^WY938iZ*9Rl*H6Y@Dk{HL3`WY?y4W!8$2I$GP z4_Sq56A8@B(8$KKi6G=7XbfS1TO5n6BxdPpY-0)J*bxwO(`6DL(=enC<5v$sgEb_u zF#}BH);p`HRitr9VaWBBSN%ZL3q+H^0t_&lQ?D}$8(g5#kR@v*pN4?Aw|A0Q#R7A< z^x03~;3ElpW)|N&JgNjDzmx?ozMj-rGXgp?ua&a7qnF-=Qn1-V{6LhxmV<$*J z-;X5lU0x1yE=pQ|p@Z=>aJ7{w;1n;a0{~>&jc;-aUH*48ur?EvxW|RiHWrsT zh`2%MU>%W*K1@&{mIKb^;9BS#B7PLRjBjY*cs8gLu77L5)p8CIakJRLFd{K!*`PtB z-mSH|8Hlbe1kd+34ZN3%4Qj>fnscocT+4*H>`(*`78AjdDxhA3o~;M>JJ7Wqh)?rb4u&Wp__6bJ!PeCGfqk~uTr~)Xy zmE6OQ{=nEj5k0n(38uYt@O4o|6)44aI|(_SwDAK*|Nb`gxK)t}kmU{?#330}0YIB= zF;t$m2j&bb(DSuSAQx-e2;rr48UU2o^nt>Y&H=z&`67Bwr~>GzSyu~yfB~ly zyz9&4qJF^a(=ZVk4}pAKO$npt`DpIIY9~Wc}r~o zpiqy)UhsTTc`K-H`3zY@s)CI4i6DiJ9fdRkFr}?IY4gvY5t=0a{CQ{6q>_H1zR-3D zvO2qhoU9Q_3emBqxJDjxbr^I*b;p{Zak_pEWM2ldvUUV5#PGGr;>}%8qskRlX#rK7 z#1Nyl<|miB`#V${oEs$OMskR@{q6EnD%$5Is(zmzWTx*1dWiUaUKT0^*M*__4@E$3 zng{6tV(hOuWwLskHQSW?@u*=$ZIGSHW?gWNKhUa@7nK=t9<}}49OS3(X1zefq{okY z_pFk9ReN549E}=(ECw>vyh%UYCViPZcTA2PIdYg)`R2%xqw(Ci-;z-K_k}@@n)-(8 z3gd}`u2T+rzJ|&Exgbc>1~Izi{hv#KM6Dg00@zywq-vuV+}ospWKDOKZ&6cxLAnMk zO61s&Y9M9%BysC>T9CBmf;iPHEl6AI90!MnC?k=LE@H=?Y(d3^#%FHBXG? z$f1%TgGWt>^2 zVQD}xBMqav`&ni@W@ct)W@ct)W@cuZr=Nbhe@{RCM20pWMP{$(jNw5%Yj!jTGTSmc zyQ-;`@ff<=%*={(HOHXZDj6p<9G#`Kt3=~`80+Nv?h z%pJL=&5Xx5GE%p-J#Axsmp<2V{`1V7ev-^=IgTNmG_8Y8!^~(GyxX?6G}^XpTdD$a zcTXxr@xYGl=)P|ob?VP^eXcdXD9{2xu#MhU+vZrivvIa<+qP}nwmI9jmDzQhd|0q; zRc-cx0{337N!kjUKK`Y9LqQ1qzgu5^K=(91{|mF}%a02pb2f zNOG{LXiabF!X0dg@>Oi^uQY}C|DX9>`rEr{f>m7n?cdD*VtCX4%TY}u9eL;HwuB3O zWY;sl#EL}e=qc2}##)L~7LDRK;@>?{iesC8k{6**^dO4$2Po1XJW@|bk(Q%KTT!I_ zC{inm)PW)eQKS%xgthZr?j8>L&!1|wXS0d_KaBl9tf!UYWNqU>FBWSXex~eB5zTwT zG9LXswP}xL!W}!%JEG87GD@Lh-q(~EtB6i|jZ?KJ1I?al>2QRs~vADzH;qT2n zQcvPrJmo|_vRrZ{->|KVJ1l;q=^ zOQj#OArxsm%d&QY7I7KMuq^xI8~PBb)Y?JP^0f44nAkMpH7L?Te!N@*#Vn1SAKnp4 z>T8?+iAj=_CLD`+S{IbiGJbp+NC|29;U!$2Rw|W{Gl)&NG@MKDToh?8L60gOJC;37 z9@07C(r_Eeur2{b`UmT6RcKHAsj+|+FF^u~SdT*~_fAkk?JOG;3aO_UmRIs})qXlfqrz>ZcY!|DZwZ@4-AO3Hx9>t~6Hdi2j(~$uq(wwlsvA496vbdH zih5x@#4Ayx!)%Nlln4dKuqfhTE|FJZQ535VD4`dKtP)`iAMuq*mloYf7QFMyii?Vo|i+zcV!W?qo{D)a0e-e(upWi6Irz_Ei=0Q(WKT> zQ`n8nBvsAgqiGJ%z=*8rUOW0|B_R2Q!>}o%TAeC&2p4-F0qBMjampTm56Pn>7SD)Y zuIBI!7{174H3Q6l4A6J=&fuD565tUzOtxlL^E0*L?pkZPq&@+#E}>fcy-wrYGs*STNRx}c+L6}PLi2(U3s5Wt*_uJEPSaY8xpL_5 zr~?71C?)OasXH1|e`iYjp;>)=W0*MrI3#f~sMs>=&u@DvPxpTxf7R4#Z_#i8O6U-c%+^q zT5XOA{d5DP?;T9-*vIfi34~~NUk#I3P7SMmw>Xt3C5v3nPv&JAV%kJHNVPmt{~(ID zMX}NciyL0^hCiR8FwAT|zpQIqlZ}B#wllDYeTl)>b6brp+Xm`8-0K*%(N`fb%Yfkw^})A8v^7P+W>KX!*7jIkTrWzEg&i zcq{~OvC#vHAhOX^=R8+{;TiiMf|g8+nU!%6U~IYMxwN_zYv~G2XlA)!=CGU8X@2UF zz-<~wkLMAb&u$gc6;K|K#!Qwr-Z-Xc7X;d77x7Z8r4dAEF3i{qZ&p_XY~wrUXdb~C zn4eA%!EIqC^J{6%6Tq6+Q)iR$G_0jFG%%x@NghQPt6vXj&Cziw{*JYD28_urR8l+f zI0PV48xG>nBvnHe%_`}QU_}Nk?J&xJjsi)tASVu!uVY#04Y<{;QpuD@pExZDz@J`Y z1w5opteozUbEuS7=i3s+KYi74OJ0P?IAs&@N|x2o9h%TgN-nt{-r*!_u!9-_h~QHE z3yY>ZU`%W(C!T-+#HbxaZ8K_V1B!T%Rni|yE=B1zemF_N7~#}~h|xL@5qGnmkp6(4 zWsNy|N+(({0{`o-?&0_l!zDO@X4pWs=L&SvHs+2@cJmWs-!>ii*vpsR5`OW-h^LaSIZ!PE=qR(%|%>V(ii zVA7&dz$LVqmD3Oaf#y~mh}XK51ja2vgpf#;h2;vsoUIL0W}FB~v$8Qso&kRWCz`eSNJ*E|=hP zdL&KtlZ)D%jyq&0X;!;Sk` zVtxn#h)uzr!8}5(Gz**7Oxqf%UypV_Pa@9KJw^UA?9k|zbb8X+==1G3_qe5PECK5C zbT^DY!+1#TbW2*DcQlyXk8{5fH32^)GxF`BC}IoUl1}HX4K=RE%FdIB^OPlu-9bEp zO>`TQ)<|07Cfbp*8zCls#ckvv?vq3YU(%g{I7wr~2kP!WMibN1!8uyictx+_Qrgan zpAo)l@{`WcYflBmxo)Pm`R+RUKSN~~Ow4=Uj#wE(|Db7x_^e`_Ul&oj7O%aF6Wk76scHdt>ndow^1ySHL(7>@*K=wL_&?1!P zMQMWbB~V_Z5C|pBoM27&H?uNXPX`c9#4F1XfQ;+{&H|z@c4YduHc%$MnprBJKHIUY z1!N8YM%z0QN}sLROj89YBTFtI$iCf@NyZ*qi~!`x5YQtDaYq2svx(wAAo^e>rhV=L zWk!#d)|CREW+I(o0U-ZTUt!~K;B(CTVh zL3~J7sr-V?2S7_wWs<8YP-gY{4gVcJj`0Qqs(biiVg?ae)&xrKu7SuVmJB2Jw~*7& zX^Gez0+5zTPM>F$05mTO6J5?Qpc+D1hhxa)H(<_S@k9ls<9y{$!^E`oAcc;p55)sau{I7 zKH6%AA`t9KG*z~qDBAP>B*}@8I+}}k1R%x43(jLhH2_?9XP``YG1oj3__U$srnDO( zq0H#6`p026?)vIP+EO!pvSI_seT+OgoBVF%3>aX3?9L$o8aADth8n9quV2pv5!2np zDh>fiZlYq0;8Hrs1_RKxmgxkP4J{iN_=fozGL-k^a6WKmbZ_a49Rnda)ZC5^)!V+D z6jsw}8Bd71hhvCA0Fr7MY)iOQtOuIdf*?%q)&WWf{r5ePudeel6w-v|3l{@{ZX1~L zU~5k&<65hlrx2^wN(oXSphdYN06E#jY64pdfM%KWOAM$++d0C&yi+~&QHX*=EWd$N zg?u5&^4=T-pwJb8bF^AY1OgCwst7<$%)E<1zJ^(USQ2%Z>ankFJp)D- zsgN|Xzu(oVs)z}!ZZ}Cn05Z)jeg|6yB=A#alB$4Lo)^Ti%g3b-BYM3m1_GB-$S#AL zYOj()j;n*(0ce;G%y!~8L7@ZxQ0IWXj_Hp+jdApk{T z2yA1Wh*8^LlUG_Zc^b^I>=$Q1^&0pUy%ni6naum}#n_LLKj91@KQi1c#Oya=nL12)E02E}F^B>uKKo55ks~HAVv&_D=spcR~zy0=NXXYP@qk#}G zGK*9)jO_o*-S_qAv_f!-s(IQ^M*wn7Ja$KDs0M^VMwY!YpnA8(LY&&0=BY>Atb3_& zvF|+30w9~lbb6}s+T&@*?#=rdQBJ~8tE%0PlM#UIc!@TW!{jco;dy-{Fn>7MqCwzW z^f<3jtnA^JegGC2;mcLt$!|x#0%X%=#>0KJjE*M;RdX1nN^3lc4ZVe(-DAPJ{QjS2y^&X zdG2R;80W%!6+lVh_e^9l2fo^kX|Q+35T|tv|5-DOtVw)KdNc9)5YB6&tGWEl7p+G0 zv0XZyYrOV+-s61zby}e~*Wn;?O-d+uN$2(Sa8m8Gh;SjR&ATUit05TDP9_ftYR|qz_ z*rZky46v^DZv{8{^A*p8B^`So%>;ySo^Qc0S5XLHcG)BaXF`Mv0+S>aHWof~@6NK9 zg#Z*L^Q{{K*kGV?{VN9lyxq+%1(u9vsWgblGM!6@IO0-1FnvGYowrn);osYo-4UIw)+_nQ;U)?n(h(*1T>t+O)S72oAesjRQdgx+o6`` zk3||*dG2K*00s58PDf`Gb>z~@GuONBMBvp-VxYb*O zD}YgGl&!N_e|*81+-Bqm0ro5#4cz4vwj&G)6At5cixHeE zm;KBadx+qi!9*7`Pu9FB#p1p#M&CUs$p6Y2(_pU{K&wdQhQYY6r)&KxzjkvX1F^Aa zLw^K@sR%$m0?;?D&L;+x0s|#vz=5k1QZ}wbt353c3ThGUjk0|<%}Y;Su#?@IKH)fb zhySK{gb6Jca0}bp_eM{FTrp*q3x=UJ8v!WY{C)fDv?789*Rbj2Apkw&SB$H(3l-3& zz~SX3qV7~MyxkaUu?T)5%^!aBj@PtleTIVkO`xAqRED)qMw2P7AOPha2=p@q zqD2h0s(#xph-j+vyf&*;g+eueW!d}2kfOCsd^t6cyhF&^U7$6!)ZS)>Qhj;fPoC0Y zNI;X>j8z;&Y#dRc>2F(`;1}~WPhEeh0`Ui!a@Jl?=XAAiWw%a2Sd?HZYT}HN9)w{tl*KYE>@80lYt#o-5}oz=Lc&7We7l8j;4W^ z+r=4`tbV~?56ZzS*3R2;mY2nzv1UH$o9E^D+9vnLh@-)n~~h6VGp} zvwyk<0Vu8d*y`g_T7|VF6rF#VS0xX%?_3Qd`?VDXYak>c#iUjfv-$c)iTBvXHD2q3 znSc<~W^P9suRT7P>sq|R2sXSVOgYG02tc(7XOr(8Gm)SL4x{!kgIk;U+4xW^PnZ?d zmR?IGDw?wqfSO#D-l3Rq4)_!VAQ1t`s^rn?eK$Q`uEv_%(dKNTPzsWvVlO_))zle? z`5me^d#7UH^%{*LXIuAni(~I*e|F_cFb8}JW^%0R)GC>4gRR@uAN&D+kQ5#Kd{-*Y zoX7szd@E>>B@9)DvpCe|&%^}US`8a8-6alDARMel@c*$T$j=o}B;yMB5 zec(YCOiO?yR4zrS+(4ss?bX}9{LK^C$TF37L7-iXfLe+GR3(kvFEVJE`DsWhh5G0D zev14_*v+wvA7WY8x>`U9g5Z?VnA@=?Yp)**p9TW$9xkOtvVrX%t%C9wdCBDdXIw@# z<2OG@l3EmnVbvdwigYHk9y`-kckGvs#V-RQ7tjI@y#5TdomB?1Ut0fddU4 zxegSZ6;F7vFo?*qKqyQ=x5*4+H_)^B=JeY>0$U%VAaY|6fJB#aRi2f~!nF@~XP9_F zfZT!-w3@Ehy)KZ{1*dcA+Ud!(qi3)lX~e9^Fm!j+GG3imxQdHfRnEmVN~e~Rk6Pz% zwJQXm_$CV1F*uxK!dU=wlBxoIv=c+Fyu5r~k!~~PK7;4n=}@aLeXVaG%$6so%(2zG=MfRq zK(afF?W-L*k#USRZmARgP1PCSRc|qc?a1N>TQGd*5iV5)$(5o^zV;Ir>~%exFHf&f z#YL@l^AgA|zT%jt^9nU@XJd`R&%E>+$DtSshU9ArZECr9KId~j=RwD&esiX`2KUAV zAo)@#HC-ku8H>8V9Ufhwii=W{$8kOGxa?vpDp^s-JUO~m-IPIwp*_CK4=4pCNeX#M zb2}8jtWT-x)*Moy^E{44Ww0i51OtHj1SR83b1Qc55>@02G39|Ks?YEBg}ZX& zS0}8ByLh?9N!7~21^~59R3Fcp@vxk(GPm@F))90IM9 zBQpS~>Cv)xRFcS^f<!|jeLZ}v{Be~cMHf{%1Odp)6DNg= zXm0~(_HVNK`oz>@EhV@VDJk27%Fq(O-+1Hkg#k1NdPna(Px+A2Q96F5PO*H zh3(42H%n4FogED|Z*Ld?^!JXwH(w6~ zAS+C!auT76{kVbt2tZ;;c{c>01T*$*F+MSVN&nH<51Z0!DX3IZ%A!yzxfEqkQz?Dc z)MWMjOHY^MlbyGJWIJ>#AL8mSqC+Nta zWjIulD=E~I2b3^%Sx17hKB?Bp{z|>~(u(`q2CXNOI0wa|+^sNUt~jYuZID5&x4z!a z;pW5zbEcUabf(ubAAoffROy+ytTSQBm{nK*bgSO`51%L(X0>t`2%}^t5HsdT8G(RW z7Ht4(t+N3@!)6ne%*iG>)|%GfVtJ$vDKUe%bK6-mp?zbYwI(Q;Q(ohxoVOqS?-3rm z!mNRUJ*paAb9$BYML;e8hV47+>lp4Yk6(WOnj-J*u`pxT$fZcB)QGF2P-v7&*wslU z5B$ANRbIcXRPVg~rM;GKIj@|q0#@o4{ux{r=2PBpWySfOo-AjlG}?H)V;I^iQ@KHK zVfU$>uq#RIu4=S#d#{I^*(rMLTwQ!+e&v0_Wc;%=zEau9pX5^B zZDqxyE6eZG~fVj(5EOdfcF1Z87f+~oFTk2b>-_0HZO7+qv#ew%k$PicRZ z4%d@_BG7RuU(R=jaZ;#WT1U=$ea-vHiSd%3hnuSCe;7vY8Z*wC)0l~jYVO`~u6)57 z1ztoi7f$mF&WH0^GU39~8k`vqnvFtd&Ar5JT^_A@KR)TD^v)eEt=%2^mMbsV<5!95 z_;}go$@N+W8PphLN*&)&?Y%wnOB-owuO}!Q|KFC0#}1iWvG&WxmJDU>JUx||@(D!dsu6pc!+)gdy^(6(b zLGSE+%^$e@*V>`4-{ymIT167|B&`z|S@IooaKvOQ)z*mDK{ zYm)P~9&56|U1J!zOP(b`+5E4m>hrsUjh9>=@9-z9yf=qmgI@3K?0wKnYqtny@xbC; z-J=2pdlJ}j!i5)g@!Gs!#LDgl0kyJSgG{aM_?itsspE(0^)Gb|-BkLa46FXqJF2_; z!3jOwOi%0aYI;Ub7t^zPx>%fbocDPH`*FG5T*FK0_59dfTyw`8X}80>Sy_bN=Dl2s z;^LhIdlG3-W8wCEgHI3wkY|gzc37l%w|}^i%CAaeHCLtank&zseizO{w2Pa+=JPqb zjr?J^#f$6^^VyaU^5I+Tv3ND1MN-502AL}Yket&e$kC&mTZC_}9o|imxpvs?@|PbS z-7%)<=;bfJ+YaYi@-#xOlRoHrRhWNPbDk#Xy z%gfObiwg?cm5WbE&h>;@m5y}xx5xPiEc9W(xp1LT{{HT=$jH*Ju2wj?x|WWNl)3x+ yN8w`mJ|YVZh2o~_0s{k8DwRD>DwQfQFi^*zD=e12T>Nx+Ibl*`!snx;PYM7i9o@YE literal 0 HcmV?d00001 diff --git a/app/src/main/res/values-land/dimens.xml b/app/src/main/res/values-land/dimens.xml new file mode 100644 index 0000000..5f681ae --- /dev/null +++ b/app/src/main/res/values-land/dimens.xml @@ -0,0 +1,3 @@ + + 48dp + \ 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 new file mode 100644 index 0000000..d720e84 --- /dev/null +++ b/app/src/main/res/values-ru/strings.xml @@ -0,0 +1,6 @@ + + + Пароль + Логин + Войти + \ No newline at end of file diff --git a/app/src/main/res/values-w1240dp/dimens.xml b/app/src/main/res/values-w1240dp/dimens.xml new file mode 100644 index 0000000..7e06511 --- /dev/null +++ b/app/src/main/res/values-w1240dp/dimens.xml @@ -0,0 +1,3 @@ + + 200dp + \ No newline at end of file diff --git a/app/src/main/res/values-w600dp/dimens.xml b/app/src/main/res/values-w600dp/dimens.xml new file mode 100644 index 0000000..5f681ae --- /dev/null +++ b/app/src/main/res/values-w600dp/dimens.xml @@ -0,0 +1,3 @@ + + 48dp + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..e00c2dd --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,5 @@ + + + 16dp + 16dp + \ No newline at end of file diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..38e41d3 --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #1565AA + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..01d78ad --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,9 @@ + + UNN + + Email + Login + Password + Sign in + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..446fbfe --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +