Search in sources :

Example 6 with MediaMmsMessageRecord

use of org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord in project Signal-Android by WhisperSystems.

the class ConversationFragment method performSave.

private void performSave(final MediaMmsMessageRecord message) {
    List<SaveAttachmentTask.Attachment> attachments = Stream.of(message.getSlideDeck().getSlides()).filter(s -> s.getUri() != null && (s.hasImage() || s.hasVideo() || s.hasAudio() || s.hasDocument())).map(s -> new SaveAttachmentTask.Attachment(s.getUri(), s.getContentType(), message.getDateReceived(), s.getFileName().orNull())).toList();
    if (!Util.isEmpty(attachments)) {
        SaveAttachmentTask saveTask = new SaveAttachmentTask(getActivity());
        saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, attachments.toArray(new SaveAttachmentTask.Attachment[0]));
        return;
    }
    Log.w(TAG, "No slide with attachable media found, failing nicely.");
    Toast.makeText(getActivity(), getResources().getQuantityString(R.plurals.ConversationFragment_error_while_saving_attachments_to_sd_card, 1), Toast.LENGTH_LONG).show();
}
Also used : TypingStatusRepository(org.thoughtcrime.securesms.components.TypingStatusRepository) Bundle(android.os.Bundle) GroupMigrationMembershipChange(org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange) RecaptchaProofBottomSheetFragment(org.thoughtcrime.securesms.ratelimit.RecaptchaProofBottomSheetFragment) GiphyMp4ItemDecoration(org.thoughtcrime.securesms.giph.mp4.GiphyMp4ItemDecoration) LinkPreview(org.thoughtcrime.securesms.linkpreview.LinkPreview) NonNull(androidx.annotation.NonNull) Uri(android.net.Uri) FrameLayout(android.widget.FrameLayout) AppCompatActivity(androidx.appcompat.app.AppCompatActivity) RecyclerViewColorizer(org.thoughtcrime.securesms.conversation.colors.RecyclerViewColorizer) ProgressDialogAsyncTask(org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask) Manifest(android.Manifest) LayoutTransition(android.animation.LayoutTransition) ActivityOptionsCompat(androidx.core.app.ActivityOptionsCompat) MultiselectForwardFragmentArgs(org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragmentArgs) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) MmsMessageRecord(org.thoughtcrime.securesms.database.model.MmsMessageRecord) SnapToTopDataObserver(org.thoughtcrime.securesms.util.SnapToTopDataObserver) HtmlUtil(org.thoughtcrime.securesms.util.HtmlUtil) PartAuthority(org.thoughtcrime.securesms.mms.PartAuthority) MultiDeviceViewOnceOpenJob(org.thoughtcrime.securesms.jobs.MultiDeviceViewOnceOpenJob) OutgoingTextMessage(org.thoughtcrime.securesms.sms.OutgoingTextMessage) ViewCompat(androidx.core.view.ViewCompat) StickyHeaderViewHolder(org.thoughtcrime.securesms.conversation.ConversationAdapter.StickyHeaderViewHolder) MultiselectForwardFragment(org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectForwardFragment) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) Set(java.util.Set) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) DimensionUnit(org.signal.core.util.DimensionUnit) SmoothScrollingLinearLayoutManager(org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager) MessageRecordUtil(org.thoughtcrime.securesms.util.MessageRecordUtil) Unit(kotlin.Unit) Nullable(androidx.annotation.Nullable) ChatWallpaper(org.thoughtcrime.securesms.wallpaper.ChatWallpaper) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) StickyHeaderDecoration(org.thoughtcrime.securesms.util.StickyHeaderDecoration) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) Stream(com.annimon.stream.Stream) ViewKt(androidx.core.view.ViewKt) Util(org.thoughtcrime.securesms.util.Util) ArrayList(java.util.ArrayList) MessageRequestState(org.thoughtcrime.securesms.messagerequests.MessageRequestState) SpannableStringBuilder(android.text.SpannableStringBuilder) SignalProxyUtil(org.thoughtcrime.securesms.util.SignalProxyUtil) Toast(android.widget.Toast) Menu(android.view.Menu) MediaMmsMessageRecord(org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord) GiphyMp4ProjectionRecycler(org.thoughtcrime.securesms.giph.mp4.GiphyMp4ProjectionRecycler) LiveData(androidx.lifecycle.LiveData) ListenableFuture(org.thoughtcrime.securesms.util.concurrent.ListenableFuture) LiveRecipient(org.thoughtcrime.securesms.recipients.LiveRecipient) DirectoryRefreshJob(org.thoughtcrime.securesms.jobs.DirectoryRefreshJob) Collectors(com.annimon.stream.Collectors) ViewModelProvider(androidx.lifecycle.ViewModelProvider) Contact(org.thoughtcrime.securesms.contactshare.Contact) RecipientBottomSheetDialogFragment(org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment) Permissions(org.thoughtcrime.securesms.permissions.Permissions) TextUtils(android.text.TextUtils) SafetyNumberChangeDialog(org.thoughtcrime.securesms.conversation.ui.error.SafetyNumberChangeDialog) IOException(java.io.IOException) Optional(org.whispersystems.libsignal.util.guava.Optional) ExecutionException(java.util.concurrent.ExecutionException) ItemClickListener(org.thoughtcrime.securesms.conversation.ConversationAdapter.ItemClickListener) StickerLocator(org.thoughtcrime.securesms.stickers.StickerLocator) Configuration(android.content.res.Configuration) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) RecipientExporter(org.thoughtcrime.securesms.recipients.RecipientExporter) LoggingFragment(org.thoughtcrime.securesms.LoggingFragment) PhoneNumberFormatter(org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter) ValueAnimator(android.animation.ValueAnimator) SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) Rect(android.graphics.Rect) ConversationTypingView(org.thoughtcrime.securesms.components.ConversationTypingView) SignalBottomActionBar(org.thoughtcrime.securesms.components.menu.SignalBottomActionBar) MessageSender(org.thoughtcrime.securesms.sms.MessageSender) MaterialAlertDialogBuilder(com.google.android.material.dialog.MaterialAlertDialogBuilder) GroupLinkInviteFriendsBottomSheetDialogFragment(org.thoughtcrime.securesms.groups.ui.invitesandrequests.invite.GroupLinkInviteFriendsBottomSheetDialogFragment) ViewUtil(org.thoughtcrime.securesms.util.ViewUtil) Animator(android.animation.Animator) R(org.thoughtcrime.securesms.R) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) GiphyMp4ProjectionPlayerHolder(org.thoughtcrime.securesms.giph.mp4.GiphyMp4ProjectionPlayerHolder) SmsDatabase(org.thoughtcrime.securesms.database.SmsDatabase) Locale(java.util.Locale) View(android.view.View) ViewOnceUtil(org.thoughtcrime.securesms.revealable.ViewOnceUtil) Recipient(org.thoughtcrime.securesms.recipients.Recipient) Animation(android.view.animation.Animation) RecyclerView(androidx.recyclerview.widget.RecyclerView) VoiceNotePlaybackState(org.thoughtcrime.securesms.components.voice.VoiceNotePlaybackState) NavHostFragment(androidx.navigation.fragment.NavHostFragment) SignalExecutors(org.signal.core.util.concurrent.SignalExecutors) ViewSwitcher(android.widget.ViewSwitcher) AppSettingsActivity(org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity) AsyncTask(android.os.AsyncTask) ContactUtil(org.thoughtcrime.securesms.contactshare.ContactUtil) MessageRequestViewModel(org.thoughtcrime.securesms.messagerequests.MessageRequestViewModel) HtmlCompat(androidx.core.text.HtmlCompat) LongMessageFragment(org.thoughtcrime.securesms.longmessage.LongMessageFragment) NotificationProfile(org.thoughtcrime.securesms.notifications.profiles.NotificationProfile) ViewGroup(android.view.ViewGroup) VoiceNoteMediaControllerOwner(org.thoughtcrime.securesms.components.voice.VoiceNoteMediaControllerOwner) Objects(java.util.Objects) Log(org.signal.core.util.logging.Log) List(java.util.List) TextView(android.widget.TextView) Slide(org.thoughtcrime.securesms.mms.Slide) ConversationItemAnimator(org.thoughtcrime.securesms.conversation.mutiselect.ConversationItemAnimator) GroupId(org.thoughtcrime.securesms.groups.GroupId) Toolbar(androidx.appcompat.widget.Toolbar) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) GiphyMp4PlaybackPolicy(org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicy) OnScrollListener(androidx.recyclerview.widget.RecyclerView.OnScrollListener) SaveAttachmentTask(org.thoughtcrime.securesms.util.SaveAttachmentTask) Snackbar(com.google.android.material.snackbar.Snackbar) MmsDatabase(org.thoughtcrime.securesms.database.MmsDatabase) GlideApp(org.thoughtcrime.securesms.mms.GlideApp) Context(android.content.Context) AlertDialog(androidx.appcompat.app.AlertDialog) SharedContactDetailsActivity(org.thoughtcrime.securesms.contactshare.SharedContactDetailsActivity) TopToastPopup(org.thoughtcrime.securesms.util.TopToastPopup) MultiselectPart(org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart) ReactionsBottomSheetDialogFragment(org.thoughtcrime.securesms.reactions.ReactionsBottomSheetDialogFragment) SignalLocalMetrics(org.thoughtcrime.securesms.util.SignalLocalMetrics) Intent(android.content.Intent) MenuItem(android.view.MenuItem) AnimationUtils(android.view.animation.AnimationUtils) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) HashSet(java.util.HashSet) SuppressLint(android.annotation.SuppressLint) StickerPackPreviewActivity(org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity) ActionItem(org.thoughtcrime.securesms.components.menu.ActionItem) GroupsV1MigrationInfoBottomSheetDialogFragment(org.thoughtcrime.securesms.groups.ui.migration.GroupsV1MigrationInfoBottomSheetDialogFragment) Colorizer(org.thoughtcrime.securesms.conversation.colors.Colorizer) ConversationScrollToView(org.thoughtcrime.securesms.components.ConversationScrollToView) ViewOnceMessageActivity(org.thoughtcrime.securesms.revealable.ViewOnceMessageActivity) GiphyMp4PlaybackController(org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackController) SimpleTask(org.thoughtcrime.securesms.util.concurrent.SimpleTask) VerifyIdentityActivity(org.thoughtcrime.securesms.verify.VerifyIdentityActivity) MultiselectItemDecoration(org.thoughtcrime.securesms.conversation.mutiselect.MultiselectItemDecoration) GroupDescriptionDialog(org.thoughtcrime.securesms.groups.ui.managegroup.dialogs.GroupDescriptionDialog) GroupDescriptionUtil(org.thoughtcrime.securesms.groups.v2.GroupDescriptionUtil) LayoutInflater(android.view.LayoutInflater) ActivityCompat(androidx.core.app.ActivityCompat) MessageDetailsFragment(org.thoughtcrime.securesms.messagedetails.MessageDetailsFragment) RemoteDeleteUtil(org.thoughtcrime.securesms.util.RemoteDeleteUtil) BlobProvider(org.thoughtcrime.securesms.providers.BlobProvider) CommunicationActions(org.thoughtcrime.securesms.util.CommunicationActions) CachedInflater(org.thoughtcrime.securesms.util.CachedInflater) InMemoryMessageRecord(org.thoughtcrime.securesms.database.model.InMemoryMessageRecord) ActionMode(androidx.appcompat.view.ActionMode) WindowUtil(org.thoughtcrime.securesms.util.WindowUtil) Color(android.graphics.Color) Observer(androidx.lifecycle.Observer) StorageUtil(org.thoughtcrime.securesms.util.StorageUtil) Bitmap(android.graphics.Bitmap) EnableCallNotificationSettingsDialog(org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog) ViewTreeObserver(android.view.ViewTreeObserver) Collections(java.util.Collections) InputStream(java.io.InputStream) SaveAttachmentTask(org.thoughtcrime.securesms.util.SaveAttachmentTask)

