Skip to content

Commit

Permalink
feat: Correctly display Transfer date (#425)
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinBoulongne authored Feb 24, 2025
2 parents 98cbcb4 + ab061b4 commit 982a040
Show file tree
Hide file tree
Showing 23 changed files with 326 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import android.content.Context
import androidx.core.app.NotificationManagerCompat
import androidx.work.WorkManager
import com.infomaniak.core.appintegrity.AppIntegrityManager
import com.infomaniak.core.buildUserAgent
import com.infomaniak.core.utils.buildUserAgent
import com.infomaniak.swisstransfer.BuildConfig
import com.infomaniak.swisstransfer.ui.MainApplication
import dagger.Module
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.core.os.BundleCompat
import androidx.lifecycle.lifecycleScope
import com.infomaniak.core.enumValueOfOrNull
import com.infomaniak.core.utils.enumValueOfOrNull
import com.infomaniak.swisstransfer.ui.navigation.*
import com.infomaniak.swisstransfer.ui.screen.newtransfer.NewTransferOpenManager
import com.infomaniak.swisstransfer.ui.screen.newtransfer.NewTransferScreen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import com.infomaniak.core.FORMAT_DATE_SIMPLE
import com.infomaniak.core.format
import com.infomaniak.core.utils.FORMAT_DATE_SIMPLE
import com.infomaniak.core.utils.format
import com.infomaniak.multiplatform_swisstransfer.common.ext.toDateFromSeconds
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.TransferUi
import com.infomaniak.swisstransfer.R
Expand All @@ -36,6 +36,7 @@ import com.infomaniak.swisstransfer.ui.images.illus.mascotDead.MascotDead
import com.infomaniak.swisstransfer.ui.previewparameter.TransferUiListPreviewParameter
import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
import com.infomaniak.swisstransfer.ui.utils.PreviewAllWindows
import com.infomaniak.swisstransfer.ui.utils.daysBeforeExpiry

@OptIn(ExperimentalMaterial3Api::class)
@Composable
Expand All @@ -47,7 +48,7 @@ fun TransferExpiredBottomSheet(

val transfer = expiredTransfer() ?: return

val descriptionText = if (transfer.expiresInDays < 0) {
val descriptionText = if (transfer.daysBeforeExpiry < 0) {
stringResource(
R.string.transferExpiredDateReachedDescription,
transfer.expirationDateTimestamp.toDateFromSeconds().format(FORMAT_DATE_SIMPLE),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,12 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewParameter
import com.infomaniak.core.FORMAT_DATE_TITLE
import com.infomaniak.core.format
import com.infomaniak.core.utils.FORMAT_DATE_TITLE
import com.infomaniak.core.utils.format
import com.infomaniak.multiplatform_swisstransfer.common.ext.toDateFromSeconds
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.TransferUi
import com.infomaniak.swisstransfer.R
import com.infomaniak.swisstransfer.ui.components.TextDotText
import com.infomaniak.swisstransfer.ui.images.AppImages.AppIcons
import com.infomaniak.swisstransfer.ui.images.icons.ChevronRightThick
Expand All @@ -44,7 +42,6 @@ import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
import com.infomaniak.swisstransfer.ui.utils.HumanReadableSizeUtils
import com.infomaniak.swisstransfer.ui.utils.PreviewLightAndDark
import com.infomaniak.swisstransfer.ui.utils.getFormattedExpiry
import com.infomaniak.swisstransfer.ui.utils.isExpired

@OptIn(ExperimentalLayoutApi::class)
@Composable
Expand All @@ -61,11 +58,7 @@ fun TransferItem(
if (transfer.files.isEmpty()) return

val files = transfer.files
val (expiryText, expiryColor) = if (transfer.isExpired) {
stringResource(R.string.transferExpired) to SwissTransferTheme.materialColors.error
} else {
transfer.getFormattedExpiry() to SwissTransferTheme.colors.secondaryTextColor
}
val (expiryText, expiryColor) = transfer.getFormattedExpiry()
val border = if (isSelected()) {
BorderStroke(width = Dimens.BorderWidth, color = SwissTransferTheme.colors.transferListStroke)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,24 @@ package com.infomaniak.swisstransfer.ui.previewparameter

import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.TransferUi
import com.infomaniak.multiplatform_swisstransfer.common.utils.DateUtils.SECONDS_IN_A_DAY
import com.infomaniak.swisstransfer.ui.screen.main.transfers.GroupedTransfers
import com.infomaniak.swisstransfer.ui.screen.main.transfers.TransfersGroupingManager.groupBySection
import com.infomaniak.swisstransfer.ui.screen.main.transfers.TransfersGroupingManager.toLocalDate
import kotlinx.datetime.Clock
import java.util.UUID

class GroupedTransfersPreviewParameterProvider : PreviewParameterProvider<GroupedTransfers> {
override val values: Sequence<GroupedTransfers> = sequenceOf(transfersPreviewData.groupBySection(today.toLocalDate()))
override val values: Sequence<GroupedTransfers> = sequenceOf(transfersPreviewData.groupBySection(now.toLocalDate()))
}

private const val today = 1736411401L
private val now get() = Clock.System.now().epochSeconds

val transfersPreviewData = listOf(
TransferUi(
uuid = UUID.randomUUID().toString(),
createdDateTimestamp = today - 0.5f.toLong() * 86_400L,
expirationDateTimestamp = today + 3 * 86_400L,
createdDateTimestamp = now - (0.5f * SECONDS_IN_A_DAY).toLong(),
expirationDateTimestamp = now + 3 * SECONDS_IN_A_DAY,
sizeUploaded = 237_866_728L,
downloadLimit = 250,
downloadLeft = 123,
Expand All @@ -44,8 +46,8 @@ val transfersPreviewData = listOf(
),
TransferUi(
uuid = UUID.randomUUID().toString(),
createdDateTimestamp = today - 0.6f.toLong() * 86_400L,
expirationDateTimestamp = today + 3 * 86_400L,
createdDateTimestamp = now - (0.6f * SECONDS_IN_A_DAY).toLong(),
expirationDateTimestamp = now + 3 * SECONDS_IN_A_DAY,
sizeUploaded = 237_866_728L,
downloadLimit = 250,
downloadLeft = 123,
Expand All @@ -55,8 +57,8 @@ val transfersPreviewData = listOf(
),
TransferUi(
uuid = UUID.randomUUID().toString(),
createdDateTimestamp = today - 5L * 86_400L,
expirationDateTimestamp = today + 5 * 86_400L,
createdDateTimestamp = now - 5L * SECONDS_IN_A_DAY,
expirationDateTimestamp = now + 5L * SECONDS_IN_A_DAY,
sizeUploaded = 89_723_143L,
downloadLimit = 20,
downloadLeft = 0,
Expand All @@ -66,8 +68,8 @@ val transfersPreviewData = listOf(
),
TransferUi(
uuid = UUID.randomUUID().toString(),
createdDateTimestamp = today - 30L * 86_400L,
expirationDateTimestamp = today - 4 * 86_400L,
createdDateTimestamp = now - 30L * SECONDS_IN_A_DAY,
expirationDateTimestamp = now - 4L * SECONDS_IN_A_DAY,
sizeUploaded = 57_689_032L,
downloadLimit = 1,
downloadLeft = 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.PermissionState
import com.google.accompanist.permissions.rememberPermissionState
import com.infomaniak.core.FORMAT_DATE_FULL
import com.infomaniak.core.format
import com.infomaniak.core.utils.FORMAT_DATE_FULL
import com.infomaniak.core.utils.format
import com.infomaniak.multiplatform_swisstransfer.common.ext.toDateFromSeconds
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.FileUi
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.TransferUi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import android.net.Uri
import androidx.lifecycle.Lifecycle
import com.infomaniak.core.*
import com.infomaniak.core.filetypes.FileType
import com.infomaniak.core.utils.DownloadManagerUtils
import com.infomaniak.multiplatform_swisstransfer.SharedApiUrlCreator
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.FileUi
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.TransferUi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import com.infomaniak.swisstransfer.ui.theme.Margin
import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
import com.infomaniak.swisstransfer.ui.utils.HumanReadableSizeUtils
import com.infomaniak.swisstransfer.ui.utils.PreviewLightAndDark
import com.infomaniak.swisstransfer.ui.utils.getFormattedExpiry
import com.infomaniak.swisstransfer.ui.utils.getWholeDate

@Composable
fun TransferInfo(getTransfer: () -> TransferUi) {
Expand Down Expand Up @@ -76,7 +76,7 @@ fun TransferInfo(getTransfer: () -> TransferUi) {

IconText(
icon = AppIcons.Clock,
text = getTransfer().getFormattedExpiry(),
text = getTransfer().getWholeDate(),
)

if (direction == TransferDirection.SENT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import androidx.compose.runtime.setValue
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.infomaniak.core.isValidEmail
import com.infomaniak.core.sentry.SentryLog
import com.infomaniak.core.utils.isValidEmail
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.FileUi
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.RemoteUploadFile
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.UploadFileSession
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.*
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import com.infomaniak.core.isValidEmail
import com.infomaniak.core.utils.isValidEmail
import com.infomaniak.swisstransfer.R
import com.infomaniak.swisstransfer.ui.components.SwissTransferInputChip
import com.infomaniak.swisstransfer.ui.components.SwissTransferTextFieldDefaults
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.infomaniak.core.percent
import com.infomaniak.core.utils.percent
import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
import com.infomaniak.swisstransfer.ui.utils.HumanReadableSizeUtils
import com.infomaniak.swisstransfer.ui.utils.PreviewLightAndDark
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,79 @@
*/
package com.infomaniak.swisstransfer.ui.utils

import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import com.infomaniak.core.utils.*
import com.infomaniak.multiplatform_swisstransfer.common.ext.toDateFromSeconds
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.TransferUi
import com.infomaniak.multiplatform_swisstransfer.common.utils.DateUtils.SECONDS_IN_A_DAY
import com.infomaniak.swisstransfer.R
import com.infomaniak.swisstransfer.ui.theme.SwissTransferTheme
import kotlinx.datetime.Clock

val TransferUi.isExpired: Boolean get() = expiresInDays < 0 || downloadLeft <= 0
enum class ExpiryStatus(@StringRes val stringId: Int) {
EXPIRED(R.string.expired), // Has expired
EXPIRES_TODAY(R.string.expiresAt), // Will expire today
EXPIRES_TOMORROW(R.string.expiresTomorrow), // Will expire tomorrow
NOT_EXPIRED(R.string.expiresIn); // Will expire someday after tomorrow

@Composable
fun getText(transfer: TransferUi): String {
val expiry = transfer.expirationDateTimestamp.toDateFromSeconds()
return when (this) {
EXPIRED -> stringResource(stringId)
EXPIRES_TODAY -> stringResource(stringId, expiry.format(FORMAT_HOUR_MINUTES))
EXPIRES_TOMORROW -> stringResource(stringId)
NOT_EXPIRED -> stringResource(stringId, transfer.daysBeforeExpiry)
}
}
}

fun TransferUi.expiryStatus(): ExpiryStatus {
val expiry = expirationDateTimestamp.toDateFromSeconds()
val now = Clock.System.now().epochSeconds.toDateFromSeconds()
val tomorrow = now.tomorrow()
return when {
isExpired -> ExpiryStatus.EXPIRED
expiry in now..now.endOfTheDay() -> ExpiryStatus.EXPIRES_TODAY
expiry in tomorrow.startOfTheDay()..tomorrow.endOfTheDay() -> ExpiryStatus.EXPIRES_TOMORROW
else -> ExpiryStatus.NOT_EXPIRED
}
}

val TransferUi.daysBeforeExpiry: Int
get() {

fun Long.epochSecondsToDays(): Int = (toDateFromSeconds().startOfTheDay().time / 1_000L / SECONDS_IN_A_DAY).toInt()

val expiry = expirationDateTimestamp.epochSecondsToDays()
val now = Clock.System.now().epochSeconds.epochSecondsToDays()

return expiry - now
}

val TransferUi.isExpired: Boolean
get() {
val expiry = expirationDateTimestamp.toDateFromSeconds()
val now = Clock.System.now().epochSeconds.toDateFromSeconds()
return expiry.before(now) || downloadLeft <= 0
}

@Composable
fun TransferUi.getFormattedExpiry(): Pair<String, Color> {
val text = expiryStatus().getText(transfer = this)
val color = if (isExpired) SwissTransferTheme.materialColors.error else SwissTransferTheme.colors.secondaryTextColor
return text to color
}

@Composable
fun TransferUi.getFormattedExpiry(): String = when (expiresInDays) {
0 -> stringResource(R.string.expiresToday)
1 -> stringResource(R.string.expiresTomorrow)
else -> stringResource(R.string.expiresIn, expiresInDays)
fun TransferUi.getWholeDate(): String {
val expiry = expirationDateTimestamp.toDateFromSeconds()
return stringResource(
R.string.expiresThe,
expiry.format(),
expiry.format(FORMAT_HOUR_MINUTES),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import androidx.compose.runtime.Immutable
import androidx.hilt.work.HiltWorker
import androidx.work.*
import androidx.work.WorkInfo.State
import com.infomaniak.core.percent
import com.infomaniak.core.sentry.SentryLog
import com.infomaniak.core.utils.percent
import com.infomaniak.multiplatform_swisstransfer.SharedApiUrlCreator
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.UploadSession
import com.infomaniak.multiplatform_swisstransfer.managers.AppSettingsManager
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@
<string name="errorAppIntegrity">Ihr Gerät wird nicht als sicher erkannt</string>
<string name="errorIncorrectPassword">Falsches Kennwort</string>
<string name="errorTransferPasswordLength">Das Passwort muss zwischen 6 und 25 Zeichen lang sein</string>
<string name="expired">Abgelaufen</string>
<string name="expiresAt">Läuft ab bei %s</string>
<string name="expiresIn">Verfällt in %d Tagen</string>
<string name="expiresToday">Läuft heute ab</string>
<string name="expiresThe">Läuft am %s um %s</string>
<string name="expiresTomorrow">Läuft morgen ab</string>
<plurals name="filesCount">
<item quantity="one">%d Datei</item>
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@
<string name="errorAppIntegrity">Su dispositivo no es reconocido como seguro</string>
<string name="errorIncorrectPassword">Contraseña incorrecta</string>
<string name="errorTransferPasswordLength">La contraseña debe tener entre 6 y 25 caracteres</string>
<string name="expired">Expirado</string>
<string name="expiresAt">Expira a %s</string>
<string name="expiresIn">Caduca en %d días</string>
<string name="expiresToday">Caduca hoy</string>
<string name="expiresThe">Expira el %s a las %s</string>
<string name="expiresTomorrow">Expira mañana</string>
<plurals name="filesCount">
<item quantity="one">%d archivo</item>
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@
<string name="deeplinkPasswordDescription">Saisis le mot de passe qui t’a été fourni pour télécharger ces fichiers.</string>
<string name="deeplinkTransferExpired">Ce transfert a expiré</string>
<string name="deeplinkTransferNotFound">Ce transfert n’existe pas</string>
<string name="downloadedTransferLabel">Transfert téléchargé : %d/%d\u0020</string>
<string name="downloadedTransferLabel">Transfert téléchargé : %d/%d</string>
<string name="errorAppIntegrity">Votre appareil n’est pas reconnu comme sûr</string>
<string name="errorIncorrectPassword">Mot de passe incorrect</string>
<string name="errorTransferPasswordLength">Le mot de passe doit comporter entre 6 et 25 caractères</string>
<string name="expired">Expiré</string>
<string name="expiresAt">Expire à %s</string>
<string name="expiresIn">Expire dans %d jours</string>
<string name="expiresToday">Expire aujourd’hui</string>
<string name="expiresThe">Expire le %s à %s</string>
<string name="expiresTomorrow">Expire demain</string>
<plurals name="filesCount">
<item quantity="one">%d fichier</item>
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@
<string name="errorAppIntegrity">Il dispositivo non è riconosciuto come sicuro</string>
<string name="errorIncorrectPassword">Password errata</string>
<string name="errorTransferPasswordLength">La password deve essere compresa tra 6 e 24 caratteri</string>
<string name="expired">Scaduto</string>
<string name="expiresAt">Scade al %s</string>
<string name="expiresIn">Scade tra %d giorni</string>
<string name="expiresToday">Scade oggi</string>
<string name="expiresThe">Scade il %s alle %s</string>
<string name="expiresTomorrow">Scade domani</string>
<plurals name="filesCount">
<item quantity="one">%d file</item>
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@
<string name="deeplinkPasswordDescription">Enter the password you have been given to download these files.</string>
<string name="deeplinkTransferExpired">This transfer has expired</string>
<string name="deeplinkTransferNotFound">This transfer does not exist</string>
<string name="downloadedTransferLabel">Downloaded transfer: %d/%d\u0020</string>
<string name="downloadedTransferLabel">Downloaded transfer: %d/%d</string>
<string name="errorAppIntegrity">Your device is not recognized as safe</string>
<string name="errorIncorrectPassword">Incorrect password</string>
<string name="errorTransferPasswordLength">The password must be between 6 and 25 characters</string>
<string name="expired">Expired</string>
<string name="expiresAt">Expires at %s</string>
<string name="expiresIn">Expires in %d days</string>
<string name="expiresToday">Expires today</string>
<string name="expiresThe">Expires on %s at %s</string>
<string name="expiresTomorrow">Expires tomorrow</string>
<plurals name="filesCount">
<item quantity="one">%d file</item>
Expand Down
Loading

0 comments on commit 982a040

Please sign in to comment.