Skip to content

Commit

Permalink
feat: Correctly display Transfer date
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinBoulongne committed Feb 21, 2025
1 parent fe1c019 commit e47a212
Show file tree
Hide file tree
Showing 14 changed files with 338 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.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,12 @@ 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 (expiryText, expiryColor) = if (transfer.isExpired) {
// stringResource(R.string.transferExpired) to SwissTransferTheme.materialColors.error
// } else {
// transfer.getFormattedExpiry() to SwissTransferTheme.colors.secondaryTextColor
// }
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 @@ -46,7 +46,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 @@ -74,7 +74,7 @@ fun TransferInfo(getTransfer: () -> TransferUi) {

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

HorizontalDivider(modifier = Modifier.padding(vertical = Margin.Medium))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,77 @@
package com.infomaniak.swisstransfer.ui.utils

import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import com.infomaniak.core.*
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 {
EXPIRED, // Has expired before today
EXPIRED_TODAY, // Has expired today
EXPIRES_TODAY, // Will expire today
EXPIRES_TOMORROW, // Will expire tomorrow
NOT_EXPIRED, // Will expire someday after tomorrow
}

fun TransferUi.expiryStatus(): ExpiryStatus {
val expiry = expirationDateTimestamp.toDateFromSeconds()
val now = Clock.System.now().epochSeconds.toDateFromSeconds()
val tomorrow = now.tomorrow()
return when {
expiry.before(now.startOfTheDay()) -> ExpiryStatus.EXPIRED
expiry in now.startOfTheDay()..now -> ExpiryStatus.EXPIRED_TODAY
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 expiry = expirationDateTimestamp.toDateFromSeconds()
val text = when (expiryStatus()) {
ExpiryStatus.EXPIRED -> stringResource(R.string.expiredThe, expiry.format())
ExpiryStatus.EXPIRED_TODAY -> stringResource(R.string.expiredAt, expiry.format(FORMAT_HOUR_MINUTES))
ExpiryStatus.EXPIRES_TODAY -> stringResource(R.string.expiresAt, expiry.format(FORMAT_HOUR_MINUTES))
ExpiryStatus.EXPIRES_TOMORROW -> stringResource(R.string.expiresTomorrow)
else -> stringResource(R.string.expiresIn, daysBeforeExpiry)
}

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),
)
}
5 changes: 4 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,11 @@
<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="expiredAt">Abgelaufen bei %s</string>
<string name="expiredThe">Abgelaufen am %s</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
5 changes: 4 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,11 @@
<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="expiredAt">Expirado a %s</string>
<string name="expiredThe">Expirado el %s</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
7 changes: 5 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,15 @@
<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="expiredAt">Expiré à %s</string>
<string name="expiredThe">Expiré le %s</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
5 changes: 4 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,11 @@
<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="expiredAt">Scaduto al %s</string>
<string name="expiredThe">Scaduto il %s</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
7 changes: 5 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,15 @@
<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="expiredAt">Expired at %s</string>
<string name="expiredThe">Expired on %s</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
33 changes: 0 additions & 33 deletions app/src/test/java/com/infomaniak/swisstransfer/ExampleUnitTest.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Infomaniak SwissTransfer - Android
* Copyright (C) 2024 Infomaniak Network SA
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.infomaniak.swisstransfer

import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.TransferUi
import com.infomaniak.swisstransfer.dataset.DummyTransfer
import com.infomaniak.swisstransfer.ui.utils.ExpiryStatus
import com.infomaniak.swisstransfer.ui.utils.daysBeforeExpiry
import com.infomaniak.swisstransfer.ui.utils.expiryStatus
import com.infomaniak.swisstransfer.ui.utils.isExpired
import org.junit.Test

class TransferDatesUnitTest {

@Test
fun check_expiryStatus_are_correct() {
assert(TransferUi(DummyTransfer.expired).expiryStatus() == ExpiryStatus.EXPIRED)
assert(TransferUi(DummyTransfer.expiredToday).expiryStatus() == ExpiryStatus.EXPIRED_TODAY)
assert(TransferUi(DummyTransfer.expiresToday).expiryStatus() == ExpiryStatus.EXPIRES_TODAY)
assert(TransferUi(DummyTransfer.expiresTomorrow).expiryStatus() == ExpiryStatus.EXPIRES_TOMORROW)
assert(TransferUi(DummyTransfer.notExpired).expiryStatus() == ExpiryStatus.NOT_EXPIRED)
}

@Test
fun check_daysBeforeExpiry_are_correct() {
assert(TransferUi(DummyTransfer.expired).daysBeforeExpiry == -5)
assert(TransferUi(DummyTransfer.expiredToday).daysBeforeExpiry == 0)
assert(TransferUi(DummyTransfer.expiresToday).daysBeforeExpiry == 0)
assert(TransferUi(DummyTransfer.expiresTomorrow).daysBeforeExpiry == 1)
assert(TransferUi(DummyTransfer.notExpired).daysBeforeExpiry == 5)
}

@Test
fun check_isExpired_are_correct() {
assert(TransferUi(DummyTransfer.expired).isExpired)
assert(TransferUi(DummyTransfer.expiredToday).isExpired)
assert(TransferUi(DummyTransfer.expiresToday).isExpired.not())
assert(TransferUi(DummyTransfer.expiresTomorrow).isExpired.not())
assert(TransferUi(DummyTransfer.notExpired).isExpired.not())
assert(TransferUi(DummyTransfer.downloaded).isExpired)
}
}
Loading

0 comments on commit e47a212

Please sign in to comment.