mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
Merge pull request #508 from Brice-W/data-extraction-2
Data extraction notifications
This commit is contained in:
commit
9f26436041
@ -52,6 +52,8 @@ import androidx.viewpager.widget.ViewPager;
|
|||||||
import com.codewaves.stickyheadergrid.StickyHeaderGridLayoutManager;
|
import com.codewaves.stickyheadergrid.StickyHeaderGridLayoutManager;
|
||||||
import com.google.android.material.tabs.TabLayout;
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
|
||||||
|
import org.session.libsession.messaging.messages.control.DataExtractionNotification;
|
||||||
|
import org.session.libsession.messaging.sending_receiving.MessageSender;
|
||||||
import org.session.libsession.messaging.threads.Address;
|
import org.session.libsession.messaging.threads.Address;
|
||||||
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
|
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter;
|
||||||
import org.thoughtcrime.securesms.database.MediaDatabase;
|
import org.thoughtcrime.securesms.database.MediaDatabase;
|
||||||
@ -351,6 +353,12 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
|
|||||||
saveTask.executeOnExecutor(THREAD_POOL_EXECUTOR,
|
saveTask.executeOnExecutor(THREAD_POOL_EXECUTOR,
|
||||||
attachments.toArray(new SaveAttachmentTask.Attachment[attachments.size()]));
|
attachments.toArray(new SaveAttachmentTask.Attachment[attachments.size()]));
|
||||||
actionMode.finish();
|
actionMode.finish();
|
||||||
|
// Sending a Data extraction notification (for incoming attachments only)
|
||||||
|
boolean containsIncoming = mediaRecords.parallelStream().anyMatch(m -> !m.isOutgoing());
|
||||||
|
if (containsIncoming) {
|
||||||
|
//TODO uncomment line below when Data extraction will be activated
|
||||||
|
//sendMediaSavedNotificationIfNeeded();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
})
|
})
|
||||||
@ -358,6 +366,16 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
|
|||||||
}, mediaRecords.size());
|
}, mediaRecords.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a MediaSaved notification to the recipient
|
||||||
|
*/
|
||||||
|
private void sendMediaSavedNotificationIfNeeded() {
|
||||||
|
// we don't send media saved notification for groups
|
||||||
|
if (recipient.isGroupRecipient()) return;
|
||||||
|
DataExtractionNotification message = new DataExtractionNotification(new DataExtractionNotification.Kind.MediaSaved(System.currentTimeMillis()));
|
||||||
|
MessageSender.send(message, recipient.getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private void handleDeleteMedia(@NonNull Collection<MediaDatabase.MediaRecord> mediaRecords) {
|
private void handleDeleteMedia(@NonNull Collection<MediaDatabase.MediaRecord> mediaRecords) {
|
||||||
int recordCount = mediaRecords.size();
|
int recordCount = mediaRecords.size();
|
||||||
|
@ -39,7 +39,8 @@ import android.view.Window;
|
|||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
import org.session.libsession.messaging.messages.control.DataExtractionNotification;
|
||||||
|
import org.session.libsession.messaging.sending_receiving.MessageSender;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.ActionBar;
|
import androidx.appcompat.app.ActionBar;
|
||||||
@ -52,7 +53,6 @@ import androidx.recyclerview.widget.LinearLayoutManager;
|
|||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.viewpager.widget.PagerAdapter;
|
import androidx.viewpager.widget.PagerAdapter;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.viewpager.widget.ViewPager;
|
||||||
|
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment;
|
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment;
|
||||||
import org.session.libsession.messaging.threads.Address;
|
import org.session.libsession.messaging.threads.Address;
|
||||||
import org.session.libsession.messaging.threads.recipients.Recipient;
|
import org.session.libsession.messaging.threads.recipients.Recipient;
|
||||||
@ -352,11 +352,26 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
|
|||||||
saveTask.executeOnExecutor(
|
saveTask.executeOnExecutor(
|
||||||
AsyncTask.THREAD_POOL_EXECUTOR,
|
AsyncTask.THREAD_POOL_EXECUTOR,
|
||||||
new Attachment(mediaItem.uri, mediaItem.type, saveDate, null));
|
new Attachment(mediaItem.uri, mediaItem.type, saveDate, null));
|
||||||
|
// Sending a Data extraction notification (for incoming attachments only)
|
||||||
|
if(!mediaItem.outgoing) {
|
||||||
|
//TODO uncomment line below when Data extraction will be activated
|
||||||
|
//sendMediaSavedNotificationIfNeeded();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.execute();
|
.execute();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a MediaSaved notification to the recipient
|
||||||
|
*/
|
||||||
|
private void sendMediaSavedNotificationIfNeeded() {
|
||||||
|
// we don't send media saved notification for groups
|
||||||
|
if (conversationRecipient.isGroupRecipient()) return;
|
||||||
|
DataExtractionNotification message = new DataExtractionNotification(new DataExtractionNotification.Kind.MediaSaved(System.currentTimeMillis()));
|
||||||
|
MessageSender.send(message, conversationRecipient.getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private void deleteMedia() {
|
private void deleteMedia() {
|
||||||
MediaItem mediaItem = getCurrentMediaItem();
|
MediaItem mediaItem = getCurrentMediaItem();
|
||||||
|
@ -57,6 +57,7 @@ import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
|
|||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
|
import org.session.libsession.messaging.messages.control.DataExtractionNotification;
|
||||||
import org.session.libsession.messaging.messages.visible.Quote;
|
import org.session.libsession.messaging.messages.visible.Quote;
|
||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage;
|
import org.session.libsession.messaging.messages.visible.VisibleMessage;
|
||||||
import org.session.libsession.messaging.opengroups.OpenGroupAPI;
|
import org.session.libsession.messaging.opengroups.OpenGroupAPI;
|
||||||
@ -745,6 +746,11 @@ public class ConversationFragment extends Fragment
|
|||||||
if (!Util.isEmpty(attachments)) {
|
if (!Util.isEmpty(attachments)) {
|
||||||
SaveAttachmentTask saveTask = new SaveAttachmentTask(getActivity());
|
SaveAttachmentTask saveTask = new SaveAttachmentTask(getActivity());
|
||||||
saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, attachments.toArray(new SaveAttachmentTask.Attachment[0]));
|
saveTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, attachments.toArray(new SaveAttachmentTask.Attachment[0]));
|
||||||
|
// Sending a Data extraction notification (for incoming attachments only)
|
||||||
|
if(!message.isOutgoing()) {
|
||||||
|
//TODO uncomment line below when Data extraction will be activated
|
||||||
|
//sendMediaSavedNotificationIfNeeded();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,6 +763,16 @@ public class ConversationFragment extends Fragment
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a MediaSaved notification to the recipient
|
||||||
|
*/
|
||||||
|
private void sendMediaSavedNotificationIfNeeded() {
|
||||||
|
// we don't send media saved notification for groups
|
||||||
|
if (recipient.isGroupRecipient()) return;
|
||||||
|
DataExtractionNotification message = new DataExtractionNotification(new DataExtractionNotification.Kind.MediaSaved(System.currentTimeMillis()));
|
||||||
|
MessageSender.send(message, recipient.getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
public @NonNull Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||||
Log.i(TAG, "onCreateLoader");
|
Log.i(TAG, "onCreateLoader");
|
||||||
|
@ -14,6 +14,7 @@ import androidx.annotation.ColorInt;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage;
|
||||||
import org.thoughtcrime.securesms.BindableConversationItem;
|
import org.thoughtcrime.securesms.BindableConversationItem;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.loki.utilities.GeneralUtilitiesKt;
|
import org.thoughtcrime.securesms.loki.utilities.GeneralUtilitiesKt;
|
||||||
@ -104,6 +105,8 @@ public class ConversationUpdateItem extends LinearLayout
|
|||||||
else if (messageRecord.isCallLog()) setCallRecord(messageRecord);
|
else if (messageRecord.isCallLog()) setCallRecord(messageRecord);
|
||||||
else if (messageRecord.isJoined()) setJoinedRecord(messageRecord);
|
else if (messageRecord.isJoined()) setJoinedRecord(messageRecord);
|
||||||
else if (messageRecord.isExpirationTimerUpdate()) setTimerRecord(messageRecord);
|
else if (messageRecord.isExpirationTimerUpdate()) setTimerRecord(messageRecord);
|
||||||
|
else if (messageRecord.isScreenshotExtraction()) setDataExtractionRecord(messageRecord, DataExtractionNotificationInfoMessage.Kind.SCREENSHOT);
|
||||||
|
else if (messageRecord.isMediaSavedExtraction()) setDataExtractionRecord(messageRecord, DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED);
|
||||||
else if (messageRecord.isEndSession()) setEndSessionRecord(messageRecord);
|
else if (messageRecord.isEndSession()) setEndSessionRecord(messageRecord);
|
||||||
else if (messageRecord.isIdentityUpdate()) setIdentityRecord(messageRecord);
|
else if (messageRecord.isIdentityUpdate()) setIdentityRecord(messageRecord);
|
||||||
else if (messageRecord.isIdentityVerified() ||
|
else if (messageRecord.isIdentityVerified() ||
|
||||||
@ -147,6 +150,22 @@ public class ConversationUpdateItem extends LinearLayout
|
|||||||
date.setVisibility(GONE);
|
date.setVisibility(GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setDataExtractionRecord(final MessageRecord messageRecord, DataExtractionNotificationInfoMessage.Kind kind) {
|
||||||
|
@ColorInt int color = GeneralUtilitiesKt.getColorWithID(getResources(), R.color.text, getContext().getTheme());
|
||||||
|
if (kind == DataExtractionNotificationInfoMessage.Kind.SCREENSHOT) {
|
||||||
|
icon.setImageResource(R.drawable.quick_camera_dark);
|
||||||
|
} else if (kind == DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED) {
|
||||||
|
icon.setImageResource(R.drawable.ic_file_download_white_36dp);
|
||||||
|
}
|
||||||
|
icon.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
|
||||||
|
|
||||||
|
body.setText(messageRecord.getDisplayBody(getContext()));
|
||||||
|
|
||||||
|
title.setVisibility(VISIBLE);
|
||||||
|
body.setVisibility(VISIBLE);
|
||||||
|
date.setVisibility(GONE);
|
||||||
|
}
|
||||||
|
|
||||||
private void setIdentityRecord(final MessageRecord messageRecord) {
|
private void setIdentityRecord(final MessageRecord messageRecord) {
|
||||||
icon.setImageResource(R.drawable.ic_security_white_24dp);
|
icon.setImageResource(R.drawable.ic_security_white_24dp);
|
||||||
icon.setColorFilter(new PorterDuffColorFilter(Color.parseColor("#757575"), PorterDuff.Mode.MULTIPLY));
|
icon.setColorFilter(new PorterDuffColorFilter(Color.parseColor("#757575"), PorterDuff.Mode.MULTIPLY));
|
||||||
|
@ -719,6 +719,14 @@ public class MmsDatabase extends MessagingDatabase {
|
|||||||
type |= Types.EXPIRATION_TIMER_UPDATE_BIT;
|
type |= Types.EXPIRATION_TIMER_UPDATE_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (retrieved.isScreenshotDataExtraction()) {
|
||||||
|
type |= Types.SCREENSHOT_EXTRACTION_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retrieved.isMediaSavedDataExtraction()) {
|
||||||
|
type |= Types.MEDIA_SAVED_EXTRACTION_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
return insertMessageInbox(retrieved, "", threadId, type, serverTimestamp);
|
return insertMessageInbox(retrieved, "", threadId, type, serverTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,10 @@ public interface MmsSmsColumns {
|
|||||||
protected static final long EXPIRATION_TIMER_UPDATE_BIT = 0x40000;
|
protected static final long EXPIRATION_TIMER_UPDATE_BIT = 0x40000;
|
||||||
protected static final long GROUP_UPDATE_MESSAGE_BIT = 0x80000;
|
protected static final long GROUP_UPDATE_MESSAGE_BIT = 0x80000;
|
||||||
|
|
||||||
|
// Data Extraction Information
|
||||||
|
protected static final long MEDIA_SAVED_EXTRACTION_BIT = 0x01000;
|
||||||
|
protected static final long SCREENSHOT_EXTRACTION_BIT = 0x02000;
|
||||||
|
|
||||||
// Encrypted Storage Information XXX
|
// Encrypted Storage Information XXX
|
||||||
public static final long ENCRYPTION_MASK = 0xFF000000;
|
public static final long ENCRYPTION_MASK = 0xFF000000;
|
||||||
// public static final long ENCRYPTION_SYMMETRIC_BIT = 0x80000000; Deprecated
|
// public static final long ENCRYPTION_SYMMETRIC_BIT = 0x80000000; Deprecated
|
||||||
@ -198,6 +202,14 @@ public interface MmsSmsColumns {
|
|||||||
return (type & EXPIRATION_TIMER_UPDATE_BIT) != 0;
|
return (type & EXPIRATION_TIMER_UPDATE_BIT) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isMediaSavedExtraction(long type) {
|
||||||
|
return (type & MEDIA_SAVED_EXTRACTION_BIT) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isScreenshotExtraction(long type) {
|
||||||
|
return (type & SCREENSHOT_EXTRACTION_BIT) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isIncomingCall(long type) {
|
public static boolean isIncomingCall(long type) {
|
||||||
return type == INCOMING_CALL_TYPE;
|
return type == INCOMING_CALL_TYPE;
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,11 @@ import org.session.libsession.messaging.messages.visible.VisibleMessage
|
|||||||
import org.session.libsession.messaging.opengroups.OpenGroup
|
import org.session.libsession.messaging.opengroups.OpenGroup
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
|
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
||||||
|
import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage
|
||||||
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
|
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
|
||||||
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
||||||
import org.session.libsession.messaging.threads.Address
|
import org.session.libsession.messaging.threads.Address
|
||||||
|
import org.session.libsession.messaging.threads.Address.Companion.fromSerialized
|
||||||
import org.session.libsession.messaging.threads.GroupRecord
|
import org.session.libsession.messaging.threads.GroupRecord
|
||||||
import org.session.libsession.messaging.threads.recipients.Recipient
|
import org.session.libsession.messaging.threads.recipients.Recipient
|
||||||
import org.session.libsession.messaging.utilities.UpdateMessageBuilder
|
import org.session.libsession.messaging.utilities.UpdateMessageBuilder
|
||||||
@ -146,7 +148,6 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
|||||||
val linkPreviews: Optional<List<LinkPreview>> = if (linkPreview.isEmpty()) Optional.absent() else Optional.of(linkPreview.mapNotNull { it!! })
|
val linkPreviews: Optional<List<LinkPreview>> = if (linkPreview.isEmpty()) Optional.absent() else Optional.of(linkPreview.mapNotNull { it!! })
|
||||||
val mmsDatabase = DatabaseFactory.getMmsDatabase(context)
|
val mmsDatabase = DatabaseFactory.getMmsDatabase(context)
|
||||||
val insertResult = if (message.sender == getUserPublicKey()) {
|
val insertResult = if (message.sender == getUserPublicKey()) {
|
||||||
|
|
||||||
val mediaMessage = OutgoingMediaMessage.from(message, targetRecipient, pointerAttachments, quote.orNull(), linkPreviews.orNull()?.firstOrNull())
|
val mediaMessage = OutgoingMediaMessage.from(message, targetRecipient, pointerAttachments, quote.orNull(), linkPreviews.orNull()?.firstOrNull())
|
||||||
mmsDatabase.beginTransaction()
|
mmsDatabase.beginTransaction()
|
||||||
mmsDatabase.insertSecureDecryptedMessageOutbox(mediaMessage, message.threadID ?: -1, message.sentTimestamp!!)
|
mmsDatabase.insertSecureDecryptedMessageOutbox(mediaMessage, message.threadID ?: -1, message.sentTimestamp!!)
|
||||||
@ -419,7 +420,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
|||||||
val infoMessage = OutgoingGroupMediaMessage(recipient, updateData, groupID, null, sentTimestamp, 0, true, null, listOf(), listOf())
|
val infoMessage = OutgoingGroupMediaMessage(recipient, updateData, groupID, null, sentTimestamp, 0, true, null, listOf(), listOf())
|
||||||
val mmsDB = DatabaseFactory.getMmsDatabase(context)
|
val mmsDB = DatabaseFactory.getMmsDatabase(context)
|
||||||
val mmsSmsDB = DatabaseFactory.getMmsSmsDatabase(context)
|
val mmsSmsDB = DatabaseFactory.getMmsSmsDatabase(context)
|
||||||
if (mmsSmsDB.getMessageFor(sentTimestamp,userPublicKey) != null) return
|
if (mmsSmsDB.getMessageFor(sentTimestamp, userPublicKey) != null) return
|
||||||
val infoMessageID = mmsDB.insertMessageOutbox(infoMessage, threadID, false, null)
|
val infoMessageID = mmsDB.insertMessageOutbox(infoMessage, threadID, false, null)
|
||||||
mmsDB.markAsSent(infoMessageID, true)
|
mmsDB.markAsSent(infoMessageID, true)
|
||||||
}
|
}
|
||||||
@ -577,4 +578,26 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
|||||||
override fun getAttachmentThumbnailUri(attachmentId: AttachmentId): Uri {
|
override fun getAttachmentThumbnailUri(attachmentId: AttachmentId): Uri {
|
||||||
return PartAuthority.getAttachmentThumbnailUri(attachmentId)
|
return PartAuthority.getAttachmentThumbnailUri(attachmentId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data Extraction Notification
|
||||||
|
override fun insertDataExtractionNotificationMessage(senderPublicKey: String, message: DataExtractionNotificationInfoMessage, sentTimestamp: Long) {
|
||||||
|
val database = DatabaseFactory.getMmsDatabase(context)
|
||||||
|
val address = fromSerialized(senderPublicKey)
|
||||||
|
val recipient = Recipient.from(context, address, false)
|
||||||
|
|
||||||
|
if (recipient.isBlocked) return
|
||||||
|
|
||||||
|
val mediaMessage = IncomingMediaMessage(address, sentTimestamp, -1,
|
||||||
|
0, false,
|
||||||
|
false,
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.absent(),
|
||||||
|
Optional.of(message))
|
||||||
|
|
||||||
|
database.insertSecureDecryptedMessageInbox(mediaMessage, -1)
|
||||||
|
}
|
||||||
}
|
}
|
@ -131,6 +131,20 @@ public abstract class DisplayRecord {
|
|||||||
return SmsDatabase.Types.isExpirationTimerUpdate(type);
|
return SmsDatabase.Types.isExpirationTimerUpdate(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data extraction
|
||||||
|
|
||||||
|
public boolean isMediaSavedExtraction() {
|
||||||
|
return MmsSmsColumns.Types.isMediaSavedExtraction(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isScreenshotExtraction() {
|
||||||
|
return MmsSmsColumns.Types.isScreenshotExtraction(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDataExtraction() {
|
||||||
|
return isMediaSavedExtraction() || isScreenshotExtraction();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isCallLog() {
|
public boolean isCallLog() {
|
||||||
return SmsDatabase.Types.isCallLog(type);
|
return SmsDatabase.Types.isCallLog(type);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import android.text.style.StyleSpan;
|
|||||||
|
|
||||||
import network.loki.messenger.R;
|
import network.loki.messenger.R;
|
||||||
|
|
||||||
|
import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage;
|
||||||
import org.session.libsession.messaging.utilities.UpdateMessageBuilder;
|
import org.session.libsession.messaging.utilities.UpdateMessageBuilder;
|
||||||
import org.session.libsession.messaging.utilities.UpdateMessageData;
|
import org.session.libsession.messaging.utilities.UpdateMessageData;
|
||||||
import org.thoughtcrime.securesms.database.MmsSmsColumns;
|
import org.thoughtcrime.securesms.database.MmsSmsColumns;
|
||||||
@ -97,6 +98,9 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||||||
} else if (isExpirationTimerUpdate()) {
|
} else if (isExpirationTimerUpdate()) {
|
||||||
int seconds = (int) (getExpiresIn() / 1000);
|
int seconds = (int) (getExpiresIn() / 1000);
|
||||||
return new SpannableString(UpdateMessageBuilder.INSTANCE.buildExpirationTimerMessage(context, seconds, getIndividualRecipient().getAddress().serialize(), isOutgoing()));
|
return new SpannableString(UpdateMessageBuilder.INSTANCE.buildExpirationTimerMessage(context, seconds, getIndividualRecipient().getAddress().serialize(), isOutgoing()));
|
||||||
|
} else if (isDataExtraction()) {
|
||||||
|
if (isScreenshotExtraction()) return new SpannableString((UpdateMessageBuilder.INSTANCE.buildDataExtractionMessage(context, DataExtractionNotificationInfoMessage.Kind.SCREENSHOT, getIndividualRecipient().getAddress().serialize())));
|
||||||
|
else if (isMediaSavedExtraction()) return new SpannableString((UpdateMessageBuilder.INSTANCE.buildDataExtractionMessage(context, DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED, getIndividualRecipient().getAddress().serialize())));
|
||||||
}
|
}
|
||||||
// TODO below lines are left here for compatibility with older group update messages, it can be deleted later on
|
// TODO below lines are left here for compatibility with older group update messages, it can be deleted later on
|
||||||
else if (isGroupUpdate() && isOutgoing()) {
|
else if (isGroupUpdate() && isOutgoing()) {
|
||||||
@ -159,7 +163,7 @@ public abstract class MessageRecord extends DisplayRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUpdate() {
|
public boolean isUpdate() {
|
||||||
return isGroupAction() || isJoined() || isExpirationTimerUpdate() || isCallLog() ||
|
return isGroupAction() || isJoined() || isExpirationTimerUpdate() || isCallLog() || isDataExtraction() ||
|
||||||
isEndSession() || isIdentityUpdate() || isIdentityVerified() || isIdentityDefault() || isLokiSessionRestoreSent() || isLokiSessionRestoreDone();
|
isEndSession() || isIdentityUpdate() || isIdentityVerified() || isIdentityDefault() || isLokiSessionRestoreSent() || isLokiSessionRestoreDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,12 +105,16 @@ public class ThreadRecord extends DisplayRecord {
|
|||||||
} else if (SmsDatabase.Types.isJoinedType(type)) {
|
} else if (SmsDatabase.Types.isJoinedType(type)) {
|
||||||
return emphasisAdded(context.getString(R.string.ThreadRecord_s_is_on_signal, getRecipient().toShortString()));
|
return emphasisAdded(context.getString(R.string.ThreadRecord_s_is_on_signal, getRecipient().toShortString()));
|
||||||
} else if (SmsDatabase.Types.isExpirationTimerUpdate(type)) {
|
} else if (SmsDatabase.Types.isExpirationTimerUpdate(type)) {
|
||||||
int seconds = (int)(getExpiresIn() / 1000);
|
int seconds = (int) (getExpiresIn() / 1000);
|
||||||
if (seconds <= 0) {
|
if (seconds <= 0) {
|
||||||
return emphasisAdded(context.getString(R.string.ThreadRecord_disappearing_messages_disabled));
|
return emphasisAdded(context.getString(R.string.ThreadRecord_disappearing_messages_disabled));
|
||||||
}
|
}
|
||||||
String time = ExpirationUtil.getExpirationDisplayValue(context, seconds);
|
String time = ExpirationUtil.getExpirationDisplayValue(context, seconds);
|
||||||
return emphasisAdded(context.getString(R.string.ThreadRecord_disappearing_message_time_updated_to_s, time));
|
return emphasisAdded(context.getString(R.string.ThreadRecord_disappearing_message_time_updated_to_s, time));
|
||||||
|
} else if (MmsSmsColumns.Types.isMediaSavedExtraction(type)) {
|
||||||
|
return emphasisAdded(context.getString(R.string.ThreadRecord_media_saved_by_s, getRecipient().toShortString()));
|
||||||
|
} else if (MmsSmsColumns.Types.isScreenshotExtraction(type)) {
|
||||||
|
return emphasisAdded(context.getString(R.string.ThreadRecord_s_took_a_screenshot, getRecipient().toShortString()));
|
||||||
} else if (SmsDatabase.Types.isIdentityUpdate(type)) {
|
} else if (SmsDatabase.Types.isIdentityUpdate(type)) {
|
||||||
if (getRecipient().isGroupRecipient()) return emphasisAdded(context.getString(R.string.ThreadRecord_safety_number_changed));
|
if (getRecipient().isGroupRecipient()) return emphasisAdded(context.getString(R.string.ThreadRecord_safety_number_changed));
|
||||||
else return emphasisAdded(context.getString(R.string.ThreadRecord_your_safety_number_with_s_has_changed, getRecipient().toShortString()));
|
else return emphasisAdded(context.getString(R.string.ThreadRecord_your_safety_number_with_s_has_changed, getRecipient().toShortString()));
|
||||||
|
@ -117,6 +117,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
|||||||
Optional.absent(),
|
Optional.absent(),
|
||||||
Optional.absent(),
|
Optional.absent(),
|
||||||
Optional.absent(),
|
Optional.absent(),
|
||||||
|
Optional.absent(),
|
||||||
Optional.absent());
|
Optional.absent());
|
||||||
//insert the timer update message
|
//insert the timer update message
|
||||||
database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
|
database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
package org.thoughtcrime.securesms.sskenvironment
|
|
||||||
|
|
||||||
class DataExtractionNotificationManager {
|
|
||||||
}
|
|
@ -440,6 +440,8 @@
|
|||||||
<string name="MessageRecord_s_disabled_disappearing_messages">%1$s a désactivé les messages éphémères.</string>
|
<string name="MessageRecord_s_disabled_disappearing_messages">%1$s a désactivé les messages éphémères.</string>
|
||||||
<string name="MessageRecord_you_set_disappearing_message_time_to_s">Vous avez défini l’expiration des messages éphémères à %1$s.</string>
|
<string name="MessageRecord_you_set_disappearing_message_time_to_s">Vous avez défini l’expiration des messages éphémères à %1$s.</string>
|
||||||
<string name="MessageRecord_s_set_disappearing_message_time_to_s">%1$s a défini l’expiration des messages éphémères à %2$s.</string>
|
<string name="MessageRecord_s_set_disappearing_message_time_to_s">%1$s a défini l’expiration des messages éphémères à %2$s.</string>
|
||||||
|
<string name="MessageRecord_s_took_a_screenshot">%1$s a pris une capture d’écran.</string>
|
||||||
|
<string name="MessageRecord_media_saved_by_s">%1$s a sauvegardé un media.</string>
|
||||||
<string name="MessageRecord_your_safety_number_with_s_has_changed">Votre numéro de sécurité avec %s a changé.</string>
|
<string name="MessageRecord_your_safety_number_with_s_has_changed">Votre numéro de sécurité avec %s a changé.</string>
|
||||||
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified">Vous avez marqué votre numéro de sécurité avec %s comme vérifié</string>
|
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified">Vous avez marqué votre numéro de sécurité avec %s comme vérifié</string>
|
||||||
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified_from_another_device">Vous avez marqué votre numéro de sécurité avec %s comme vérifié à partir d’un autre appareil</string>
|
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified_from_another_device">Vous avez marqué votre numéro de sécurité avec %s comme vérifié à partir d’un autre appareil</string>
|
||||||
|
@ -515,6 +515,8 @@
|
|||||||
<string name="MessageRecord_s_disabled_disappearing_messages">%1$s disabled disappearing messages.</string>
|
<string name="MessageRecord_s_disabled_disappearing_messages">%1$s disabled disappearing messages.</string>
|
||||||
<string name="MessageRecord_you_set_disappearing_message_time_to_s">You set the disappearing message timer to %1$s</string>
|
<string name="MessageRecord_you_set_disappearing_message_time_to_s">You set the disappearing message timer to %1$s</string>
|
||||||
<string name="MessageRecord_s_set_disappearing_message_time_to_s">%1$s set the disappearing message timer to %2$s</string>
|
<string name="MessageRecord_s_set_disappearing_message_time_to_s">%1$s set the disappearing message timer to %2$s</string>
|
||||||
|
<string name="MessageRecord_s_took_a_screenshot">%1$s took a screenshot.</string>
|
||||||
|
<string name="MessageRecord_media_saved_by_s">Media saved by %1$s.</string>
|
||||||
<string name="MessageRecord_your_safety_number_with_s_has_changed">Your safety number with %s has changed.</string>
|
<string name="MessageRecord_your_safety_number_with_s_has_changed">Your safety number with %s has changed.</string>
|
||||||
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified">You marked your safety number with %s verified</string>
|
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified">You marked your safety number with %s verified</string>
|
||||||
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified_from_another_device">You marked your safety number with %s verified from another device</string>
|
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified_from_another_device">You marked your safety number with %s verified from another device</string>
|
||||||
@ -713,6 +715,8 @@
|
|||||||
<string name="ThreadRecord_s_is_on_signal">%s is on Session!</string>
|
<string name="ThreadRecord_s_is_on_signal">%s is on Session!</string>
|
||||||
<string name="ThreadRecord_disappearing_messages_disabled">Disappearing messages disabled</string>
|
<string name="ThreadRecord_disappearing_messages_disabled">Disappearing messages disabled</string>
|
||||||
<string name="ThreadRecord_disappearing_message_time_updated_to_s">Disappearing message time set to %s</string>
|
<string name="ThreadRecord_disappearing_message_time_updated_to_s">Disappearing message time set to %s</string>
|
||||||
|
<string name="ThreadRecord_s_took_a_screenshot">%s took a screenshot.</string>
|
||||||
|
<string name="ThreadRecord_media_saved_by_s">Media saved by %s.</string>
|
||||||
<string name="ThreadRecord_safety_number_changed">Safety number changed</string>
|
<string name="ThreadRecord_safety_number_changed">Safety number changed</string>
|
||||||
<string name="ThreadRecord_your_safety_number_with_s_has_changed">Your safety number with %s has changed.</string>
|
<string name="ThreadRecord_your_safety_number_with_s_has_changed">Your safety number with %s has changed.</string>
|
||||||
<string name="ThreadRecord_you_marked_verified">You marked verified</string>
|
<string name="ThreadRecord_you_marked_verified">You marked verified</string>
|
||||||
|
@ -11,6 +11,7 @@ import org.session.libsession.messaging.messages.visible.Attachment
|
|||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||||
import org.session.libsession.messaging.opengroups.OpenGroup
|
import org.session.libsession.messaging.opengroups.OpenGroup
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
|
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId
|
||||||
|
import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
||||||
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
|
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
|
||||||
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
||||||
@ -159,4 +160,7 @@ interface StorageProtocol {
|
|||||||
// Message Handling
|
// Message Handling
|
||||||
/// Returns the ID of the `TSIncomingMessage` that was constructed.
|
/// Returns the ID of the `TSIncomingMessage` that was constructed.
|
||||||
fun persist(message: VisibleMessage, quotes: QuoteModel?, linkPreview: List<LinkPreview?>, groupPublicKey: String?, openGroupID: String?, attachments: List<Attachment>): Long?
|
fun persist(message: VisibleMessage, quotes: QuoteModel?, linkPreview: List<LinkPreview?>, groupPublicKey: String?, openGroupID: String?, attachments: List<Attachment>): Long?
|
||||||
|
|
||||||
|
// Data Extraction Notification
|
||||||
|
fun insertDataExtractionNotificationMessage(senderPublicKey: String, message: DataExtractionNotificationInfoMessage, sentTimestamp: Long)
|
||||||
}
|
}
|
@ -9,7 +9,7 @@ class DataExtractionNotification(): ControlMessage() {
|
|||||||
// Kind enum
|
// Kind enum
|
||||||
sealed class Kind {
|
sealed class Kind {
|
||||||
class Screenshot() : Kind()
|
class Screenshot() : Kind()
|
||||||
class MediaSaved(val timestanp: Long) : Kind()
|
class MediaSaved(val timestamp: Long) : Kind()
|
||||||
|
|
||||||
val description: String =
|
val description: String =
|
||||||
when(this) {
|
when(this) {
|
||||||
@ -46,7 +46,7 @@ class DataExtractionNotification(): ControlMessage() {
|
|||||||
val kind = kind ?: return false
|
val kind = kind ?: return false
|
||||||
return when(kind) {
|
return when(kind) {
|
||||||
is Kind.Screenshot -> true
|
is Kind.Screenshot -> true
|
||||||
is Kind.MediaSaved -> kind.timestanp > 0
|
is Kind.MediaSaved -> kind.timestamp > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ class DataExtractionNotification(): ControlMessage() {
|
|||||||
is Kind.Screenshot -> dataExtractionNotification.type = SignalServiceProtos.DataExtractionNotification.Type.SCREENSHOT
|
is Kind.Screenshot -> dataExtractionNotification.type = SignalServiceProtos.DataExtractionNotification.Type.SCREENSHOT
|
||||||
is Kind.MediaSaved -> {
|
is Kind.MediaSaved -> {
|
||||||
dataExtractionNotification.type = SignalServiceProtos.DataExtractionNotification.Type.MEDIA_SAVED
|
dataExtractionNotification.type = SignalServiceProtos.DataExtractionNotification.Type.MEDIA_SAVED
|
||||||
dataExtractionNotification.timestamp = kind.timestanp
|
dataExtractionNotification.timestamp = kind.timestamp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val contentProto = SignalServiceProtos.Content.newBuilder()
|
val contentProto = SignalServiceProtos.Content.newBuilder()
|
||||||
@ -73,5 +73,4 @@ class DataExtractionNotification(): ControlMessage() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -3,10 +3,11 @@ package org.session.libsession.messaging.messages.signal;
|
|||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage;
|
import org.session.libsession.messaging.messages.visible.VisibleMessage;
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
|
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment;
|
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment;
|
||||||
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview;
|
import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage;
|
||||||
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel;
|
|
||||||
import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact;
|
import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact;
|
||||||
import org.session.libsession.messaging.threads.Address;
|
import org.session.libsession.messaging.threads.Address;
|
||||||
|
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview;
|
||||||
|
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel;
|
||||||
import org.session.libsession.utilities.GroupUtil;
|
import org.session.libsession.utilities.GroupUtil;
|
||||||
import org.session.libsignal.libsignal.util.guava.Optional;
|
import org.session.libsignal.libsignal.util.guava.Optional;
|
||||||
import org.session.libsignal.service.api.messages.SignalServiceAttachment;
|
import org.session.libsignal.service.api.messages.SignalServiceAttachment;
|
||||||
@ -26,9 +27,11 @@ public class IncomingMediaMessage {
|
|||||||
private final int subscriptionId;
|
private final int subscriptionId;
|
||||||
private final long expiresIn;
|
private final long expiresIn;
|
||||||
private final boolean expirationUpdate;
|
private final boolean expirationUpdate;
|
||||||
private final QuoteModel quote;
|
|
||||||
private final boolean unidentified;
|
private final boolean unidentified;
|
||||||
|
|
||||||
|
private final DataExtractionNotificationInfoMessage dataExtractionNotification;
|
||||||
|
private final QuoteModel quote;
|
||||||
|
|
||||||
private final List<Attachment> attachments = new LinkedList<>();
|
private final List<Attachment> attachments = new LinkedList<>();
|
||||||
private final List<Contact> sharedContacts = new LinkedList<>();
|
private final List<Contact> sharedContacts = new LinkedList<>();
|
||||||
private final List<LinkPreview> linkPreviews = new LinkedList<>();
|
private final List<LinkPreview> linkPreviews = new LinkedList<>();
|
||||||
@ -44,7 +47,8 @@ public class IncomingMediaMessage {
|
|||||||
Optional<List<SignalServiceAttachment>> attachments,
|
Optional<List<SignalServiceAttachment>> attachments,
|
||||||
Optional<QuoteModel> quote,
|
Optional<QuoteModel> quote,
|
||||||
Optional<List<Contact>> sharedContacts,
|
Optional<List<Contact>> sharedContacts,
|
||||||
Optional<List<LinkPreview>> linkPreviews)
|
Optional<List<LinkPreview>> linkPreviews,
|
||||||
|
Optional<DataExtractionNotificationInfoMessage> dataExtractionNotification)
|
||||||
{
|
{
|
||||||
this.push = true;
|
this.push = true;
|
||||||
this.from = from;
|
this.from = from;
|
||||||
@ -53,6 +57,7 @@ public class IncomingMediaMessage {
|
|||||||
this.subscriptionId = subscriptionId;
|
this.subscriptionId = subscriptionId;
|
||||||
this.expiresIn = expiresIn;
|
this.expiresIn = expiresIn;
|
||||||
this.expirationUpdate = expirationUpdate;
|
this.expirationUpdate = expirationUpdate;
|
||||||
|
this.dataExtractionNotification = dataExtractionNotification.orNull();
|
||||||
this.quote = quote.orNull();
|
this.quote = quote.orNull();
|
||||||
this.unidentified = unidentified;
|
this.unidentified = unidentified;
|
||||||
|
|
||||||
@ -73,7 +78,7 @@ public class IncomingMediaMessage {
|
|||||||
Optional<List<LinkPreview>> linkPreviews)
|
Optional<List<LinkPreview>> linkPreviews)
|
||||||
{
|
{
|
||||||
return new IncomingMediaMessage(from, message.getSentTimestamp(), -1, expiresIn, false,
|
return new IncomingMediaMessage(from, message.getSentTimestamp(), -1, expiresIn, false,
|
||||||
false, Optional.fromNullable(message.getText()), group, Optional.fromNullable(attachments), quote, Optional.absent(), linkPreviews);
|
false, Optional.fromNullable(message.getText()), group, Optional.fromNullable(attachments), quote, Optional.absent(), linkPreviews, Optional.absent());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSubscriptionId() {
|
public int getSubscriptionId() {
|
||||||
@ -116,6 +121,20 @@ public class IncomingMediaMessage {
|
|||||||
return groupId != null;
|
return groupId != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isScreenshotDataExtraction() {
|
||||||
|
if (dataExtractionNotification == null) return false;
|
||||||
|
else {
|
||||||
|
return dataExtractionNotification.getKind() == DataExtractionNotificationInfoMessage.Kind.SCREENSHOT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMediaSavedDataExtraction() {
|
||||||
|
if (dataExtractionNotification == null) return false;
|
||||||
|
else {
|
||||||
|
return dataExtractionNotification.getKind() == DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public QuoteModel getQuote() {
|
public QuoteModel getQuote() {
|
||||||
return quote;
|
return quote;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import org.session.libsession.messaging.messages.control.*
|
|||||||
import org.session.libsession.messaging.messages.visible.Attachment
|
import org.session.libsession.messaging.messages.visible.Attachment
|
||||||
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||||
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment
|
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment
|
||||||
|
import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage
|
||||||
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
|
import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview
|
||||||
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI
|
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI
|
||||||
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
|
||||||
@ -45,6 +46,7 @@ fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content,
|
|||||||
is TypingIndicator -> handleTypingIndicator(message)
|
is TypingIndicator -> handleTypingIndicator(message)
|
||||||
is ClosedGroupControlMessage -> handleClosedGroupControlMessage(message)
|
is ClosedGroupControlMessage -> handleClosedGroupControlMessage(message)
|
||||||
is ExpirationTimerUpdate -> handleExpirationTimerUpdate(message)
|
is ExpirationTimerUpdate -> handleExpirationTimerUpdate(message)
|
||||||
|
is DataExtractionNotification -> handleDataExtractionNotification(message)
|
||||||
is ConfigurationMessage -> handleConfigurationMessage(message)
|
is ConfigurationMessage -> handleConfigurationMessage(message)
|
||||||
is VisibleMessage -> handleVisibleMessage(message, proto, openGroupID)
|
is VisibleMessage -> handleVisibleMessage(message, proto, openGroupID)
|
||||||
}
|
}
|
||||||
@ -91,6 +93,24 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data Extraction Notification handling
|
||||||
|
|
||||||
|
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) {
|
||||||
|
// we don't handle data extraction messages for groups (they shouldn't be sent, but in case we filter them here too)
|
||||||
|
if (message.groupPublicKey != null) return
|
||||||
|
|
||||||
|
val storage = MessagingConfiguration.shared.storage
|
||||||
|
val senderPublicKey = message.sender!!
|
||||||
|
val notification: DataExtractionNotificationInfoMessage = when(message.kind) {
|
||||||
|
is DataExtractionNotification.Kind.Screenshot -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.SCREENSHOT)
|
||||||
|
is DataExtractionNotification.Kind.MediaSaved -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED)
|
||||||
|
else -> return
|
||||||
|
}
|
||||||
|
storage.insertDataExtractionNotificationMessage(senderPublicKey, notification, message.sentTimestamp!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configuration message handling
|
||||||
|
|
||||||
private fun MessageReceiver.handleConfigurationMessage(message: ConfigurationMessage) {
|
private fun MessageReceiver.handleConfigurationMessage(message: ConfigurationMessage) {
|
||||||
val context = MessagingConfiguration.shared.context
|
val context = MessagingConfiguration.shared.context
|
||||||
val storage = MessagingConfiguration.shared.storage
|
val storage = MessagingConfiguration.shared.storage
|
||||||
@ -153,7 +173,8 @@ fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Get or create thread
|
// Get or create thread
|
||||||
val threadID = storage.getOrCreateThreadIdFor(message.syncTarget ?: message.sender!!, message.groupPublicKey, openGroupID)
|
val threadID = storage.getOrCreateThreadIdFor(message.syncTarget
|
||||||
|
?: message.sender!!, message.groupPublicKey, openGroupID)
|
||||||
// Parse quote if needed
|
// Parse quote if needed
|
||||||
var quoteModel: QuoteModel? = null
|
var quoteModel: QuoteModel? = null
|
||||||
if (message.quote != null && proto.dataMessage.hasQuote()) {
|
if (message.quote != null && proto.dataMessage.hasQuote()) {
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.session.libsession.messaging.sending_receiving.dataextraction
|
||||||
|
|
||||||
|
class DataExtractionNotificationInfoMessage {
|
||||||
|
|
||||||
|
enum class Kind {
|
||||||
|
SCREENSHOT,
|
||||||
|
MEDIA_SAVED
|
||||||
|
}
|
||||||
|
|
||||||
|
var kind: Kind? = null
|
||||||
|
|
||||||
|
constructor(kind: Kind?) {
|
||||||
|
this.kind = kind
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,6 +3,7 @@ package org.session.libsession.messaging.utilities
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import org.session.libsession.R
|
import org.session.libsession.R
|
||||||
import org.session.libsession.messaging.MessagingConfiguration
|
import org.session.libsession.messaging.MessagingConfiguration
|
||||||
|
import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage
|
||||||
import org.session.libsession.utilities.ExpirationUtil
|
import org.session.libsession.utilities.ExpirationUtil
|
||||||
import org.session.libsignal.service.api.messages.SignalServiceGroup
|
import org.session.libsignal.service.api.messages.SignalServiceGroup
|
||||||
|
|
||||||
@ -78,7 +79,7 @@ object UpdateMessageBuilder {
|
|||||||
if (!isOutgoing && sender == null) return ""
|
if (!isOutgoing && sender == null) return ""
|
||||||
val senderName: String? = if (!isOutgoing) {
|
val senderName: String? = if (!isOutgoing) {
|
||||||
MessagingConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender
|
MessagingConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender
|
||||||
} else { sender }
|
} else { context.getString(R.string.MessageRecord_you) }
|
||||||
return if (duration <= 0) {
|
return if (duration <= 0) {
|
||||||
if (isOutgoing) context.getString(R.string.MessageRecord_you_disabled_disappearing_messages)
|
if (isOutgoing) context.getString(R.string.MessageRecord_you_disabled_disappearing_messages)
|
||||||
else context.getString(R.string.MessageRecord_s_disabled_disappearing_messages, senderName)
|
else context.getString(R.string.MessageRecord_s_disabled_disappearing_messages, senderName)
|
||||||
@ -89,8 +90,13 @@ object UpdateMessageBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO do this when the current update is merged
|
fun buildDataExtractionMessage(context: Context, kind: DataExtractionNotificationInfoMessage.Kind, sender: String? = null): String {
|
||||||
fun buildDataExtractionMessage(): String {
|
val senderName = MessagingConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender
|
||||||
return ""
|
return when (kind) {
|
||||||
|
DataExtractionNotificationInfoMessage.Kind.SCREENSHOT ->
|
||||||
|
context.getString(R.string.MessageRecord_s_took_a_screenshot, senderName)
|
||||||
|
DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED ->
|
||||||
|
context.getString(R.string.MessageRecord_media_saved_by_s, senderName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -509,6 +509,8 @@
|
|||||||
<string name="MessageRecord_s_disabled_disappearing_messages">%1$s disabled disappearing messages.</string>
|
<string name="MessageRecord_s_disabled_disappearing_messages">%1$s disabled disappearing messages.</string>
|
||||||
<string name="MessageRecord_you_set_disappearing_message_time_to_s">You set the disappearing message timer to %1$s</string>
|
<string name="MessageRecord_you_set_disappearing_message_time_to_s">You set the disappearing message timer to %1$s</string>
|
||||||
<string name="MessageRecord_s_set_disappearing_message_time_to_s">%1$s set the disappearing message timer to %2$s</string>
|
<string name="MessageRecord_s_set_disappearing_message_time_to_s">%1$s set the disappearing message timer to %2$s</string>
|
||||||
|
<string name="MessageRecord_s_took_a_screenshot">%1$s took a screenshot.</string>
|
||||||
|
<string name="MessageRecord_media_saved_by_s">Media saved by %1$s.</string>
|
||||||
<string name="MessageRecord_your_safety_number_with_s_has_changed">Your safety number with %s has changed.</string>
|
<string name="MessageRecord_your_safety_number_with_s_has_changed">Your safety number with %s has changed.</string>
|
||||||
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified">You marked your safety number with %s verified</string>
|
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified">You marked your safety number with %s verified</string>
|
||||||
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified_from_another_device">You marked your safety number with %s verified from another device</string>
|
<string name="MessageRecord_you_marked_your_safety_number_with_s_verified_from_another_device">You marked your safety number with %s verified from another device</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user