Example 7 with MediaMmsMessageRecord

use of org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord in project Signal-Android by WhisperSystems.

the class ConversationItem method setQuote.

private void setQuote(@NonNull MessageRecord current, @NonNull Optional<MessageRecord> previous, @NonNull Optional<MessageRecord> next, boolean isGroupThread, @NonNull ChatColors chatColors) {
    boolean startOfCluster = isStartOfMessageCluster(current, previous, isGroupThread);
    if (current.isMms() && !current.isMmsNotification() && ((MediaMmsMessageRecord) current).getQuote() != null) {
        if (quoteView == null) {
            throw new AssertionError();
        }
        Quote quote = ((MediaMmsMessageRecord) current).getQuote();
        // noinspection ConstantConditions
        quoteView.setQuote(glideRequests, quote.getId(), Recipient.live(quote.getAuthor()).get(), quote.getDisplayText(), quote.isOriginalMissing(), quote.getAttachment(), chatColors);
        quoteView.setVisibility(View.VISIBLE);
        quoteView.setTextSize(TypedValue.COMPLEX_UNIT_SP, SignalStore.settings().getMessageFontSize());
        quoteView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
        quoteView.setOnClickListener(view -> {
            if (eventListener != null && batchSelected.isEmpty()) {
                eventListener.onQuoteClicked((MmsMessageRecord) current);
            } else {
                passthroughClickListener.onClick(view);
            }
        });
        quoteView.setOnLongClickListener(passthroughClickListener);
        if (startOfCluster) {
            if (current.isOutgoing()) {
                quoteView.setTopCornerSizes(true, true);
            } else if (isGroupThread) {
                quoteView.setTopCornerSizes(false, false);
            } else {
                quoteView.setTopCornerSizes(true, true);
            }
        } else if (!isSingularMessage(current, previous, next, isGroupThread)) {
            if (current.isOutgoing()) {
                quoteView.setTopCornerSizes(true, false);
            } else {
                quoteView.setTopCornerSizes(false, true);
            }
        }
        if (mediaThumbnailStub.resolved()) {
            ViewUtil.setTopMargin(mediaThumbnailStub.require(), readDimen(R.dimen.message_bubble_top_padding));
        }
        if (linkPreviewStub.resolved() && !hasBigImageLinkPreview(current)) {
            ViewUtil.setTopMargin(linkPreviewStub.get(), readDimen(R.dimen.message_bubble_top_padding));
        }
    } else {
        if (quoteView != null) {
            quoteView.dismiss();
        }
        int topMargin = (current.isOutgoing() || !startOfCluster || !groupThread) ? 0 : readDimen(R.dimen.message_bubble_top_image_margin);
        if (mediaThumbnailStub.resolved()) {
            ViewUtil.setTopMargin(mediaThumbnailStub.require(), topMargin);
        }
    }
}
Also used : Quote(org.thoughtcrime.securesms.database.model.Quote) MediaMmsMessageRecord(org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord) TextPaint(android.text.TextPaint) SuppressLint(android.annotation.SuppressLint)

