enhancement: recover expired token in profile (#1135)

This commit is contained in:
Diego Beraldin 2024-07-14 17:16:18 +02:00 committed by GitHub
parent 0f99736da3
commit 19ba7ee2c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 109 additions and 2 deletions

View File

@ -334,7 +334,7 @@ internal open class DefaultStrings : Strings {
override val moderatorZoneTitle = "Moderation tools" override val moderatorZoneTitle = "Moderation tools"
override val moderatorZoneActionContents = "Moderated contents" override val moderatorZoneActionContents = "Moderated contents"
override val messageAuthIssue = override val messageAuthIssue =
"An error occurred while fetching user data, try refreshing the screen" "An error occurred while fetching data, possibly your token has expired."
override val banReasonPlaceholder = "Reason (optional)" override val banReasonPlaceholder = "Reason (optional)"
override val banItemPermanent = "Permanent ban" override val banItemPermanent = "Permanent ban"
override val banItemRemoveData = "Remove data" override val banItemRemoveData = "Remove data"
@ -431,4 +431,8 @@ internal open class DefaultStrings : Strings {
override val settingsItemAlternateMarkdownRendering = "Enable alternate Markdown rendering" override val settingsItemAlternateMarkdownRendering = "Enable alternate Markdown rendering"
override val settingsItemConfigureBottomNavigationBar = "Configure bottom navigation bar" override val settingsItemConfigureBottomNavigationBar = "Configure bottom navigation bar"
override val selectTabNavigationTitle = "Select a section" override val selectTabNavigationTitle = "Select a section"
override val messageAuthIssueSegue =
"You could try one of the following actions:\n• force refresh\n• log in again\n• clear the application data"
override val messageAuthIssueSegueHighlight1 = "force refresh"
override val messageAuthIssueSegueHighlight2 = "log in again"
} }

View File

@ -429,6 +429,9 @@ interface Strings {
val settingsItemAlternateMarkdownRendering: String val settingsItemAlternateMarkdownRendering: String
val settingsItemConfigureBottomNavigationBar: String val settingsItemConfigureBottomNavigationBar: String
val selectTabNavigationTitle: String val selectTabNavigationTitle: String
val messageAuthIssueSegue: String
val messageAuthIssueSegueHighlight1: String
val messageAuthIssueSegueHighlight2: String
} }
object Locales { object Locales {

View File

@ -1,6 +1,7 @@
package com.github.diegoberaldin.raccoonforlemmy.unit.myaccount package com.github.diegoberaldin.raccoonforlemmy.unit.myaccount
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -14,6 +15,8 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.PullRefreshIndicator
import androidx.compose.material.pullrefresh.pullRefresh import androidx.compose.material.pullrefresh.pullRefresh
@ -33,12 +36,17 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.koin.getScreenModel import cafe.adriel.voyager.koin.getScreenModel
import cafe.adriel.voyager.navigator.tab.Tab import cafe.adriel.voyager.navigator.tab.Tab
import cafe.adriel.voyager.navigator.tab.TabOptions import cafe.adriel.voyager.navigator.tab.TabOptions
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.ProgressHud import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.ProgressHud
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SectionSelector import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SectionSelector
@ -69,6 +77,12 @@ import com.github.diegoberaldin.raccoonforlemmy.unit.zoomableimage.ZoomableImage
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
private object AuthIssueAnnotations {
const val ANNOTATION_ACTION = "action"
const val ACTION_REFRESH = "refresh"
const val ACTION_LOGIN = "login"
}
object ProfileLoggedScreen : Tab { object ProfileLoggedScreen : Tab {
override val options: TabOptions override val options: TabOptions
@Composable get() { @Composable get() {
@ -142,12 +156,98 @@ object ProfileLoggedScreen : Tab {
if (uiState.user == null) { if (uiState.user == null) {
item { item {
Text( Text(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth().padding(horizontal = Spacing.s),
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
text = LocalStrings.current.messageAuthIssue, text = LocalStrings.current.messageAuthIssue,
style = MaterialTheme.typography.bodyLarge, style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onBackground, color = MaterialTheme.colorScheme.onBackground,
) )
val annotatedString =
buildAnnotatedString {
val text = LocalStrings.current.messageAuthIssueSegue
val span1 =
LocalStrings.current.messageAuthIssueSegueHighlight1
val span2 =
LocalStrings.current.messageAuthIssueSegueHighlight2
withStyle(SpanStyle(color = MaterialTheme.colorScheme.onBackground)) {
append(text)
val span1Start = text.indexOf(span1)
val span1End = span1Start + span1.length
addStringAnnotation(
tag = AuthIssueAnnotations.ANNOTATION_ACTION,
annotation = AuthIssueAnnotations.ACTION_REFRESH,
start = span1Start,
end = span1End,
)
addStyle(
SpanStyle(
color = MaterialTheme.colorScheme.primary,
textDecoration = TextDecoration.Underline,
),
span1Start,
span1End,
)
val span2Start = text.indexOf(span2)
val span2End = span2Start + span2.length
addStringAnnotation(
tag = AuthIssueAnnotations.ANNOTATION_ACTION,
annotation = AuthIssueAnnotations.ACTION_LOGIN,
start = span2Start,
end = span2End,
)
addStyle(
SpanStyle(
color = MaterialTheme.colorScheme.primary,
textDecoration = TextDecoration.Underline,
),
span2Start,
span2End,
)
}
}
Box(
modifier =
Modifier
.padding(
vertical = Spacing.m,
horizontal = Spacing.s,
).border(
width = 1.dp,
color = MaterialTheme.colorScheme.onBackground,
shape = RoundedCornerShape(CornerSize.l),
).padding(
vertical = Spacing.s,
horizontal = Spacing.m,
),
) {
ClickableText(
modifier =
Modifier.fillMaxWidth(),
text = annotatedString,
style = MaterialTheme.typography.bodyLarge,
onClick = { offset ->
val annotation =
annotatedString
.getStringAnnotations(
tag = AuthIssueAnnotations.ANNOTATION_ACTION,
start = offset,
end = offset,
).firstOrNull()
if (annotation != null) {
when (annotation.item) {
AuthIssueAnnotations.ACTION_REFRESH ->
model.reduce(ProfileLoggedMviModel.Intent.Refresh)
AuthIssueAnnotations.ACTION_LOGIN ->
notificationCenter.send(
NotificationCenterEvent.ProfileSideMenuAction.Logout,
)
}
}
},
)
}
} }
} else { } else {
item { item {