mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-03 13:47:31 +01:00
feat(profile): prettier account age
This commit is contained in:
parent
2229883cb2
commit
a58eb9b6b2
@ -1,5 +1,7 @@
|
||||
package com.github.diegoberaldin.racconforlemmy.core_utils
|
||||
|
||||
import java.time.LocalDateTime
|
||||
import java.time.Period
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
@ -13,6 +15,39 @@ actual object DateTime {
|
||||
return date.format(formatter)
|
||||
}
|
||||
|
||||
actual fun getPrettyDate(
|
||||
iso8601Timestamp: String,
|
||||
yearLabel: String,
|
||||
monthLabel: String,
|
||||
dayLabel: String,
|
||||
): String {
|
||||
val now = LocalDateTime.now().toLocalDate()
|
||||
val date = getDateFromIso8601Timestamp(iso8601Timestamp).toLocalDate()
|
||||
val delta = Period.between(date, now)
|
||||
return when {
|
||||
delta.years >= 1 -> buildString {
|
||||
append("${delta.years}$yearLabel")
|
||||
if (delta.months >= 1) {
|
||||
append(" ${delta.months}$monthLabel")
|
||||
}
|
||||
if (delta.days >= 1) {
|
||||
append(" ${delta.days}$dayLabel")
|
||||
}
|
||||
}
|
||||
|
||||
delta.months >= 1 -> buildString {
|
||||
append("${delta.months}$monthLabel")
|
||||
if (delta.days >= 1) {
|
||||
append(" ${delta.days}$dayLabel")
|
||||
}
|
||||
}
|
||||
|
||||
else -> buildString {
|
||||
append("${delta.days}$dayLabel")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDateFromIso8601Timestamp(string: String): ZonedDateTime {
|
||||
return ZonedDateTime.parse(string)
|
||||
}
|
||||
|
@ -5,4 +5,11 @@ expect object DateTime {
|
||||
iso8601Timestamp: String,
|
||||
format: String,
|
||||
): String
|
||||
}
|
||||
|
||||
fun getPrettyDate(
|
||||
iso8601Timestamp: String,
|
||||
yearLabel: String,
|
||||
monthLabel: String,
|
||||
dayLabel: String,
|
||||
): String
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
package com.github.diegoberaldin.racconforlemmy.core_utils
|
||||
|
||||
import platform.Foundation.NSCalendar
|
||||
import platform.Foundation.NSCalendarIdentifierGregorian
|
||||
import platform.Foundation.NSCalendarUnitDay
|
||||
import platform.Foundation.NSCalendarUnitMonth
|
||||
import platform.Foundation.NSCalendarUnitYear
|
||||
import platform.Foundation.NSDate
|
||||
import platform.Foundation.NSDateFormatter
|
||||
import platform.Foundation.NSISO8601DateFormatter
|
||||
@ -23,7 +28,46 @@ actual object DateTime {
|
||||
return dateFormatter.stringFromDate(date)
|
||||
}
|
||||
|
||||
actual fun getPrettyDate(
|
||||
iso8601Timestamp: String,
|
||||
yearLabel: String,
|
||||
monthLabel: String,
|
||||
dayLabel: String,
|
||||
): String {
|
||||
val date = getDateFromIso8601Timestamp(iso8601Timestamp) ?: return ""
|
||||
val now = NSDate()
|
||||
val calendar = NSCalendar(calendarIdentifier = NSCalendarIdentifierGregorian)
|
||||
val delta = calendar.components(
|
||||
unitFlags = NSCalendarUnitDay.or(NSCalendarUnitMonth).or(NSCalendarUnitYear),
|
||||
fromDate = date,
|
||||
toDate = now,
|
||||
options = 0,
|
||||
)
|
||||
return when {
|
||||
delta.year >= 1 -> buildString {
|
||||
append("${delta.year}$yearLabel")
|
||||
if (delta.month >= 1) {
|
||||
append(" ${delta.month}$monthLabel")
|
||||
}
|
||||
if (delta.day >= 1) {
|
||||
append(" ${delta.day}$dayLabel")
|
||||
}
|
||||
}
|
||||
|
||||
delta.month >= 1 -> buildString {
|
||||
append("${delta.month}$monthLabel")
|
||||
if (delta.day >= 1) {
|
||||
append(" ${delta.day}$dayLabel")
|
||||
}
|
||||
}
|
||||
|
||||
else -> buildString {
|
||||
append("${delta.day}$dayLabel")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDateFromIso8601Timestamp(string: String): NSDate? {
|
||||
return NSISO8601DateFormatter().dateFromString(string)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
@ -34,7 +33,6 @@ import io.kamel.image.asyncPainterResource
|
||||
@Composable
|
||||
internal fun ProfileLoggedContent(
|
||||
user: UserModel,
|
||||
onLogout: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().padding(horizontal = Spacing.m),
|
||||
@ -44,16 +42,22 @@ internal fun ProfileLoggedContent(
|
||||
val avatar = user.avatar.orEmpty()
|
||||
if (avatar.isNotEmpty()) {
|
||||
val painterResource = asyncPainterResource(data = avatar)
|
||||
KamelImage(modifier = Modifier.size(100.dp).clip(RoundedCornerShape(CornerSize.m)),
|
||||
KamelImage(
|
||||
modifier = Modifier.size(100.dp).clip(RoundedCornerShape(CornerSize.m)),
|
||||
resource = painterResource,
|
||||
contentDescription = null,
|
||||
onLoading = {
|
||||
CircularProgressIndicator()
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
val name = user.name.orEmpty()
|
||||
Text(
|
||||
text = name, style = MaterialTheme.typography.headlineMedium
|
||||
text = user.name,
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
)
|
||||
Text(
|
||||
text = user.host,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = Spacing.m).fillMaxWidth(),
|
||||
@ -104,9 +108,11 @@ internal fun ProfileLoggedContent(
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||
) {
|
||||
Text(
|
||||
text = DateTime.getFormattedDate(
|
||||
text = DateTime.getPrettyDate(
|
||||
iso8601Timestamp = user.accountAge + "Z",
|
||||
format = "dd.MM.yy"
|
||||
yearLabel = stringResource(MR.strings.profile_year_short),
|
||||
monthLabel = stringResource(MR.strings.profile_month_short),
|
||||
dayLabel = stringResource(MR.strings.profile_day_short),
|
||||
),
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
)
|
||||
@ -117,13 +123,6 @@ internal fun ProfileLoggedContent(
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(Spacing.l))
|
||||
Button(
|
||||
onClick = {
|
||||
onLogout()
|
||||
},
|
||||
) {
|
||||
Text(stringResource(MR.strings.profile_button_logout))
|
||||
}
|
||||
Spacer(modifier = Modifier.height(Spacing.s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ internal fun ProfileNotLoggedContent(
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize().padding(horizontal = Spacing.m),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs)
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(MR.strings.profile_not_logged_message),
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature_profile.ui
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.AccountCircle
|
||||
import androidx.compose.material.icons.filled.Logout
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
@ -15,11 +17,13 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||
import com.github.diegoberaldin.racconforlemmy.core_utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core_appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core_architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain_identity.di.getApiConfigurationRepository
|
||||
@ -41,7 +45,9 @@ object ProfileTab : Tab {
|
||||
|
||||
return remember(instance) {
|
||||
TabOptions(
|
||||
index = 0u, title = instance, icon = icon
|
||||
index = 0u,
|
||||
title = instance,
|
||||
icon = icon,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -61,11 +67,26 @@ object ProfileTab : Tab {
|
||||
val title by remember(lang) {
|
||||
mutableStateOf(staticString(MR.strings.navigation_profile.desc()))
|
||||
}
|
||||
TopAppBar(title = {
|
||||
Text(
|
||||
text = title, style = MaterialTheme.typography.titleLarge
|
||||
)
|
||||
})
|
||||
TopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
)
|
||||
},
|
||||
actions = {
|
||||
if (uiState.currentUser != null) {
|
||||
Image(
|
||||
modifier = Modifier.onClick {
|
||||
model.reduce(ProfileScreenMviModel.Intent.Logout)
|
||||
},
|
||||
imageVector = Icons.Default.Logout,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
) {
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
@ -78,9 +99,9 @@ object ProfileTab : Tab {
|
||||
bottomSheetNavigator.show(LoginBottomSheet())
|
||||
})
|
||||
} else {
|
||||
ProfileLoggedContent(user = user, onLogout = {
|
||||
model.reduce(ProfileScreenMviModel.Intent.Logout)
|
||||
})
|
||||
ProfileLoggedContent(
|
||||
user = user,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,9 @@
|
||||
<string name="profile_post_score">Post score</string>
|
||||
<string name="profile_comment_score">Comment score</string>
|
||||
<string name="profile_account_age">Account age</string>
|
||||
<string name="profile_year_short">y</string>
|
||||
<string name="profile_month_short">m</string>
|
||||
<string name="profile_day_short">d</string>
|
||||
|
||||
<string name="login_field_instance_name">Instance name</string>
|
||||
<string name="login_field_user_name">Username (or email)</string>
|
||||
|
@ -8,6 +8,11 @@
|
||||
<string name="navigation_search">Ricerca</string>
|
||||
<string name="navigation_settings">Impostazioni</string>
|
||||
|
||||
<string name="message_generic_error">Errore generico</string>
|
||||
<string name="message_missing_field">Campo obbligatorio</string>
|
||||
|
||||
<string name="button_confirm">Conferma</string>
|
||||
|
||||
<string name="home_listing_type_all">Tutti</string>
|
||||
<string name="home_listing_type_local">Locali</string>
|
||||
<string name="home_listing_type_subscribed">Iscrizioni</string>
|
||||
@ -28,6 +33,24 @@
|
||||
<string name="home_sort_type_top_year">Top anno</string>
|
||||
<string name="home_instance_via">via %1$s</string>
|
||||
|
||||
<string name="profile_not_logged_message">Login non effettuato.\nAggiungi un account per
|
||||
continuare.
|
||||
</string>
|
||||
<string name="profile_button_login">Login</string>
|
||||
<string name="profile_button_logout">Logout</string>
|
||||
<string name="profile_post_score">Punti post</string>
|
||||
<string name="profile_comment_score">Punti commento</string>
|
||||
<string name="profile_account_age">Età account</string>
|
||||
<string name="profile_year_short">a</string>
|
||||
<string name="profile_month_short">m</string>
|
||||
<string name="profile_day_short">g</string>
|
||||
|
||||
<string name="login_field_instance_name">Nome istanza</string>
|
||||
<string name="login_field_user_name">Nome utente (o email)</string>
|
||||
<string name="login_field_password">Password</string>
|
||||
<string name="login_field_token">TOTP 2FA token</string>
|
||||
<string name="login_field_label_optional">(opzionale)</string>
|
||||
|
||||
<string name="settings_ui_theme">Tema interfaccia</string>
|
||||
<string name="settings_theme_dark">Scuro</string>
|
||||
<string name="settings_theme_light">Chiaro</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user