Example 8 with MediaMmsMessageRecord

use of org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord in project Signal-Android by WhisperSystems.

the class ConversationDataSource method load.

@Override
@Nullable
public ConversationMessage load(@NonNull MessageId messageId) {
    Stopwatch stopwatch = new Stopwatch("load(" + messageId + "), thread " + threadId);
    MessageDatabase database = messageId.isMms() ? SignalDatabase.mms() : SignalDatabase.sms();
    MessageRecord record = database.getMessageRecordOrNull(messageId.getId());
    stopwatch.split("message");
    try {
        if (record != null) {
            List<Mention> mentions;
            if (messageId.isMms()) {
                mentions = SignalDatabase.mentions().getMentionsForMessage(messageId.getId());
            } else {
                mentions = Collections.emptyList();
            }
            stopwatch.split("mentions");
            List<ReactionRecord> reactions = SignalDatabase.reactions().getReactions(messageId);
            record = ReactionHelper.recordWithReactions(record, reactions);
            stopwatch.split("reactions");
            if (messageId.isMms()) {
                List<DatabaseAttachment> attachments = SignalDatabase.attachments().getAttachmentsForMessage(messageId.getId());
                if (attachments.size() > 0) {
                    record = ((MediaMmsMessageRecord) record).withAttachments(context, attachments);
                }
            }
            stopwatch.split("attachments");
            return ConversationMessage.ConversationMessageFactory.createWithUnresolvedData(ApplicationDependencies.getApplication(), record, mentions);
        } else {
            return null;
        }
    } finally {
        stopwatch.stop(TAG);
    }
}
Also used : MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) Mention(org.thoughtcrime.securesms.database.model.Mention) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) MediaMmsMessageRecord(org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord) InMemoryMessageRecord(org.thoughtcrime.securesms.database.model.InMemoryMessageRecord) SmsMessageRecord(org.thoughtcrime.securesms.database.model.SmsMessageRecord) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) Nullable(androidx.annotation.Nullable)

