kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add ability to copy text slides in full.
rodzic
c4817ac017
commit
a44a105cbc
|
@ -69,8 +69,11 @@ import com.annimon.stream.Stream;
|
|||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.signal.core.util.DimensionUnit;
|
||||
import org.signal.core.util.StreamUtil;
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.LoggingFragment;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
@ -133,6 +136,7 @@ import org.thoughtcrime.securesms.mms.GlideApp;
|
|||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.mms.TextSlide;
|
||||
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
|
||||
|
@ -169,7 +173,6 @@ import org.thoughtcrime.securesms.util.Util;
|
|||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.WindowUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
import org.signal.core.util.concurrent.SimpleTask;
|
||||
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
|
||||
import org.thoughtcrime.securesms.verify.VerifyIdentityActivity;
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
|
||||
|
@ -931,22 +934,44 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||
}
|
||||
|
||||
private void handleCopyMessage(final Set<MultiselectPart> multiselectParts) {
|
||||
CharSequence bodies = Stream.of(multiselectParts)
|
||||
SimpleTask.run(() -> extractBodies(multiselectParts),
|
||||
bodies -> {
|
||||
if (!Util.isEmpty(bodies)) {
|
||||
Util.copyToClipboard(requireContext(), bodies);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private @NotNull CharSequence extractBodies(final Set<MultiselectPart> multiselectParts) {
|
||||
return Stream.of(multiselectParts)
|
||||
.sortBy(m -> m.getMessageRecord().getDateReceived())
|
||||
.map(MultiselectPart::getConversationMessage)
|
||||
.distinct()
|
||||
.map(m -> m.getDisplayBody(requireContext()))
|
||||
.filterNot(TextUtils::isEmpty)
|
||||
.map(message -> {
|
||||
if (MessageRecordUtil.hasTextSlide(message.getMessageRecord())) {
|
||||
TextSlide textSlide = MessageRecordUtil.requireTextSlide(message.getMessageRecord());
|
||||
if (textSlide.getUri() == null) {
|
||||
return message.getDisplayBody(requireContext());
|
||||
}
|
||||
|
||||
try (InputStream stream = PartAuthority.getAttachmentStream(requireContext(), textSlide.getUri())) {
|
||||
String body = StreamUtil.readFullyAsString(stream);
|
||||
return ConversationMessage.ConversationMessageFactory.createWithUnresolvedData(requireContext(), message.getMessageRecord(), body)
|
||||
.getDisplayBody(requireContext());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Failed to read text slide data.");
|
||||
}
|
||||
}
|
||||
|
||||
return message.getDisplayBody(requireContext());
|
||||
})
|
||||
.filterNot(Util::isEmpty)
|
||||
.collect(SpannableStringBuilder::new, (bodyBuilder, body) -> {
|
||||
if (bodyBuilder.length() > 0) {
|
||||
bodyBuilder.append('\n');
|
||||
}
|
||||
bodyBuilder.append(body);
|
||||
});
|
||||
|
||||
if (!TextUtils.isEmpty(bodies)) {
|
||||
Util.copyToClipboard(requireContext(), bodies);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDeleteMessages(final Set<MultiselectPart> multiselectParts) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.thoughtcrime.securesms.database.MmsSmsColumns
|
|||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.mms.TextSlide
|
||||
import org.thoughtcrime.securesms.stickers.StickerUrl
|
||||
|
||||
const val MAX_BODY_DISPLAY_LENGTH = 1000
|
||||
|
@ -78,6 +79,12 @@ fun MessageRecord.hasQuote(): Boolean =
|
|||
fun MessageRecord.hasLinkPreview(): Boolean =
|
||||
isMms && (this as MmsMessageRecord).linkPreviews.isNotEmpty()
|
||||
|
||||
fun MessageRecord.hasTextSlide(): Boolean =
|
||||
isMms && (this as MmsMessageRecord).slideDeck.textSlide != null && this.slideDeck.textSlide?.uri != null
|
||||
|
||||
fun MessageRecord.requireTextSlide(): TextSlide =
|
||||
requireNotNull((this as MmsMessageRecord).slideDeck.textSlide)
|
||||
|
||||
fun MessageRecord.hasBigImageLinkPreview(context: Context): Boolean {
|
||||
if (!hasLinkPreview()) {
|
||||
return false
|
||||
|
|
|
@ -153,8 +153,8 @@ public class Util {
|
|||
return collection == null || collection.isEmpty();
|
||||
}
|
||||
|
||||
public static boolean isEmpty(@Nullable String value) {
|
||||
return value == null || value.length() == 0;
|
||||
public static boolean isEmpty(@Nullable CharSequence charSequence) {
|
||||
return charSequence == null || charSequence.length() == 0;
|
||||
}
|
||||
|
||||
public static boolean hasItems(@Nullable Collection<?> collection) {
|
||||
|
|
Ładowanie…
Reference in New Issue