Skip to content

Commit c66577e

Browse files
committed
updated: logout moved to profile page
fixed: ignored network error meanwhile reading state update
1 parent a70f33c commit c66577e

9 files changed

Lines changed: 160 additions & 21 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.home.reader.component.dto
2+
3+
data class ProfileDto(
4+
val username: String
5+
)

app/src/main/java/com/home/reader/ui/AppViewModelProvider.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.home.reader.ui.reader.viewmodel.ReaderViewModel
1212
import com.home.reader.ui.series.viewmodel.SeriesViewModel
1313
import com.home.reader.ui.common.component.viewmodel.NavigationMenuViewModel
1414
import com.home.reader.ui.common.component.viewmodel.UpdateOnResumeViewModel
15+
import com.home.reader.ui.profile.ProfileViewModel
1516

1617
object AppViewModelProvider {
1718
val Factory = viewModelFactory {
@@ -65,6 +66,12 @@ object AppViewModelProvider {
6566
context = readerApplication().applicationContext
6667
)
6768
}
69+
70+
initializer {
71+
ProfileViewModel(
72+
userRepository = readerApplication().container.userRepository
73+
)
74+
}
6875
}
6976
}
7077

app/src/main/java/com/home/reader/ui/common/component/NavigationMenu.kt

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.home.reader.ui.common.component
22

33
import androidx.compose.material.icons.Icons
44
import androidx.compose.material.icons.rounded.AccountCircle
5-
import androidx.compose.material.icons.rounded.Close
65
import androidx.compose.material.icons.rounded.Home
76
import androidx.compose.material.icons.rounded.ShoppingCart
87
import androidx.compose.material3.Icon
@@ -41,7 +40,11 @@ fun NavigationMenu(
4140
selected = currentDestination.value == "login",
4241
onClick = {
4342
currentDestination.value = "login"
44-
if (loginState.value == null) controller.navigate(NavigationRoutes.Unauthenticated.Login)
43+
if (loginState.value == null) {
44+
controller.navigate(NavigationRoutes.Unauthenticated.Login)
45+
} else {
46+
controller.navigate(NavigationRoutes.Authenticated.Profile)
47+
}
4548
}
4649
)
4750

@@ -65,13 +68,6 @@ fun NavigationMenu(
6568
controller.navigate(NavigationRoutes.Authenticated.Catalogue)
6669
}
6770
)
68-
69-
item(
70-
icon = { Icon(Icons.Rounded.Close, contentDescription = "Log out") },
71-
label = { Text(text = "Log out") },
72-
selected = false,
73-
onClick = { viewModel.logout() }
74-
)
7571
}
7672
},
7773
content = content

app/src/main/java/com/home/reader/ui/common/component/viewmodel/NavigationMenuViewModel.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,4 @@ class NavigationMenuViewModel(
1919
}
2020
}
2121

22-
fun logout() {
23-
viewModelScope.launch {
24-
userRepository.delete()
25-
loginState.value = null
26-
}
27-
}
2822
}

app/src/main/java/com/home/reader/ui/navigation/NavigationRoutes.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ sealed class NavigationRoutes {
2727

2828
@Serializable
2929
object Catalogue : Authenticated()
30+
31+
@Serializable
32+
object Profile : Authenticated()
3033
}
3134

3235
}