Example 9 with MediaMmsMessageRecord

use of org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord in project Signal-Android by signalapp.

the class MenuState method getMenuState.

static MenuState getMenuState(@NonNull Recipient conversationRecipient, @NonNull Set<MultiselectPart> selectedParts, boolean shouldShowMessageRequest, boolean isNonAdminInAnnouncementGroup) {
    Builder builder = new Builder();
    boolean actionMessage = false;
    boolean hasText = false;
    boolean sharedContact = false;
    boolean viewOnce = false;
    boolean remoteDelete = false;
    boolean hasInMemory = false;
    boolean hasPendingMedia = false;
    boolean mediaIsSelected = false;
    for (MultiselectPart part : selectedParts) {
        MessageRecord messageRecord = part.getMessageRecord();
        if (isActionMessage(messageRecord)) {
            actionMessage = true;
            if (messageRecord.isInMemoryMessageRecord()) {
                hasInMemory = true;
            }
        }
        if (!(part instanceof MultiselectPart.Attachments)) {
            if (messageRecord.getBody().length() > 0) {
                hasText = true;
            }
        } else {
            mediaIsSelected = true;
            if (messageRecord.isMediaPending()) {
                hasPendingMedia = true;
            }
        }
        if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getSharedContacts().isEmpty()) {
            sharedContact = true;
        }
        if (messageRecord.isViewOnce()) {
            viewOnce = true;
        }
        if (messageRecord.isRemoteDelete()) {
            remoteDelete = true;
        }
    }
    boolean shouldShowForwardAction = !actionMessage && !sharedContact && !viewOnce && !remoteDelete && !hasPendingMedia && selectedParts.size() <= MAX_FORWARDABLE_COUNT;
    int uniqueRecords = selectedParts.stream().map(MultiselectPart::getMessageRecord).collect(Collectors.toSet()).size();
    if (uniqueRecords > 1) {
        builder.shouldShowForwardAction(shouldShowForwardAction).shouldShowReplyAction(false).shouldShowDetailsAction(false).shouldShowSaveAttachmentAction(false).shouldShowResendAction(false);
    } else {
        MessageRecord messageRecord = selectedParts.iterator().next().getMessageRecord();
        builder.shouldShowResendAction(messageRecord.isFailed()).shouldShowSaveAttachmentAction(mediaIsSelected && !actionMessage && !viewOnce && messageRecord.isMms() && !hasPendingMedia && !messageRecord.isMmsNotification() && ((MediaMmsMessageRecord) messageRecord).containsMediaSlide() && ((MediaMmsMessageRecord) messageRecord).getSlideDeck().getStickerSlide() == null).shouldShowForwardAction(shouldShowForwardAction).shouldShowDetailsAction(!actionMessage && !conversationRecipient.isReleaseNotes()).shouldShowReplyAction(canReplyToMessage(conversationRecipient, actionMessage, messageRecord, shouldShowMessageRequest, isNonAdminInAnnouncementGroup));
    }
    return builder.shouldShowCopyAction(!actionMessage && !remoteDelete && hasText).shouldShowDeleteAction(!hasInMemory && onlyContainsCompleteMessages(selectedParts)).shouldShowReactions(!conversationRecipient.isReleaseNotes()).build();
}
Also used : MultiselectPart(org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart) MediaMmsMessageRecord(org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord) MmsMessageRecord(org.thoughtcrime.securesms.database.model.MmsMessageRecord) MediaMmsMessageRecord(org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord)

