mirror of
https://github.com/n08i40k/polytechnic-android.git
synced 2025-12-06 17:57:46 +03:00
Релиз 1.1
Исправлена установка группы пользователя при регистрации. Во вкладке профиля добавлена кнопка для выхода из аккаунта.
This commit is contained in:
@@ -32,8 +32,8 @@ android {
|
|||||||
applicationId = "ru.n08i40k.polytechnic.next"
|
applicationId = "ru.n08i40k.polytechnic.next"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 1
|
versionCode = 2
|
||||||
versionName = "1.0"
|
versionName = "1.1"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
class PolytechnicApplication : Application() {
|
class PolytechnicApplication : Application() {
|
||||||
|
@Suppress("unused")
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var container: AppContainer
|
lateinit var container: AppContainer
|
||||||
}
|
}
|
||||||
@@ -4,17 +4,14 @@ import android.app.Application
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.EntryPoint
|
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
import dagger.hilt.android.components.ActivityComponent
|
|
||||||
import dagger.hilt.components.SingletonComponent
|
import dagger.hilt.components.SingletonComponent
|
||||||
import ru.n08i40k.polytechnic.next.PolytechnicApplication
|
|
||||||
import ru.n08i40k.polytechnic.next.data.users.ProfileRepository
|
|
||||||
import ru.n08i40k.polytechnic.next.data.users.impl.FakeProfileRepository
|
|
||||||
import ru.n08i40k.polytechnic.next.data.users.impl.RemoteProfileRepository
|
|
||||||
import ru.n08i40k.polytechnic.next.data.schedule.ScheduleRepository
|
import ru.n08i40k.polytechnic.next.data.schedule.ScheduleRepository
|
||||||
import ru.n08i40k.polytechnic.next.data.schedule.impl.FakeScheduleRepository
|
import ru.n08i40k.polytechnic.next.data.schedule.impl.FakeScheduleRepository
|
||||||
import ru.n08i40k.polytechnic.next.data.schedule.impl.RemoteScheduleRepository
|
import ru.n08i40k.polytechnic.next.data.schedule.impl.RemoteScheduleRepository
|
||||||
|
import ru.n08i40k.polytechnic.next.data.users.ProfileRepository
|
||||||
|
import ru.n08i40k.polytechnic.next.data.users.impl.FakeProfileRepository
|
||||||
|
import ru.n08i40k.polytechnic.next.data.users.impl.RemoteProfileRepository
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
interface AppContainer {
|
interface AppContainer {
|
||||||
|
|||||||
@@ -7,6 +7,3 @@ sealed interface MyResult<out R> {
|
|||||||
data class Failure(val exception: Exception) : MyResult<Nothing>
|
data class Failure(val exception: Exception) : MyResult<Nothing>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> MyResult<T>.successOr(fallback: T): T {
|
|
||||||
return (this as? MyResult.Success<T>)?.data ?: fallback
|
|
||||||
}
|
|
||||||
@@ -10,9 +10,10 @@ import ru.n08i40k.polytechnic.next.data.schedule.ScheduleRepository
|
|||||||
import ru.n08i40k.polytechnic.next.model.Lesson
|
import ru.n08i40k.polytechnic.next.model.Lesson
|
||||||
import ru.n08i40k.polytechnic.next.model.LessonTime
|
import ru.n08i40k.polytechnic.next.model.LessonTime
|
||||||
import ru.n08i40k.polytechnic.next.model.LessonType
|
import ru.n08i40k.polytechnic.next.model.LessonType
|
||||||
import ru.n08i40k.polytechnic.next.data.MyResult;
|
import ru.n08i40k.polytechnic.next.data.MyResult
|
||||||
|
|
||||||
class FakeScheduleRepository : ScheduleRepository {
|
class FakeScheduleRepository : ScheduleRepository {
|
||||||
|
@Suppress("SpellCheckingInspection")
|
||||||
companion object {
|
companion object {
|
||||||
val exampleGroup = Group(
|
val exampleGroup = Group(
|
||||||
name = "ИС-214/23", days = arrayListOf(
|
name = "ИС-214/23", days = arrayListOf(
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetRequest
|
|||||||
import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetRequestData
|
import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetRequestData
|
||||||
import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetResponse
|
import ru.n08i40k.polytechnic.next.network.data.schedule.ScheduleGetResponse
|
||||||
import ru.n08i40k.polytechnic.next.settings.settingsDataStore
|
import ru.n08i40k.polytechnic.next.settings.settingsDataStore
|
||||||
import java.lang.Thread.sleep
|
|
||||||
|
|
||||||
class RemoteScheduleRepository(private val context: Context) : ScheduleRepository {
|
class RemoteScheduleRepository(private val context: Context) : ScheduleRepository {
|
||||||
override suspend fun getGroup(): MyResult<Group> {
|
override suspend fun getGroup(): MyResult<Group> {
|
||||||
@@ -24,7 +23,7 @@ class RemoteScheduleRepository(private val context: Context) : ScheduleRepositor
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (groupName.isEmpty())
|
if (groupName.isEmpty())
|
||||||
return@withContext MyResult.Failure(RuntimeException("No group name provided!"))
|
return@withContext MyResult.Failure(IllegalArgumentException("No group name provided!"))
|
||||||
|
|
||||||
val responseFuture = RequestFuture.newFuture<ScheduleGetResponse>()
|
val responseFuture = RequestFuture.newFuture<ScheduleGetResponse>()
|
||||||
ScheduleGetRequest(
|
ScheduleGetRequest(
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
package ru.n08i40k.polytechnic.next.model
|
package ru.n08i40k.polytechnic.next.model
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
package ru.n08i40k.polytechnic.next.network
|
package ru.n08i40k.polytechnic.next.network
|
||||||
|
|
||||||
object NetworkValues {
|
object NetworkValues {
|
||||||
const val API_HOST = "https://192.168.0.103:5050/api/v1/"
|
const val API_HOST = "https://polytechnic.n08i40k.ru:5050/api/v1/"
|
||||||
}
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package ru.n08i40k.polytechnic.next.network
|
|
||||||
|
|
||||||
class ResponseBase {
|
|
||||||
fun handleResponse(response: String?) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,6 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import ru.n08i40k.polytechnic.next.data.AppContainer
|
|
||||||
import ru.n08i40k.polytechnic.next.data.MockAppContainer
|
|
||||||
import ru.n08i40k.polytechnic.next.ui.auth.AuthScreen
|
import ru.n08i40k.polytechnic.next.ui.auth.AuthScreen
|
||||||
import ru.n08i40k.polytechnic.next.ui.main.MainScreen
|
import ru.n08i40k.polytechnic.next.ui.main.MainScreen
|
||||||
import ru.n08i40k.polytechnic.next.ui.theme.AppTheme
|
import ru.n08i40k.polytechnic.next.ui.theme.AppTheme
|
||||||
|
|||||||
@@ -447,6 +447,15 @@ fun tryRegister(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runBlocking {
|
||||||
|
context.settingsDataStore.updateData { currentSettings ->
|
||||||
|
currentSettings
|
||||||
|
.toBuilder()
|
||||||
|
.setGroup(group)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
navController.navigate("main")
|
navController.navigate("main")
|
||||||
}, {
|
}, {
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ private fun tryChangeGroup(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun getGroups(context: Context): ArrayList<String> {
|
private fun getGroups(context: Context): ArrayList<String> {
|
||||||
val groupPlaceholder = stringResource(R.string.loading);
|
val groupPlaceholder = stringResource(R.string.loading)
|
||||||
|
|
||||||
val groups = remember { arrayListOf(groupPlaceholder) }
|
val groups = remember { arrayListOf(groupPlaceholder) }
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.filled.AccountCircle
|
import androidx.compose.material.icons.filled.AccountCircle
|
||||||
import androidx.compose.material.icons.filled.Email
|
import androidx.compose.material.icons.filled.Email
|
||||||
import androidx.compose.material.icons.filled.Lock
|
import androidx.compose.material.icons.filled.Lock
|
||||||
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@@ -137,6 +138,23 @@ internal fun ProfileCard(profile: Profile = FakeProfileRepository.exampleProfile
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Button(onClick = {
|
||||||
|
runBlocking {
|
||||||
|
context.settingsDataStore.updateData {
|
||||||
|
it
|
||||||
|
.toBuilder()
|
||||||
|
.setGroup("")
|
||||||
|
.setAccessToken("")
|
||||||
|
.setUserId("")
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context.profileViewModel!!.onUnauthorized()
|
||||||
|
}) {
|
||||||
|
Text(stringResource(R.string.sign_out))
|
||||||
|
}
|
||||||
|
|
||||||
if (passwordChanging) {
|
if (passwordChanging) {
|
||||||
ChangePasswordDialog(
|
ChangePasswordDialog(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ fun ProfileScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is ProfileUiState.NoProfile -> {
|
is ProfileUiState.NoProfile -> {
|
||||||
TextButton(onClick = onRefreshProfile, modifier = Modifier.fillMaxSize()) {
|
if (!uiState.isLoading) {
|
||||||
Text(stringResource(R.string.reload), textAlign = TextAlign.Center)
|
TextButton(onClick = onRefreshProfile, modifier = Modifier.fillMaxSize()) {
|
||||||
|
Text(stringResource(R.string.reload), textAlign = TextAlign.Center)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package ru.n08i40k.polytechnic.next.ui.main.schedule
|
package ru.n08i40k.polytechnic.next.ui.main.schedule
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.pager.HorizontalPager
|
import androidx.compose.foundation.pager.HorizontalPager
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|||||||
@@ -38,8 +38,10 @@ fun ScheduleScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is ScheduleUiState.NoSchedule -> {
|
is ScheduleUiState.NoSchedule -> {
|
||||||
TextButton(onClick = onRefreshSchedule, modifier = Modifier.fillMaxSize()) {
|
if (!uiState.isLoading) {
|
||||||
Text(stringResource(R.string.reload), textAlign = TextAlign.Center)
|
TextButton(onClick = onRefreshSchedule, modifier = Modifier.fillMaxSize()) {
|
||||||
|
Text(stringResource(R.string.reload), textAlign = TextAlign.Center)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("unused")
|
||||||
|
|
||||||
package ru.n08i40k.polytechnic.next.ui.theme
|
package ru.n08i40k.polytechnic.next.ui.theme
|
||||||
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@@ -257,7 +259,7 @@ fun AppTheme(
|
|||||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
// Dynamic color is available on Android 12+
|
// Dynamic color is available on Android 12+
|
||||||
dynamicColor: Boolean = true,
|
dynamicColor: Boolean = true,
|
||||||
content: @Composable() () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
val colorScheme = when {
|
val colorScheme = when {
|
||||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
package ru.n08i40k.polytechnic.next.utils
|
|
||||||
|
|
||||||
data class ErrorMessage(val message: String)
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIEpjCCAw6gAwIBAgIRAO5cnXTnxJXAIMgjHjt8VNAwDQYJKoZIhvcNAQELBQAw
|
|
||||||
azEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMSAwHgYDVQQLDBdIT01F
|
|
||||||
LVBDXG4wOGk0MGtASE9NRS1QQzEnMCUGA1UEAwwebWtjZXJ0IEhPTUUtUENcbjA4
|
|
||||||
aTQwa0BIT01FLVBDMB4XDTI0MDQyMTIyMjE1MVoXDTM0MDQyMTIyMjE1MVowazEe
|
|
||||||
MBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMSAwHgYDVQQLDBdIT01FLVBD
|
|
||||||
XG4wOGk0MGtASE9NRS1QQzEnMCUGA1UEAwwebWtjZXJ0IEhPTUUtUENcbjA4aTQw
|
|
||||||
a0BIT01FLVBDMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAxdT1huby
|
|
||||||
eoG+X/kJoh1tn6jVJB/zN1r0/O7PZSZXJ9qYHufl6IwEfPlKJPNfpYifiSZ1x/R+
|
|
||||||
flzmfk8Q3L/njIh3WOURmKhPuHyUnruVQnM/66FqRAp0gSntuGnQ8y/JEkSRtzRI
|
|
||||||
p75Rp/1NktDRqi8UOq1+aXCKwyh/jcu2gaJ9L0EKRqpxrGjm2hF3yYRQU/DRcWhc
|
|
||||||
VJKpMW4TpelRxUTM5QSdqsoe+GoKgLQeHzLXRSmRdTMFql/yG3Cy3MfYNR/oA+Nu
|
|
||||||
Nlt1ozPBTrtQ0LhTlToJkALB2cBxodRGJs871eDqzTzDHbJ6+OjlNy4xtZEgDTqt
|
|
||||||
XIl0wexOTjVk+31ClLsaqtfWDsyFPpAG4G7+eAUNPXY1MSiui3SmF5G3tLKUMmci
|
|
||||||
A6hV7MSBOhSF+Rl0pzZ6t8/aANmZerpALymRRzpp93z3evdQqRtki1oi4x1SIb5h
|
|
||||||
cNHgvwTzb6vSxd17lTiB78bWGVsDO3wy7JMuWRdA/AClxufeA8d7RlkPAgMBAAGj
|
|
||||||
RTBDMA4GA1UdDwEB/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW
|
|
||||||
BBRR8ZgtYNodDB7WWBFlx8lNwWlkZDANBgkqhkiG9w0BAQsFAAOCAYEAtMxjGIF0
|
|
||||||
7I3UzM/2e/VWV8zaKRP4y7Nc3SbmygPi1kE+MJUtGyGqnOtVvTwVqmN1YMYe7Z3f
|
|
||||||
/IsjuMJfmDGq71gNf/frGDykOojpGnzk7R0d4VDWGA3cP+urSumilcz5a/nCfrps
|
|
||||||
zU5ZIM53t30Eg1FUdpJ84a9n2MF5rTBoFwez1JoeUUYdSI2SpbOHCAIzH3VLfQX0
|
|
||||||
n/80aWxrykpPsvqVE171fpq7JHYXgftCR/aEOrMNpq0mlv3uQ8nJ0ejLcHG5FOCn
|
|
||||||
0sjx3ol/5VbVQItfhUHzQab0ubNaxl3VhxJEuqlvqJn0A0VoisCARPp1k9IIwz78
|
|
||||||
LuuPUMjzmazBWgtE4Sj95M159f+A7tHeTXRDElSVb1QOAiHiFwBR6Eiw4jfjzJMi
|
|
||||||
RbZTh4aZ7YNtMFLROv3B8CP9TfcdyX/SeKRFwBp9mCotg9pxNuDwrwQ36+zyxv4N
|
|
||||||
W98lNodK590KS7F7P1P1oFS+cguzxiGJ3du4O5TTOY7VdgS+gz8DlBE+
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -30,4 +30,5 @@
|
|||||||
<string name="change_password">Сменить пароль</string>
|
<string name="change_password">Сменить пароль</string>
|
||||||
<string name="change_username">Сменить имя пользователя</string>
|
<string name="change_username">Сменить имя пользователя</string>
|
||||||
<string name="change_group">Сменить группу</string>
|
<string name="change_group">Сменить группу</string>
|
||||||
|
<string name="sign_out">Выйти с аккаунта</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,10 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="purple_200">#FFBB86FC</color>
|
|
||||||
<color name="purple_500">#FF6200EE</color>
|
|
||||||
<color name="purple_700">#FF3700B3</color>
|
|
||||||
<color name="teal_200">#FF03DAC5</color>
|
|
||||||
<color name="teal_700">#FF018786</color>
|
|
||||||
<color name="black">#FF000000</color>
|
|
||||||
<color name="white">#FFFFFFFF</color>
|
<color name="white">#FFFFFFFF</color>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -30,4 +30,5 @@
|
|||||||
<string name="change_username">Change username</string>
|
<string name="change_username">Change username</string>
|
||||||
<string name="loading">Loading…</string>
|
<string name="loading">Loading…</string>
|
||||||
<string name="change_group">Change group</string>
|
<string name="change_group">Change group</string>
|
||||||
|
<string name="sign_out">Sign out</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user