mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 01:07:47 +00:00
Merge branch 'dev' of https://github.com/loki-project/session-android into light-theme
# Conflicts: # res/values/strings.xml
This commit is contained in:
commit
de93b6669e
8
res/menu/conversation_copy_session_id.xml
Normal file
8
res/menu/conversation_copy_session_id.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:title="@string/activity_conversation_menu_copy_session_id"
|
||||||
|
android:id="@+id/menu_copy_session_id"
|
||||||
|
android:icon="@drawable/ic_content_copy_white_24dp" />
|
||||||
|
|
||||||
|
</menu>
|
@ -1860,4 +1860,6 @@
|
|||||||
<string name="dialog_ui_mode_option_night">Night</string>
|
<string name="dialog_ui_mode_option_night">Night</string>
|
||||||
<string name="dialog_ui_mode_option_system_default">System default</string>
|
<string name="dialog_ui_mode_option_system_default">System default</string>
|
||||||
|
|
||||||
|
<string name="activity_conversation_menu_copy_session_id">Copy Session ID</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -21,6 +21,8 @@ import android.annotation.SuppressLint;
|
|||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
@ -747,6 +749,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
} else {
|
} else {
|
||||||
inflater.inflate(R.menu.conversation_block, menu);
|
inflater.inflate(R.menu.conversation_block, menu);
|
||||||
}
|
}
|
||||||
|
inflater.inflate(R.menu.conversation_copy_session_id, menu);
|
||||||
} else if (isGroupConversation() && !isOpenGroupOrRSSFeed) {
|
} else if (isGroupConversation() && !isOpenGroupOrRSSFeed) {
|
||||||
// inflater.inflate(R.menu.conversation_group_options, menu);
|
// inflater.inflate(R.menu.conversation_group_options, menu);
|
||||||
|
|
||||||
@ -854,6 +857,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
// case R.id.menu_call_insecure: handleDial(getRecipient(), false); return true;
|
// case R.id.menu_call_insecure: handleDial(getRecipient(), false); return true;
|
||||||
case R.id.menu_unblock: handleUnblock(); return true;
|
case R.id.menu_unblock: handleUnblock(); return true;
|
||||||
case R.id.menu_block: handleBlock(); return true;
|
case R.id.menu_block: handleBlock(); return true;
|
||||||
|
case R.id.menu_copy_session_id: handleCopySessionID(); return true;
|
||||||
case R.id.menu_view_media: handleViewMedia(); return true;
|
case R.id.menu_view_media: handleViewMedia(); return true;
|
||||||
case R.id.menu_add_shortcut: handleAddShortcut(); return true;
|
case R.id.menu_add_shortcut: handleAddShortcut(); return true;
|
||||||
case R.id.menu_search: handleSearch(); return true;
|
case R.id.menu_search: handleSearch(); return true;
|
||||||
@ -1083,6 +1087,15 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}).show();
|
}).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleCopySessionID() {
|
||||||
|
if (recipient.isGroupRecipient()) { return; }
|
||||||
|
String sessionID = recipient.getAddress().toPhoneString();
|
||||||
|
ClipboardManager clipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData clip = ClipData.newPlainText("Session ID", sessionID);
|
||||||
|
clipboard.setPrimaryClip(clip);
|
||||||
|
Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
private void handleViewMedia() {
|
private void handleViewMedia() {
|
||||||
Intent intent = new Intent(this, MediaOverviewActivity.class);
|
Intent intent = new Intent(this, MediaOverviewActivity.class);
|
||||||
intent.putExtra(MediaOverviewActivity.ADDRESS_EXTRA, recipient.getAddress());
|
intent.putExtra(MediaOverviewActivity.ADDRESS_EXTRA, recipient.getAddress());
|
||||||
|
@ -834,6 +834,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
public long handleSynchronizeSentMediaMessage(@NonNull SentTranscriptMessage message)
|
public long handleSynchronizeSentMediaMessage(@NonNull SentTranscriptMessage message)
|
||||||
throws MmsException
|
throws MmsException
|
||||||
{
|
{
|
||||||
|
if (SessionMetaProtocol.shouldIgnoreMessage(message.getTimestamp())) { return -1; }
|
||||||
|
|
||||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||||
Recipient recipients = getSyncMessageMasterDestination(message);
|
Recipient recipients = getSyncMessageMasterDestination(message);
|
||||||
Optional<QuoteModel> quote = getValidatedQuote(message.getMessage().getQuote());
|
Optional<QuoteModel> quote = getValidatedQuote(message.getMessage().getQuote());
|
||||||
@ -1002,6 +1004,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
public long handleSynchronizeSentTextMessage(@NonNull SentTranscriptMessage message)
|
public long handleSynchronizeSentTextMessage(@NonNull SentTranscriptMessage message)
|
||||||
throws MmsException
|
throws MmsException
|
||||||
{
|
{
|
||||||
|
if (SessionMetaProtocol.shouldIgnoreMessage(message.getTimestamp())) { return -1; }
|
||||||
|
|
||||||
Recipient recipient = getSyncMessageMasterDestination(message);
|
Recipient recipient = getSyncMessageMasterDestination(message);
|
||||||
String body = message.getMessage().getBody().or("");
|
String body = message.getMessage().getBody().or("");
|
||||||
@ -1459,7 +1462,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SessionMetaProtocol.shouldIgnoreMessage(content)) {
|
if (SessionMetaProtocol.shouldIgnoreMessage(content.getTimestamp())) {
|
||||||
Log.d("Loki", "Ignoring duplicate message.");
|
Log.d("Loki", "Ignoring duplicate message.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import android.os.Handler
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import nl.komponents.kovenant.Promise
|
import nl.komponents.kovenant.Promise
|
||||||
import nl.komponents.kovenant.functional.bind
|
import nl.komponents.kovenant.functional.bind
|
||||||
import nl.komponents.kovenant.then
|
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
import org.thoughtcrime.securesms.database.Address
|
import org.thoughtcrime.securesms.database.Address
|
||||||
@ -34,6 +33,7 @@ import java.util.*
|
|||||||
class PublicChatPoller(private val context: Context, private val group: PublicChat) {
|
class PublicChatPoller(private val context: Context, private val group: PublicChat) {
|
||||||
private val handler = Handler()
|
private val handler = Handler()
|
||||||
private var hasStarted = false
|
private var hasStarted = false
|
||||||
|
private var isPollOngoing = false
|
||||||
public var isCaughtUp = false
|
public var isCaughtUp = false
|
||||||
|
|
||||||
// region Convenience
|
// region Convenience
|
||||||
@ -186,12 +186,10 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh
|
|||||||
}
|
}
|
||||||
fun processOutgoingMessage(message: PublicChatMessage) {
|
fun processOutgoingMessage(message: PublicChatMessage) {
|
||||||
val messageServerID = message.serverID ?: return
|
val messageServerID = message.serverID ?: return
|
||||||
val isDuplicate = DatabaseFactory.getLokiMessageDatabase(context).getMessageID(messageServerID) != null
|
|
||||||
if (isDuplicate) { return }
|
|
||||||
if (message.body.isEmpty() && message.attachments.isEmpty() && message.quote == null) { return }
|
if (message.body.isEmpty() && message.attachments.isEmpty() && message.quote == null) { return }
|
||||||
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
|
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
|
||||||
val dataMessage = getDataMessage(message)
|
val dataMessage = getDataMessage(message)
|
||||||
SessionMetaProtocol.dropFromTimestampCacheIfNeeded(dataMessage.timestamp)
|
SessionMetaProtocol.dropFromTimestampCacheIfNeeded(message.serverTimestamp)
|
||||||
val transcript = SentTranscriptMessage(userHexEncodedPublicKey, message.serverTimestamp, dataMessage, dataMessage.expiresInSeconds.toLong(), Collections.singletonMap(userHexEncodedPublicKey, false))
|
val transcript = SentTranscriptMessage(userHexEncodedPublicKey, message.serverTimestamp, dataMessage, dataMessage.expiresInSeconds.toLong(), Collections.singletonMap(userHexEncodedPublicKey, false))
|
||||||
transcript.messageServerID = messageServerID
|
transcript.messageServerID = messageServerID
|
||||||
if (dataMessage.quote.isPresent || (dataMessage.attachments.isPresent && dataMessage.attachments.get().size > 0) || dataMessage.previews.isPresent) {
|
if (dataMessage.quote.isPresent || (dataMessage.attachments.isPresent && dataMessage.attachments.get().size > 0) || dataMessage.previews.isPresent) {
|
||||||
@ -212,6 +210,8 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isPollOngoing) { return }
|
||||||
|
isPollOngoing = true
|
||||||
val userDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userHexEncodedPublicKey)
|
val userDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userHexEncodedPublicKey)
|
||||||
var uniqueDevices = setOf<String>()
|
var uniqueDevices = setOf<String>()
|
||||||
val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize()
|
val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize()
|
||||||
@ -249,8 +249,10 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
isCaughtUp = true
|
isCaughtUp = true
|
||||||
|
isPollOngoing = false
|
||||||
}.fail {
|
}.fail {
|
||||||
Log.d("Loki", "Failed to get messages for group chat with ID: ${group.channel} on server: ${group.server}.")
|
Log.d("Loki", "Failed to get messages for group chat with ID: ${group.channel} on server: ${group.server}.")
|
||||||
|
isPollOngoing = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,8 +23,7 @@ object SessionMetaProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun shouldIgnoreMessage(content: SignalServiceContent): Boolean {
|
fun shouldIgnoreMessage(timestamp: Long): Boolean {
|
||||||
val timestamp = content.timestamp
|
|
||||||
val shouldIgnoreMessage = timestamps.contains(timestamp)
|
val shouldIgnoreMessage = timestamps.contains(timestamp)
|
||||||
timestamps.add(timestamp)
|
timestamps.add(timestamp)
|
||||||
return shouldIgnoreMessage
|
return shouldIgnoreMessage
|
||||||
|
Loading…
x
Reference in New Issue
Block a user