Add MediaNoLongerAvailable wiring.

This commit is contained in:
Alex Hart
2024-10-31 15:29:28 -03:00
committed by GitHub
parent 1a8988f825
commit 719ae72270
9 changed files with 167 additions and 0 deletions

View File

@@ -134,5 +134,6 @@ public interface BindableConversationItem extends Unbindable, GiphyMp4Playable,
void onMessageRequestAcceptOptionsClicked();
void onItemDoubleClick(MultiselectPart multiselectPart);
void onPaymentTombstoneClicked();
void onDisplayMediaNoLongerAvailableSheet();
}
}

View File

@@ -16,6 +16,8 @@ import org.thoughtcrime.securesms.stickers.StickerLocator
import org.thoughtcrime.securesms.util.ParcelUtil
import org.whispersystems.signalservice.api.util.UuidUtil
import java.util.UUID
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.milliseconds
/**
* Note: We have to use our own Parcelable implementation because we need to do custom stuff to preserve
@@ -146,6 +148,12 @@ abstract class Attachment(
val isPermanentlyFailed: Boolean
get() = transferState == AttachmentTable.TRANSFER_PROGRESS_PERMANENT_FAILURE
/**
* Denotes whether the media for the given attachment is no longer available for download.
*/
val isMediaNoLongerAvailableForDownload: Boolean
get() = isPermanentlyFailed && uploadTimestamp.milliseconds > 30.days
val isSticker: Boolean
get() = stickerLocator != null

View File

@@ -80,6 +80,7 @@ import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.badges.BadgeImageView;
import org.thoughtcrime.securesms.badges.gifts.GiftMessageView;
import org.thoughtcrime.securesms.badges.gifts.OpenableGift;
import org.thoughtcrime.securesms.billing.upgrade.UpgradeToStartMediaBackupSheet;
import org.thoughtcrime.securesms.calls.links.CallLinks;
import org.thoughtcrime.securesms.components.AlertView;
import org.thoughtcrime.securesms.components.AudioView;
@@ -2607,6 +2608,11 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
Log.w(TAG, "No activity existed to view the media.");
Toast.makeText(context, R.string.ConversationItem_unable_to_open_media, Toast.LENGTH_LONG).show();
}
} else if (slide.asAttachment().isMediaNoLongerAvailableForDownload() && !SignalStore.backup().backsUpMedia()) {
Log.i(TAG, "Clicked unavailable media, attempting to display sheet.");
if (eventListener != null) {
eventListener.onDisplayMediaNoLongerAvailableSheet();
}
} else if (slide.asAttachment().isPermanentlyFailed()) {
String failedMessage;

View File

@@ -112,6 +112,7 @@ import org.thoughtcrime.securesms.badges.gifts.OpenableGift
import org.thoughtcrime.securesms.badges.gifts.OpenableGiftItemDecoration
import org.thoughtcrime.securesms.badges.gifts.viewgift.received.ViewReceivedGiftBottomSheet
import org.thoughtcrime.securesms.badges.gifts.viewgift.sent.ViewSentGiftBottomSheet
import org.thoughtcrime.securesms.billing.upgrade.UpgradeToStartMediaBackupSheet
import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar
import org.thoughtcrime.securesms.components.AnimatingToggle
import org.thoughtcrime.securesms.components.ComposeText
@@ -2895,6 +2896,14 @@ class ConversationFragment :
this@ConversationFragment.showPaymentTombstoneLearnMoreDialog()
}
override fun onDisplayMediaNoLongerAvailableSheet() {
if (SignalStore.backup.areBackupsEnabled) {
UpgradeToStartMediaBackupSheet().show(parentFragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)
} else {
MediaNoLongerAvailableBottomSheet().show(parentFragmentManager, BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG)
}
}
override fun onMessageWithErrorClicked(messageRecord: MessageRecord) {
val recipientId = viewModel.recipientSnapshot?.id ?: return
if (messageRecord.isIdentityMismatchFailure) {

View File

@@ -0,0 +1,124 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.conversation.v2
import android.os.Bundle
import android.view.View
import androidx.activity.result.ActivityResultLauncher
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import org.signal.core.ui.BottomSheets
import org.signal.core.ui.Buttons
import org.signal.core.ui.Previews
import org.signal.core.ui.SignalPreview
import org.signal.core.ui.horizontalGutters
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.backup.v2.MessageBackupTier
import org.thoughtcrime.securesms.components.settings.app.subscription.MessageBackupsCheckoutLauncher.createBackupsCheckoutLauncher
import org.thoughtcrime.securesms.compose.ComposeBottomSheetDialogFragment
/**
* Bottom sheet displayed when the user taps media that is not available for download,
* over 30 days old, and they do not currently have a subscription.
*/
class MediaNoLongerAvailableBottomSheet : ComposeBottomSheetDialogFragment() {
private lateinit var checkoutLauncher: ActivityResultLauncher<MessageBackupTier?>
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
checkoutLauncher = createBackupsCheckoutLauncher {
dismissAllowingStateLoss()
}
}
@Composable
override fun SheetContent() {
MediaNoLongerAvailableBottomSheetContent(
onContinueClick = {
checkoutLauncher.launch(MessageBackupTier.PAID)
},
onNotNowClick = { dismissAllowingStateLoss() }
)
}
}
@Composable
private fun MediaNoLongerAvailableBottomSheetContent(
onContinueClick: () -> Unit = {},
onNotNowClick: () -> Unit = {}
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxWidth()
.horizontalGutters()
) {
BottomSheets.Handle()
Image(
painter = painterResource(R.drawable.image_signal_backups_media),
contentDescription = null,
modifier = Modifier.padding(vertical = 16.dp)
)
Text(
text = stringResource(R.string.MediaNoLongerAvailableSheet__this_media_is_no_longer_available),
style = MaterialTheme.typography.titleLarge,
textAlign = TextAlign.Center,
modifier = Modifier.padding(bottom = 10.dp)
)
Text(
text = stringResource(R.string.MediaNoLongerAvailableSheet__to_start_backing_up_all_your_media),
color = MaterialTheme.colorScheme.onSurfaceVariant,
textAlign = TextAlign.Center,
modifier = Modifier.padding(bottom = 92.dp)
)
Buttons.LargeTonal(
onClick = onContinueClick,
modifier = Modifier
.padding(bottom = 22.dp)
.defaultMinSize(minWidth = 220.dp)
) {
Text(
text = stringResource(R.string.MediaNoLongerAvailableSheet__continue)
)
}
TextButton(
onClick = onNotNowClick,
modifier = Modifier
.padding(bottom = 32.dp)
.defaultMinSize(minWidth = 220.dp)
) {
Text(
text = stringResource(R.string.MediaNoLongerAvailableSheet__not_now)
)
}
}
}
@SignalPreview
@Composable
private fun MediaNoLongerAvailableBottomSheetContentPreview() {
Previews.BottomSheetPreview {
MediaNoLongerAvailableBottomSheetContent()
}
}

View File

@@ -382,6 +382,10 @@ class MessageDetailsFragment : FullScreenDialogFragment(), MessageDetailsAdapter
Log.w(TAG, "Not yet implemented!", Exception())
}
override fun onDisplayMediaNoLongerAvailableSheet() {
Log.w(TAG, "Not yet implemented!", Exception())
}
interface Callback {
fun onMessageDetailsFragmentDismissed()
}