app/src/main/java/com/home/reader/ui/navigation/NestedNavigation.kt

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ import androidx.navigation.NavController
66
import androidx.navigation.NavGraphBuilder
77
import androidx.navigation.compose.composable
88
import androidx.navigation.toRoute
9+
import com.home.reader.component.dto.ProfileDto
910
import com.home.reader.persistence.entity.User
1011
import com.home.reader.ui.catalogue.screen.CatalogueScreen
1112
import com.home.reader.ui.common.component.NavigationMenu
1213
import com.home.reader.ui.issues.screen.IssuesScreen
1314
import com.home.reader.ui.login.screen.LoginScreen
15+
import com.home.reader.ui.profile.ProfileScreen
1416
import com.home.reader.ui.reader.configuration.ReaderConfig
1517
import com.home.reader.ui.reader.screen.ReaderScreen
1618
import com.home.reader.ui.series.screen.SeriesScreen
@@ -21,7 +23,11 @@ fun NavGraphBuilder.authenticatedGraph(
2123
currentPosition: MutableState<String>
2224
) {
2325
composable<NavigationRoutes.Authenticated.Series> {
24-
NavigationMenu(loginState = loginState, controller = controller, currentDestination = currentPosition) {
26+
NavigationMenu(
27+
loginState = loginState,
28+
controller = controller,
29+
currentDestination = currentPosition
30+
) {
2531
SeriesScreen(
2632
loginState = loginState,
2733
onNavigateToIssuesScreen = { id, name ->
@@ -33,7 +39,11 @@ fun NavGraphBuilder.authenticatedGraph(
3339

3440
composable<NavigationRoutes.Authenticated.Issues> {
3541
val config: NavigationRoutes.Authenticated.Issues = it.toRoute()
36-
NavigationMenu(loginState = loginState, controller = controller, currentDestination = currentPosition) {
42+
NavigationMenu(
43+
loginState = loginState,
44+
controller = controller,
45+
currentDestination = currentPosition
46+
) {
3747
IssuesScreen(
3848
seriesId = config.seriesId,
3949
seriesName = config.name,
@@ -45,16 +55,37 @@ fun NavGraphBuilder.authenticatedGraph(
4555
composable<ReaderConfig> { ReaderScreen(config = it.toRoute()) }
4656

4757
composable<NavigationRoutes.Unauthenticated.Login> {
48-
NavigationMenu(loginState = loginState, controller = controller, currentDestination = currentPosition) {
58+
NavigationMenu(
59+
loginState = loginState,
60+
controller = controller,
61+
currentDestination = currentPosition
62+
) {
4963
LoginScreen(navigateOnSuccess = { controller.navigate(NavigationRoutes.Authenticated.Series) })
5064
}
5165
}
5266

5367
composable<NavigationRoutes.Authenticated.Catalogue> {
54-
NavigationMenu(loginState = loginState, controller = controller, currentDestination = currentPosition) {
68+
NavigationMenu(
69+
loginState = loginState,
70+
controller = controller,
71+
currentDestination = currentPosition
72+
) {
5573
CatalogueScreen(
5674
onNavigateToReaderScreen = { config -> controller.navigate(config) }
5775
)
5876
}
5977
}
78+
79+
composable<NavigationRoutes.Authenticated.Profile> {
80+
NavigationMenu(
81+
loginState = loginState,
82+
controller = controller,
83+
currentDestination = currentPosition
84+
) {
85+
ProfileScreen(
86+
profile = ProfileDto(username = loginState.value?.username ?: ""),
87+
navigateOnExit = { controller.navigate(NavigationRoutes.Authenticated.Series) }
88+
)
89+
}
90+
}
6091
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.home.reader.ui.profile
2+
3+
import android.graphics.Color
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.Row
6+
import androidx.compose.foundation.layout.fillMaxHeight
7+
import androidx.compose.foundation.layout.height
8+
import androidx.compose.foundation.layout.padding
9+
import androidx.compose.material.icons.Icons
10+
import androidx.compose.material.icons.automirrored.filled.ExitToApp
11+
import androidx.compose.material.icons.rounded.AccountCircle
12+
import androidx.compose.material3.Icon
13+
import androidx.compose.material3.IconButton
14+
import androidx.compose.material3.MaterialTheme
15+
import androidx.compose.material3.Text
16+
import androidx.compose.runtime.Composable
17+
import androidx.compose.ui.Alignment
18+
import androidx.compose.ui.Modifier
19+
import androidx.compose.ui.tooling.preview.Preview
20+
import androidx.compose.ui.unit.dp
21+
import androidx.lifecycle.viewmodel.compose.viewModel
22+
import com.home.reader.component.dto.ProfileDto
23+
import com.home.reader.ui.AppViewModelProvider
24+
25+
@Composable
26+
fun ProfileScreen(
27+
viewModel: ProfileViewModel = viewModel(factory = AppViewModelProvider.Factory),
28+
profile: ProfileDto,
29+
navigateOnExit: () -> Unit
30+
) {
31+
Column(
32+
modifier = Modifier.padding(top = 50.dp)
33+
) {
34+
Row(modifier = Modifier.height(40.dp)) {
35+
Row(
36+
verticalAlignment = Alignment.CenterVertically,
37+
modifier = Modifier.fillMaxHeight().weight(2f)
38+
) {
39+
Icon(Icons.Rounded.AccountCircle, contentDescription = "Account")
40+
Text(text = profile.username)
41+
}
42+
43+
44+
IconButton(
45+
onClick = {
46+
viewModel.logout()
47+
navigateOnExit()
48+
}
49+
) {
50+
Icon(Icons.AutoMirrored.Filled.ExitToApp, contentDescription = "Exit")
51+
}
52+
}
53+
54+
}
55+
}
56+
57+
@Composable
58+
@Preview(
59+
showBackground = true,
60+
backgroundColor = Color.WHITE.toLong()
61+
)
62+
private fun Preview() {
63+
val profile = ProfileDto(
64+
username = "Username"
65+
)
66+
67+
MaterialTheme {
68+
ProfileScreen(profile = profile){}
69+
}
70+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.home.reader.ui.profile
2+
3+
import androidx.compose.runtime.mutableStateOf
4+
import androidx.lifecycle.ViewModel
5+
import androidx.lifecycle.viewModelScope
6+
import com.home.reader.persistence.entity.User
7+
import com.home.reader.persistence.repository.UserRepository
8+
import kotlinx.coroutines.launch
9+
10+
class ProfileViewModel(
11+
private val userRepository: UserRepository
12+
) : ViewModel() {
13+
var loginState = mutableStateOf<User?>(null)
14+
15+
init {
16+
viewModelScope.launch {
17+
loginState.value = userRepository.get()
18+
}
19+
}
20+
21+
fun logout() {
22+
viewModelScope.launch {
23+
userRepository.delete()
24+
loginState.value = null
25+
}
26+
}
27+
}

app/src/main/java/com/home/reader/ui/reader/viewmodel/ReaderViewModel.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,15 @@ class ReaderViewModel(
7575
state.value = state.value.copy(currentPage = page)
7676
viewModelScope.launch(Dispatchers.IO) {
7777
when (state.value.mode) {
78-
ReaderMode.REMOTE -> api.updateProgress(state.value.externalId!!, page)
78+
ReaderMode.REMOTE -> {
79+
try {
80+
api.updateProgress(state.value.externalId!!, page)
81+
} catch (_: Exception) {
82+
//TODO save to database and post later
83+
}
84+
}
7985
ReaderMode.LOCAL -> issueRepository.updateState(state.value.id!!, page)
80-
else -> {
86+
ReaderMode.CACHED -> {
8187
try {
8288
api.updateProgress(state.value.externalId!!, page)
8389
} catch (_: Exception) {

0 commit comments

Comments
 (0)