Example 10 with MediaMmsMessageRecord

use of org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord in project Signal-Android by WhisperSystems.

the class ConversationFragment method handleForwardMessage.

private void handleForwardMessage(MessageRecord message) {
    Intent composeIntent = new Intent(getActivity(), ShareActivity.class);
    composeIntent.putExtra(Intent.EXTRA_TEXT, message.getDisplayBody().toString());
    if (message.isMms()) {
        MediaMmsMessageRecord mediaMessage = (MediaMmsMessageRecord) message;
        if (mediaMessage.containsMediaSlide()) {
            Slide slide = mediaMessage.getSlideDeck().getSlides().get(0);
            composeIntent.putExtra(Intent.EXTRA_STREAM, slide.getUri());
            composeIntent.setType(slide.getContentType());
        }
    }
    startActivity(composeIntent);
}
Also used : MediaMmsMessageRecord(org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord) Slide(org.thoughtcrime.securesms.mms.Slide) Intent(android.content.Intent)

Aggregations

MediaMmsMessageRecord (org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord)20 MessageRecord (org.thoughtcrime.securesms.database.model.MessageRecord)12 Nullable (androidx.annotation.Nullable)8 MultiselectPart (org.thoughtcrime.securesms.conversation.mutiselect.MultiselectPart)8 MmsMessageRecord (org.thoughtcrime.securesms.database.model.MmsMessageRecord)8 Slide (org.thoughtcrime.securesms.mms.Slide)8 SuppressLint (android.annotation.SuppressLint)7 Intent (android.content.Intent)6 MessageDatabase (org.thoughtcrime.securesms.database.MessageDatabase)6 ArrayList (java.util.ArrayList)5 ValueAnimator (android.animation.ValueAnimator)4 Context (android.content.Context)4 Color (android.graphics.Color)4 Rect (android.graphics.Rect)4 Uri (android.net.Uri)4 SpannableStringBuilder (android.text.SpannableStringBuilder)4 TextPaint (android.text.TextPaint)4 View (android.view.View)4 ViewGroup (android.view.ViewGroup)4 TextView (android.widget.TextView)4