mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-05-04 15:35:38 +01:00
Always prefetch wallpaper before opening a conversation.
This commit is contained in:
committed by
Greyson Parrelli
parent
9b4a13a491
commit
b8b9a632b5
@@ -13,12 +13,9 @@ import org.signal.core.models.UriSerializer
|
||||
import org.signal.core.models.media.Media
|
||||
import org.thoughtcrime.securesms.badges.models.Badge
|
||||
import org.thoughtcrime.securesms.conversation.ConversationIntents.ConversationScreenType
|
||||
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
||||
import org.thoughtcrime.securesms.mms.SlideFactory
|
||||
import org.thoughtcrime.securesms.recipients.Recipient.Companion.resolved
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.stickers.StickerLocator
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
||||
|
||||
@Serializable
|
||||
@Parcelize
|
||||
@@ -43,14 +40,6 @@ data class ConversationArgs(
|
||||
@IgnoredOnParcel
|
||||
val draftMediaType: SlideFactory.MediaType? = SlideFactory.MediaType.from(draftContentType)
|
||||
|
||||
@IgnoredOnParcel
|
||||
val wallpaper: ChatWallpaper?
|
||||
get() = resolved(recipientId).wallpaper
|
||||
|
||||
@IgnoredOnParcel
|
||||
val chatColors: ChatColors
|
||||
get() = resolved(recipientId).chatColors
|
||||
|
||||
fun canInitializeFromDatabase(): Boolean {
|
||||
return draftText == null && (draftMedia == null || ConversationIntents.isBubbleIntentUri(draftMedia) || ConversationIntents.isNotificationIntentUri(draftMedia)) && draftMediaType == null
|
||||
}
|
||||
|
||||
+13
-10
@@ -93,6 +93,7 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
@@ -479,8 +480,7 @@ class ConversationFragment :
|
||||
repository = ConversationRepository(localContext = requireContext(), isInBubble = args.conversationScreenType == ConversationScreenType.BUBBLE),
|
||||
recipientRepository = conversationRecipientRepository,
|
||||
messageRequestRepository = messageRequestRepository,
|
||||
scheduledMessagesRepository = ScheduledMessagesRepository(),
|
||||
initialChatColors = args.chatColors
|
||||
scheduledMessagesRepository = ScheduledMessagesRepository()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -685,8 +685,6 @@ class ConversationFragment :
|
||||
incognito = args.isIncognito
|
||||
)
|
||||
conversationToolbarOnScrollHelper.attach(binding.conversationItemRecycler)
|
||||
presentWallpaper(args.wallpaper)
|
||||
presentChatColors(args.chatColors)
|
||||
presentConversationTitle(viewModel.recipientSnapshot)
|
||||
presentGroupConversationSubtitle(createGroupSubtitleString(viewModel.titleViewParticipantsSnapshot))
|
||||
presentActionBarMenu()
|
||||
@@ -1324,10 +1322,11 @@ class ConversationFragment :
|
||||
lifecycleScope.launch {
|
||||
viewModel
|
||||
.pinnedMessages
|
||||
.combine(viewModel.wallpaper) { messages, wallpaper -> messages to wallpaper }
|
||||
.flowWithLifecycle(viewLifecycleOwner.lifecycle)
|
||||
.flowOn(Dispatchers.Main)
|
||||
.collect {
|
||||
presentPinnedMessage(it, args.wallpaper != null)
|
||||
.collect { (messages, wallpaper) ->
|
||||
presentPinnedMessage(pinnedMessages = messages, hasWallpaper = wallpaper != null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1679,8 +1678,12 @@ class ConversationFragment :
|
||||
presentConversationTitle(recipient)
|
||||
presentChatColors(recipient.chatColors)
|
||||
invalidateOptionsMenu()
|
||||
|
||||
updateMessageRequestAcceptedState(!viewModel.hasMessageRequestState)
|
||||
|
||||
recyclerViewColorizer.setChatColors(recipient.chatColors)
|
||||
if (adapter.onHasWallpaperChanged(hasWallpaper = recipient.wallpaper != null)) {
|
||||
conversationItemDecorations.hasWallpaper = recipient.wallpaper != null
|
||||
}
|
||||
}
|
||||
|
||||
@MainThread
|
||||
@@ -2147,7 +2150,7 @@ class ConversationFragment :
|
||||
lifecycleOwner = viewLifecycleOwner,
|
||||
requestManager = Glide.with(this),
|
||||
clickListener = ConversationItemClickListener(),
|
||||
hasWallpaper = args.wallpaper != null,
|
||||
hasWallpaper = viewModel.wallpaperSnapshot != null,
|
||||
colorizer = colorizer,
|
||||
startExpirationTimeout = viewModel::startExpirationTimeout,
|
||||
chatColorsDataProvider = viewModel::chatColorsSnapshot,
|
||||
@@ -2164,7 +2167,7 @@ class ConversationFragment :
|
||||
adapter.setPagingController(viewModel.pagingController)
|
||||
|
||||
recyclerViewColorizer = RecyclerViewColorizer(binding.conversationItemRecycler)
|
||||
recyclerViewColorizer.setChatColors(args.chatColors)
|
||||
viewModel.recipientSnapshot?.chatColors?.let { recyclerViewColorizer.setChatColors(it) }
|
||||
|
||||
binding.conversationItemRecycler.adapter = ConcatAdapter(typingIndicatorAdapter, adapter)
|
||||
multiselectItemDecoration = MultiselectItemDecoration(
|
||||
@@ -2201,7 +2204,7 @@ class ConversationFragment :
|
||||
threadHeaderMarginDecoration.toolbarMargin = statusBarInset + resources.getDimensionPixelSize(R.dimen.signal_m3_toolbar_height) + 16.dp
|
||||
binding.conversationItemRecycler.addItemDecoration(threadHeaderMarginDecoration)
|
||||
|
||||
conversationItemDecorations = ConversationItemDecorations(hasWallpaper = args.wallpaper != null)
|
||||
conversationItemDecorations = ConversationItemDecorations(hasWallpaper = viewModel.wallpaperSnapshot != null)
|
||||
binding.conversationItemRecycler.addItemDecoration(conversationItemDecorations, 0)
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -35,6 +35,7 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
@@ -58,7 +59,6 @@ import org.thoughtcrime.securesms.banner.banners.UnauthorizedBanner
|
||||
import org.thoughtcrime.securesms.contactshare.Contact
|
||||
import org.thoughtcrime.securesms.conversation.ConversationMessage
|
||||
import org.thoughtcrime.securesms.conversation.ScheduledMessagesRepository
|
||||
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
||||
import org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart
|
||||
import org.thoughtcrime.securesms.conversation.plaintext.PlaintextExportRepository
|
||||
import org.thoughtcrime.securesms.conversation.v2.data.ConversationElementKey
|
||||
@@ -102,6 +102,7 @@ import org.thoughtcrime.securesms.util.hasGiftBadge
|
||||
import org.thoughtcrime.securesms.util.rx.RxStore
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.time.Duration
|
||||
|
||||
/**
|
||||
@@ -110,7 +111,6 @@ import kotlin.time.Duration
|
||||
class ConversationViewModel(
|
||||
val threadId: Long,
|
||||
requestedStartingPosition: Int,
|
||||
initialChatColors: ChatColors,
|
||||
private val repository: ConversationRepository,
|
||||
recipientRepository: ConversationRecipientRepository,
|
||||
messageRequestRepository: MessageRequestRepository,
|
||||
@@ -158,7 +158,7 @@ class ConversationViewModel(
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
||||
private val chatBounds: BehaviorSubject<Rect> = BehaviorSubject.create()
|
||||
private val chatColors: RxStore<ChatColorsDrawable.ChatColorsData> = RxStore(ChatColorsDrawable.ChatColorsData(initialChatColors, null))
|
||||
private val chatColors: RxStore<ChatColorsDrawable.ChatColorsData> = RxStore(ChatColorsDrawable.ChatColorsData(null, null))
|
||||
val chatColorsSnapshot: ChatColorsDrawable.ChatColorsData get() = chatColors.state
|
||||
|
||||
@Volatile
|
||||
@@ -172,6 +172,8 @@ class ConversationViewModel(
|
||||
val isPushAvailable: Boolean
|
||||
get() = recipientSnapshot?.isRegistered == true && Recipient.self().isRegistered
|
||||
|
||||
val wallpaper: Flow<ChatWallpaper?> = recipient.asFlow().map { it.wallpaper }.distinctUntilChanged()
|
||||
|
||||
val wallpaperSnapshot: ChatWallpaper?
|
||||
get() = recipientSnapshot?.wallpaper
|
||||
|
||||
@@ -216,7 +218,7 @@ class ConversationViewModel(
|
||||
private val _plaintextExportState = MutableStateFlow<PlaintextExportState>(PlaintextExportState.None)
|
||||
val plaintextExportState: StateFlow<PlaintextExportState> = _plaintextExportState
|
||||
|
||||
private val plaintextExportCancelled = java.util.concurrent.atomic.AtomicBoolean(false)
|
||||
private val plaintextExportCancelled = AtomicBoolean(false)
|
||||
|
||||
init {
|
||||
disposables += recipient
|
||||
|
||||
+2
-19
@@ -168,7 +168,6 @@ import org.thoughtcrime.securesms.util.SnapToTopDataObserver;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.PagingMappingAdapter;
|
||||
import org.thoughtcrime.securesms.verify.SelfVerificationFailureSheet;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
||||
import org.signal.core.ui.WindowSizeClassExtensionsKt;
|
||||
import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState;
|
||||
|
||||
@@ -1305,15 +1304,7 @@ public class ConversationListFragment extends MainFragment implements Conversati
|
||||
}
|
||||
|
||||
private void handleCreateConversation(long threadId, Recipient recipient, int distributionType) {
|
||||
SimpleTask.run(getLifecycle(), () -> {
|
||||
ChatWallpaper wallpaper = recipient.resolve().getWallpaper();
|
||||
if (wallpaper != null && !wallpaper.prefetch(requireContext(), 250)) {
|
||||
Log.w(TAG, "Failed to prefetch wallpaper.");
|
||||
}
|
||||
return null;
|
||||
}, (nothing) -> {
|
||||
getNavigator().goToConversation(recipient.getId(), threadId, distributionType, -1);
|
||||
});
|
||||
getNavigator().goToConversation(recipient.getId(), threadId, distributionType, -1);
|
||||
}
|
||||
|
||||
private void handleOpenIncognito(@NonNull Conversation conversation) {
|
||||
@@ -1321,15 +1312,7 @@ public class ConversationListFragment extends MainFragment implements Conversati
|
||||
Recipient recipient = conversation.getThreadRecord().getRecipient();
|
||||
int distributionType = conversation.getThreadRecord().getDistributionType();
|
||||
|
||||
SimpleTask.run(getLifecycle(), () -> {
|
||||
ChatWallpaper wallpaper = recipient.resolve().getWallpaper();
|
||||
if (wallpaper != null && !wallpaper.prefetch(requireContext(), 250)) {
|
||||
Log.w(TAG, "Failed to prefetch wallpaper.");
|
||||
}
|
||||
return null;
|
||||
}, (nothing) -> {
|
||||
getNavigator().goToConversation(recipient.getId(), threadId, distributionType, -1, true);
|
||||
});
|
||||
getNavigator().goToConversation(recipient.getId(), threadId, distributionType, -1, true);
|
||||
}
|
||||
|
||||
private void startActionModeIfNotActive() {
|
||||
|
||||
@@ -17,6 +17,7 @@ import androidx.lifecycle.viewModelScope
|
||||
import androidx.lifecycle.viewmodel.CreationExtras
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -29,14 +30,18 @@ import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.reactive.asFlow
|
||||
import kotlinx.coroutines.rx3.asObservable
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.calls.log.CallLogRow
|
||||
import org.thoughtcrime.securesms.components.settings.app.notifications.profiles.NotificationProfilesRepository
|
||||
import org.thoughtcrime.securesms.components.snackbars.SnackbarStateConsumerRegistry
|
||||
import org.thoughtcrime.securesms.conversation.ConversationArgs
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.megaphone.Megaphone
|
||||
import org.thoughtcrime.securesms.megaphone.Megaphones
|
||||
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.stories.Stories
|
||||
import org.thoughtcrime.securesms.util.delegate
|
||||
import org.thoughtcrime.securesms.window.AppScaffoldNavigator
|
||||
@@ -44,11 +49,12 @@ import java.util.Optional
|
||||
|
||||
@OptIn(ExperimentalMaterial3AdaptiveApi::class)
|
||||
class MainNavigationViewModel(
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
initialListLocation: MainNavigationListLocation = MainNavigationListLocation.CHATS
|
||||
) : ViewModel(), MainNavigationRouter {
|
||||
|
||||
companion object {
|
||||
private val TAG = Log.tag(MainNavigationViewModel::class)
|
||||
private const val LOCK_PANE_TO_SECONDARY = "lock_pane_to_secondary"
|
||||
}
|
||||
|
||||
@@ -141,9 +147,11 @@ class MainNavigationViewModel(
|
||||
is MainNavigationDetailLocation.Chats.Conversation -> {
|
||||
internalActiveChatThreadId.update { location.conversationArgs.threadId }
|
||||
}
|
||||
|
||||
is MainNavigationDetailLocation.Calls -> {
|
||||
internalActiveCallId.update { location.controllerKey }
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
@@ -221,8 +229,13 @@ class MainNavigationViewModel(
|
||||
return
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
internalDetailLocation.emit(location)
|
||||
when (location) {
|
||||
is MainNavigationDetailLocation.Chats.Conversation -> goToConversation(location.conversationArgs)
|
||||
else -> {
|
||||
viewModelScope.launch {
|
||||
internalDetailLocation.emit(location)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +252,16 @@ class MainNavigationViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun goToConversation(args: ConversationArgs) = viewModelScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val wallpaper = Recipient.resolved(args.recipientId).wallpaper
|
||||
if (wallpaper?.prefetch(AppDependencies.application, 250) == false) {
|
||||
Log.w(TAG, "goToConversation: Failed to prefetch wallpaper.")
|
||||
}
|
||||
}
|
||||
internalDetailLocation.emit(MainNavigationDetailLocation.Chats.Conversation(args))
|
||||
}
|
||||
|
||||
fun goToCameraFirstStoryCapture() {
|
||||
viewModelScope.launch {
|
||||
internalNavigationEvents.emit(NavigationEvent.STORY_CAMERA_FIRST)
|
||||
|
||||
Reference in New Issue
Block a user