diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 972ec30be1..3d223e42c0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -172,9 +172,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
allContacts = ContactUtilities.getAllContacts(this);
+ SessionContactDatabase contactDB = DatabaseFactory.getSessionContactDatabase(this);
+ LokiUserDatabase userDB = DatabaseFactory.getLokiUserDatabase(this);
+ for (Recipient recipient : allContacts) {
+ if (recipient.isGroupRecipient()) { continue; }
+ String sessionID = recipient.getAddress().serialize();
+ Contact contact = contactDB.getContactWithSessionID(sessionID);
+ if (contact == null) {
+ contact = new Contact(sessionID);
+ String name = userDB.getDisplayName(sessionID);
+ contact.setName(name);
+ contact.setProfilePictureURL(recipient.getProfileAvatar());
+ contact.setProfilePictureEncryptionKey(recipient.getProfileKey());
+ contact.setTrusted(true);
+ }
+ contactDB.setContact(contact);
+ }
+ }
+
if (poller != null) {
poller.setCaughtUp(false);
}
startPollingIfNeeded();
-
OpenGroupManager.INSTANCE.setAllCaughtUp(false);
OpenGroupManager.INSTANCE.startPolling();
}
@@ -210,7 +220,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
Log.i(TAG, "App is no longer visible.");
KeyCachingService.onAppBackgrounded(this);
messageNotifier.setVisibleThread(-1);
- // Loki
if (poller != null) {
poller.stopIfNeeded();
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java b/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java
index b556d20f55..85cf9332bf 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java
@@ -18,8 +18,11 @@ import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.annimon.stream.Stream;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
+
+import org.session.libsession.messaging.contacts.Contact;
import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
import org.thoughtcrime.securesms.database.DatabaseFactory;
+import org.thoughtcrime.securesms.loki.database.SessionContactDatabase;
import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
import org.thoughtcrime.securesms.mms.GlideRequests;
@@ -197,7 +200,14 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener
if (senderHexEncodedPublicKey.equalsIgnoreCase(TextSecurePreferences.getLocalNumber(getContext()))) {
quoteeDisplayName = TextSecurePreferences.getProfileName(getContext());
} else {
- quoteeDisplayName = DatabaseFactory.getLokiUserDatabase(getContext()).getDisplayName(senderHexEncodedPublicKey);
+ SessionContactDatabase contactDB = DatabaseFactory.getSessionContactDatabase(getContext());
+ Contact contact = contactDB.getContactWithSessionID(senderHexEncodedPublicKey);
+ if (contact != null) {
+ Contact.ContactContext context = (this.conversationRecipient.isOpenGroupRecipient()) ? Contact.ContactContext.OPEN_GROUP : Contact.ContactContext.REGULAR;
+ quoteeDisplayName = contact.displayName(context);
+ } else {
+ quoteeDisplayName = senderHexEncodedPublicKey;
+ }
}
authorView.setText(isOwnNumber ? getContext().getString(R.string.QuoteView_you) : quoteeDisplayName);
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java
index ddad4b628a..862a9bd2df 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java
@@ -62,7 +62,6 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
-
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -103,6 +102,7 @@ import org.session.libsession.utilities.recipients.RecipientModifiedListener;
import org.session.libsession.utilities.ExpirationUtil;
import org.session.libsession.utilities.GroupUtil;
import org.session.libsession.utilities.MediaTypes;
+import org.session.libsession.utilities.SSKEnvironment;
import org.session.libsession.utilities.ServiceUtil;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
@@ -157,8 +157,6 @@ import org.thoughtcrime.securesms.loki.activities.EditClosedGroupActivity;
import org.thoughtcrime.securesms.loki.activities.HomeActivity;
import org.thoughtcrime.securesms.loki.activities.SelectContactsActivity;
import org.thoughtcrime.securesms.loki.api.PublicChatInfoUpdateWorker;
-import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
-import org.thoughtcrime.securesms.loki.database.LokiUserDatabase;
import org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol;
import org.thoughtcrime.securesms.loki.utilities.GeneralUtilitiesKt;
import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities;
@@ -212,14 +210,14 @@ import network.loki.messenger.R;
*/
@SuppressLint("StaticFieldLeak")
public class ConversationActivity extends PassphraseRequiredActionBarActivity
- implements ConversationFragment.ConversationFragmentListener,
- AttachmentManager.AttachmentListener,
- RecipientModifiedListener,
- OnKeyboardShownListener,
- InputPanel.Listener,
- InputPanel.MediaListener,
- ComposeText.CursorPositionChangedListener,
- ConversationSearchBottomBar.EventListener
+ implements ConversationFragment.ConversationFragmentListener,
+ AttachmentManager.AttachmentListener,
+ RecipientModifiedListener,
+ OnKeyboardShownListener,
+ InputPanel.Listener,
+ InputPanel.MediaListener,
+ ComposeText.CursorPositionChangedListener,
+ ConversationSearchBottomBar.EventListener
{
private static final String TAG = ConversationActivity.class.getSimpleName();
@@ -234,11 +232,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
public static final String LAST_SEEN_EXTRA = "last_seen";
public static final String STARTING_POSITION_EXTRA = "starting_position";
-// private static final int PICK_GALLERY = 1;
+ // private static final int PICK_GALLERY = 1;
private static final int PICK_DOCUMENT = 2;
private static final int PICK_AUDIO = 3;
private static final int PICK_CONTACT = 4;
-// private static final int GET_CONTACT_DETAILS = 5;
+ // private static final int GET_CONTACT_DETAILS = 5;
// private static final int GROUP_EDIT = 6;
private static final int TAKE_PHOTO = 7;
private static final int ADD_CONTACT = 8;
@@ -418,7 +416,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.i(TAG, "onNewIntent()");
-
+
if (isFinishing()) {
Log.w(TAG, "Activity is finishing...");
return;
@@ -513,90 +511,89 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
super.onActivityResult(reqCode, resultCode, data);
if ((data == null && reqCode != TAKE_PHOTO && reqCode != SMS_DEFAULT) ||
- (resultCode != RESULT_OK && reqCode != SMS_DEFAULT))
+ (resultCode != RESULT_OK && reqCode != SMS_DEFAULT))
{
updateLinkPreviewState();
return;
}
switch (reqCode) {
- case PICK_DOCUMENT:
- setMedia(data.getData(), MediaType.DOCUMENT);
- break;
- case PICK_AUDIO:
- setMedia(data.getData(), MediaType.AUDIO);
- break;
- case TAKE_PHOTO:
- if (attachmentManager.getCaptureUri() != null) {
- setMedia(attachmentManager.getCaptureUri(), MediaType.IMAGE);
- }
- break;
- case ADD_CONTACT:
- recipient = Recipient.from(this, recipient.getAddress(), true);
- recipient.addListener(this);
- fragment.reloadList();
- break;
+ case PICK_DOCUMENT:
+ setMedia(data.getData(), MediaType.DOCUMENT);
+ break;
+ case PICK_AUDIO:
+ setMedia(data.getData(), MediaType.AUDIO);
+ break;
+ case TAKE_PHOTO:
+ if (attachmentManager.getCaptureUri() != null) {
+ setMedia(attachmentManager.getCaptureUri(), MediaType.IMAGE);
+ }
+ break;
+ case ADD_CONTACT:
+ recipient = Recipient.from(this, recipient.getAddress(), true);
+ recipient.addListener(this);
+ fragment.reloadList();
+ break;
/*
case PICK_LOCATION:
SignalPlace place = new SignalPlace(PlacePicker.getPlace(data, this));
attachmentManager.setLocation(place, getCurrentMediaConstraints());
break;
*/
- case PICK_GIF:
- setMedia(data.getData(),
- MediaType.GIF,
- data.getIntExtra(GiphyActivity.EXTRA_WIDTH, 0),
- data.getIntExtra(GiphyActivity.EXTRA_HEIGHT, 0));
- break;
- case SMS_DEFAULT:
- initializeSecurity(true, isDefaultSms);
- break;
- case MEDIA_SENDER:
- long expiresIn = recipient.getExpireMessages() * 1000L;
- int subscriptionId = -1;
- boolean initiating = threadId == -1;
- String message = data.getStringExtra(MediaSendActivity.EXTRA_MESSAGE);
- SlideDeck slideDeck = new SlideDeck();
+ case PICK_GIF:
+ setMedia(data.getData(),
+ MediaType.GIF,
+ data.getIntExtra(GiphyActivity.EXTRA_WIDTH, 0),
+ data.getIntExtra(GiphyActivity.EXTRA_HEIGHT, 0));
+ break;
+ case SMS_DEFAULT:
+ initializeSecurity(true, isDefaultSms);
+ break;
+ case MEDIA_SENDER:
+ long expiresIn = recipient.getExpireMessages() * 1000L;
+ int subscriptionId = -1;
+ boolean initiating = threadId == -1;
+ String message = data.getStringExtra(MediaSendActivity.EXTRA_MESSAGE);
+ SlideDeck slideDeck = new SlideDeck();
- List mediaList = data.getParcelableArrayListExtra(MediaSendActivity.EXTRA_MEDIA);
+ List mediaList = data.getParcelableArrayListExtra(MediaSendActivity.EXTRA_MEDIA);
- for (Media mediaItem : mediaList) {
- if (MediaUtil.isVideoType(mediaItem.getMimeType())) {
- slideDeck.addSlide(new VideoSlide(this, mediaItem.getUri(), 0, mediaItem.getCaption().orNull()));
- } else if (MediaUtil.isGif(mediaItem.getMimeType())) {
- slideDeck.addSlide(new GifSlide(this, mediaItem.getUri(), 0, mediaItem.getWidth(), mediaItem.getHeight(), mediaItem.getCaption().orNull()));
- } else if (MediaUtil.isImageType(mediaItem.getMimeType())) {
- slideDeck.addSlide(new ImageSlide(this, mediaItem.getUri(), 0, mediaItem.getWidth(), mediaItem.getHeight(), mediaItem.getCaption().orNull()));
- } else {
- Log.w(TAG, "Asked to send an unexpected mimeType: '" + mediaItem.getMimeType() + "'. Skipping.");
+ for (Media mediaItem : mediaList) {
+ if (MediaUtil.isVideoType(mediaItem.getMimeType())) {
+ slideDeck.addSlide(new VideoSlide(this, mediaItem.getUri(), 0, mediaItem.getCaption().orNull()));
+ } else if (MediaUtil.isGif(mediaItem.getMimeType())) {
+ slideDeck.addSlide(new GifSlide(this, mediaItem.getUri(), 0, mediaItem.getWidth(), mediaItem.getHeight(), mediaItem.getCaption().orNull()));
+ } else if (MediaUtil.isImageType(mediaItem.getMimeType())) {
+ slideDeck.addSlide(new ImageSlide(this, mediaItem.getUri(), 0, mediaItem.getWidth(), mediaItem.getHeight(), mediaItem.getCaption().orNull()));
+ } else {
+ Log.w(TAG, "Asked to send an unexpected mimeType: '" + mediaItem.getMimeType() + "'. Skipping.");
+ }
}
- }
- final Context context = ConversationActivity.this.getApplicationContext();
+ final Context context = ConversationActivity.this.getApplicationContext();
- sendMediaMessage(message,
- slideDeck,
- inputPanel.getQuote().orNull(),
- Optional.absent(),
- initiating).addListener(new AssertedSuccessListener() {
- @Override
- public void onSuccess(Void result) {
- AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
- Stream.of(slideDeck.getSlides())
- .map(Slide::getUri)
- .withoutNulls()
- .filter(BlobProvider::isAuthority)
- .forEach(uri -> BlobProvider.getInstance().delete(context, uri));
- });
- }
- });
-
- break;
- case INVITE_CONTACTS:
- if (data.getExtras() == null || !data.hasExtra(SelectContactsActivity.Companion.getSelectedContactsKey())) return;
- String[] selectedContacts = data.getExtras().getStringArray(SelectContactsActivity.Companion.getSelectedContactsKey());
- sendOpenGroupInvitations(selectedContacts);
- break;
+ sendMediaMessage(message,
+ slideDeck,
+ inputPanel.getQuote().orNull(),
+ Optional.absent(),
+ initiating).addListener(new AssertedSuccessListener() {
+ @Override
+ public void onSuccess(Void result) {
+ AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
+ Stream.of(slideDeck.getSlides())
+ .map(Slide::getUri)
+ .withoutNulls()
+ .filter(BlobProvider::isAuthority)
+ .forEach(uri -> BlobProvider.getInstance().delete(context, uri));
+ });
+ }
+ });
+ break;
+ case INVITE_CONTACTS:
+ if (data.getExtras() == null || !data.hasExtra(SelectContactsActivity.Companion.getSelectedContactsKey())) return;
+ String[] selectedContacts = data.getExtras().getStringArray(SelectContactsActivity.Companion.getSelectedContactsKey());
+ sendOpenGroupInvitations(selectedContacts);
+ break;
}
}
@@ -676,14 +673,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (isSingleConversation() && getRecipient().getContactUri() == null) {
inflater.inflate(R.menu.conversation_add_to_contacts, menu);
}
-
-
if (recipient != null && recipient.isLocalNumber()) {
if (isSecureText) menu.findItem(R.id.menu_call_secure).setVisible(false);
else menu.findItem(R.id.menu_call_insecure).setVisible(false);
-
MenuItem muteItem = menu.findItem(R.id.menu_mute_notifications);
-
if (muteItem != null) {
muteItem.setVisible(false);
}
@@ -751,26 +744,26 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
switch (item.getItemId()) {
// case R.id.menu_call_secure: handleDial(getRecipient(), true); 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_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_add_shortcut: handleAddShortcut(); return true;
- case R.id.menu_search: handleSearch(); return true;
+ case R.id.menu_unblock: handleUnblock(); 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_add_shortcut: handleAddShortcut(); return true;
+ case R.id.menu_search: handleSearch(); return true;
// case R.id.menu_add_to_contacts: handleAddToContacts(); return true;
// case R.id.menu_reset_secure_session: handleResetSecureSession(); return true;
// case R.id.menu_group_recipients: handleDisplayGroupRecipients(); return true;
- case R.id.menu_distribution_broadcast: handleDistributionBroadcastEnabled(item); return true;
- case R.id.menu_distribution_conversation: handleDistributionConversationEnabled(item); return true;
- case R.id.menu_edit_group: handleEditPushGroup(); return true;
- case R.id.menu_leave: handleLeavePushGroup(); return true;
- case R.id.menu_mute_notifications: handleMuteNotifications(); return true;
- case R.id.menu_unmute_notifications: handleUnmuteNotifications(); return true;
+ case R.id.menu_distribution_broadcast: handleDistributionBroadcastEnabled(item); return true;
+ case R.id.menu_distribution_conversation: handleDistributionConversationEnabled(item); return true;
+ case R.id.menu_edit_group: handleEditPushGroup(); return true;
+ case R.id.menu_leave: handleLeavePushGroup(); return true;
+ case R.id.menu_mute_notifications: handleMuteNotifications(); return true;
+ case R.id.menu_unmute_notifications: handleUnmuteNotifications(); return true;
// case R.id.menu_conversation_settings: handleConversationSettings(); return true;
- case R.id.menu_expiring_messages_off:
- case R.id.menu_expiring_messages: handleSelectMessageExpiration(); return true;
- case R.id.menu_invite_to_open_group: handleInviteToOpenGroup(); return true;
- case android.R.id.home: handleReturnToConversationList(); return true;
+ case R.id.menu_expiring_messages_off:
+ case R.id.menu_expiring_messages: handleSelectMessageExpiration(); return true;
+ case R.id.menu_invite_to_open_group: handleInviteToOpenGroup(); return true;
+ case android.R.id.home: handleReturnToConversationList(); return true;
}
return false;
@@ -841,7 +834,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@Override
protected Void doInBackground(Void... params) {
DatabaseFactory.getRecipientDatabase(ConversationActivity.this)
- .setMuted(recipient, until);
+ .setMuted(recipient, until);
return null;
}
@@ -856,7 +849,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@Override
protected Void doInBackground(Void... params) {
DatabaseFactory.getRecipientDatabase(ConversationActivity.this)
- .setMuted(recipient, 0);
+ .setMuted(recipient, 0);
return null;
}
@@ -868,20 +861,20 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
int bodyRes = R.string.ConversationActivity_you_will_once_again_be_able_to_receive_messages_and_calls_from_this_contact;
new AlertDialog.Builder(this)
- .setTitle(titleRes)
- .setMessage(bodyRes)
- .setNegativeButton(android.R.string.cancel, null)
- .setPositiveButton(R.string.ConversationActivity_unblock, (dialog, which) -> {
- new AsyncTask() {
- @Override
- protected Void doInBackground(Void... params) {
- DatabaseFactory.getRecipientDatabase(ConversationActivity.this)
- .setBlocked(recipient, false);
+ .setTitle(titleRes)
+ .setMessage(bodyRes)
+ .setNegativeButton(android.R.string.cancel, null)
+ .setPositiveButton(R.string.ConversationActivity_unblock, (dialog, which) -> {
+ new AsyncTask() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ DatabaseFactory.getRecipientDatabase(ConversationActivity.this)
+ .setBlocked(recipient, false);
- return null;
- }
- }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }).show();
+ return null;
+ }
+ }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }).show();
}
@TargetApi(Build.VERSION_CODES.KITKAT)
@@ -951,7 +944,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (icon == null) {
icon = IconCompat.createWithResource(context, recipient.isGroupRecipient() ? R.mipmap.ic_group_shortcut
- : R.mipmap.ic_person_shortcut);
+ : R.mipmap.ic_person_shortcut);
}
return icon;
@@ -961,14 +954,14 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
protected void onPostExecute(IconCompat icon) {
Context context = getApplicationContext();
String name = Optional.fromNullable(recipient.getName())
- .or(Optional.fromNullable(recipient.getProfileName()))
- .or(recipient.toShortString());
+ .or(Optional.fromNullable(recipient.getProfileName()))
+ .or(recipient.toShortString());
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(context, recipient.getAddress().serialize() + '-' + System.currentTimeMillis())
- .setShortLabel(name)
- .setIcon(icon)
- .setIntent(ShortcutLauncherActivity.createIntent(context, recipient.getAddress()))
- .build();
+ .setShortLabel(name)
+ .setIcon(icon)
+ .setIntent(ShortcutLauncherActivity.createIntent(context, recipient.getAddress()))
+ .build();
if (ShortcutManagerCompat.requestPinShortcut(context, shortcutInfo, null)) {
Toast.makeText(context, getString(R.string.ConversationActivity_added_to_home_screen), Toast.LENGTH_LONG).show();
@@ -984,7 +977,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private void handleLeavePushGroup() {
if (getRecipient() == null) {
Toast.makeText(this, getString(R.string.ConversationActivity_invalid_recipient),
- Toast.LENGTH_LONG).show();
+ Toast.LENGTH_LONG).show();
return;
}
@@ -1052,7 +1045,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@Override
protected Void doInBackground(Void... params) {
DatabaseFactory.getThreadDatabase(ConversationActivity.this)
- .setDistributionType(threadId, DistributionTypes.BROADCAST);
+ .setDistributionType(threadId, DistributionTypes.BROADCAST);
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@@ -1068,7 +1061,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@Override
protected Void doInBackground(Void... params) {
DatabaseFactory.getThreadDatabase(ConversationActivity.this)
- .setDistributionType(threadId, DistributionTypes.CONVERSATION);
+ .setDistributionType(threadId, DistributionTypes.CONVERSATION);
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
@@ -1100,7 +1093,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
/* Loki - We don't support SMS
if (!isSecureText && !isPushGroupConversation()) sendButton.disableTransport(Type.TEXTSECURE);
if (recipient.isPushGroupRecipient()) sendButton.disableTransport(Type.SMS);
-
if (!recipient.isPushGroupRecipient() && recipient.isForceSmsSelection()) {
sendButton.setDefaultTransport(Type.SMS);
} else {
@@ -1425,35 +1417,35 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
Log.i(TAG, "Selected: " + type);
switch (type) {
- case AttachmentTypeSelector.ADD_GALLERY:
- AttachmentManager.selectGallery(this, MEDIA_SENDER, recipient, composeText.getTextTrimmed()); break;
- case AttachmentTypeSelector.ADD_DOCUMENT:
- AttachmentManager.selectDocument(this, PICK_DOCUMENT); break;
- case AttachmentTypeSelector.ADD_SOUND:
- AttachmentManager.selectAudio(this, PICK_AUDIO); break;
- case AttachmentTypeSelector.ADD_CONTACT_INFO:
- AttachmentManager.selectContactInfo(this, PICK_CONTACT); break;
- case AttachmentTypeSelector.ADD_LOCATION:
- AttachmentManager.selectLocation(this, PICK_LOCATION); break;
- case AttachmentTypeSelector.TAKE_PHOTO:
- attachmentManager.capturePhoto(this, TAKE_PHOTO); break;
- case AttachmentTypeSelector.ADD_GIF:
- boolean hasSeenGIFMetaDataWarning = TextSecurePreferences.hasSeenGIFMetaDataWarning(this);
- if (!hasSeenGIFMetaDataWarning) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("Search GIFs?");
- builder.setMessage("You will not have full metadata protection when sending GIFs.");
- builder.setPositiveButton("OK", (dialog, which) -> {
+ case AttachmentTypeSelector.ADD_GALLERY:
+ AttachmentManager.selectGallery(this, MEDIA_SENDER, recipient, composeText.getTextTrimmed()); break;
+ case AttachmentTypeSelector.ADD_DOCUMENT:
+ AttachmentManager.selectDocument(this, PICK_DOCUMENT); break;
+ case AttachmentTypeSelector.ADD_SOUND:
+ AttachmentManager.selectAudio(this, PICK_AUDIO); break;
+ case AttachmentTypeSelector.ADD_CONTACT_INFO:
+ AttachmentManager.selectContactInfo(this, PICK_CONTACT); break;
+ case AttachmentTypeSelector.ADD_LOCATION:
+ AttachmentManager.selectLocation(this, PICK_LOCATION); break;
+ case AttachmentTypeSelector.TAKE_PHOTO:
+ attachmentManager.capturePhoto(this, TAKE_PHOTO); break;
+ case AttachmentTypeSelector.ADD_GIF:
+ boolean hasSeenGIFMetaDataWarning = TextSecurePreferences.hasSeenGIFMetaDataWarning(this);
+ if (!hasSeenGIFMetaDataWarning) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Search GIFs?");
+ builder.setMessage("You will not have full metadata protection when sending GIFs.");
+ builder.setPositiveButton("OK", (dialog, which) -> {
+ AttachmentManager.selectGif(this, PICK_GIF);
+ dialog.dismiss();
+ });
+ builder.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss());
+ builder.create().show();
+ TextSecurePreferences.setHasSeenGIFMetaDataWarning(this);
+ } else {
AttachmentManager.selectGif(this, PICK_GIF);
- dialog.dismiss();
- });
- builder.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss());
- builder.create().show();
- TextSecurePreferences.setHasSeenGIFMetaDataWarning(this);
- } else {
- AttachmentManager.selectGif(this, PICK_GIF);
- }
- break;
+ }
+ break;
}
}
@@ -1548,8 +1540,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
draftDatabase.insertDrafts(threadId, drafts);
threadDatabase.updateSnippet(threadId, drafts.getSnippet(ConversationActivity.this),
- drafts.getUriSnippet(),
- System.currentTimeMillis(), Types.BASE_DRAFT_TYPE, true);
+ drafts.getUriSnippet(),
+ System.currentTimeMillis(), Types.BASE_DRAFT_TYPE, true);
} else if (threadId > 0) {
threadDatabase.update(threadId, false);
}
@@ -1652,10 +1644,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
String timestamp = new SimpleDateFormat("yyyy-MM-dd-HHmmss", Locale.US).format(new Date());
String filename = String.format("signal-%s.txt", timestamp);
Uri textUri = BlobProvider.getInstance()
- .forData(textData)
- .withMimeType(MediaTypes.LONG_TEXT)
- .withFileName(filename)
- .createForSingleSessionInMemory();
+ .forData(textData)
+ .withMimeType(MediaTypes.LONG_TEXT)
+ .withFileName(filename)
+ .createForSingleSessionInMemory();
textSlide = Optional.of(new TextSlide(this, textUri, filename, textData.length));
}
@@ -1733,10 +1725,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
boolean needsSplit = message.length() > characterCalculator.calculateCharacters(message).maxPrimaryMessageSize;
boolean isMediaMessage = attachmentManager.isAttachmentPresent() ||
// recipient.isGroupRecipient() ||
- inputPanel.getQuote().isPresent() ||
- linkPreviewViewModel.hasLinkPreview() ||
- LinkPreviewUtil.isValidMediaUrl(message) || // Loki - Send GIFs as media messages
- needsSplit;
+ inputPanel.getQuote().isPresent() ||
+ linkPreviewViewModel.hasLinkPreview() ||
+ LinkPreviewUtil.isValidMediaUrl(message) || // Loki - Send GIFs as media messages
+ needsSplit;
if (isMediaMessage) {
sendMediaMessage(initiating);
@@ -1757,7 +1749,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
private void sendMediaMessage(boolean initiating)
- throws InvalidMessageException
+ throws InvalidMessageException
{
Log.i(TAG, "Sending media message...");
sendMediaMessage(getMessage(), attachmentManager.buildSlideDeck(), inputPanel.getQuote().orNull(), linkPreviewViewModel.getActiveLinkPreview(), initiating);
@@ -1817,7 +1809,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
private void sendTextMessage(final boolean initiating)
- throws InvalidMessageException
+ throws InvalidMessageException
{
final Context context = getApplicationContext();
final String messageBody = getMessage();
@@ -1895,10 +1887,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@Override
public void onRecorderPermissionRequired() {
Permissions.with(this)
- .request(Manifest.permission.RECORD_AUDIO)
- .withRationaleDialog(getString(R.string.ConversationActivity_to_send_audio_messages_allow_signal_access_to_your_microphone), R.drawable.ic_baseline_mic_48)
- .withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_requires_the_microphone_permission_in_order_to_send_audio_messages))
- .execute();
+ .request(Manifest.permission.RECORD_AUDIO)
+ .withRationaleDialog(getString(R.string.ConversationActivity_to_send_audio_messages_allow_signal_access_to_your_microphone), R.drawable.ic_baseline_mic_48)
+ .withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_requires_the_microphone_permission_in_order_to_send_audio_messages))
+ .execute();
}
@Override
@@ -2057,16 +2049,16 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@Override
public void onClick(View v) {
Permissions.with(ConversationActivity.this)
- .request(Manifest.permission.CAMERA)
- .withRationaleDialog(getString(R.string.ConversationActivity_to_capture_photos_and_video_allow_signal_access_to_the_camera), R.drawable.ic_baseline_photo_camera_48)
- .withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_needs_the_camera_permission_to_take_photos_or_video))
- .onAllGranted(() -> {
- composeText.clearFocus();
- startActivityForResult(MediaSendActivity.buildCameraIntent(ConversationActivity.this, recipient), MEDIA_SENDER);
- overridePendingTransition(R.anim.camera_slide_from_bottom, R.anim.stationary);
- })
- .onAnyDenied(() -> Toast.makeText(ConversationActivity.this, R.string.ConversationActivity_signal_needs_camera_permissions_to_take_photos_or_video, Toast.LENGTH_LONG).show())
- .execute();
+ .request(Manifest.permission.CAMERA)
+ .withRationaleDialog(getString(R.string.ConversationActivity_to_capture_photos_and_video_allow_signal_access_to_the_camera), R.drawable.ic_baseline_photo_camera_48)
+ .withPermanentDenialDialog(getString(R.string.ConversationActivity_signal_needs_the_camera_permission_to_take_photos_or_video))
+ .onAllGranted(() -> {
+ composeText.clearFocus();
+ startActivityForResult(MediaSendActivity.buildCameraIntent(ConversationActivity.this, recipient), MEDIA_SENDER);
+ overridePendingTransition(R.anim.camera_slide_from_bottom, R.anim.stationary);
+ })
+ .onAnyDenied(() -> Toast.makeText(ConversationActivity.this, R.string.ConversationActivity_signal_needs_camera_permissions_to_take_photos_or_video, Toast.LENGTH_LONG).show())
+ .execute();
}
}
@@ -2176,7 +2168,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
if (text.length() > 0) {
if (currentMentionStartIndex > text.length()) {
- resetMentions(); // Should never occur
+ resetMentions(); // Should never occur
}
int lastCharacterIndex = text.length() - 1;
char lastCharacter = text.charAt(lastCharacterIndex);
@@ -2184,11 +2176,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
if (lastCharacterIndex > 0) {
secondToLastCharacter = text.charAt(lastCharacterIndex - 1);
}
- String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(ConversationActivity.this);
- LokiThreadDatabase threadDatabase = DatabaseFactory.getLokiThreadDatabase(ConversationActivity.this);
- LokiUserDatabase userDatabase = DatabaseFactory.getLokiUserDatabase(ConversationActivity.this);
if (lastCharacter == '@' && Character.isWhitespace(secondToLastCharacter)) {
- List mentionCandidates = MentionsManager.shared.getMentionCandidates("", threadId);
+ List mentionCandidates = MentionsManager.INSTANCE.getMentionCandidates("", threadId, recipient.isOpenGroupRecipient());
currentMentionStartIndex = lastCharacterIndex;
mentionCandidateSelectionViewContainer.setVisibility(View.VISIBLE);
mentionCandidateSelectionView.show(mentionCandidates, threadId);
@@ -2199,7 +2188,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} else {
if (currentMentionStartIndex != -1) {
String query = text.substring(currentMentionStartIndex + 1); // + 1 to get rid of the @
- List mentionCandidates = MentionsManager.shared.getMentionCandidates(query, threadId);
+ List mentionCandidates = MentionsManager.INSTANCE.getMentionCandidates(query, threadId, recipient.isOpenGroupRecipient());
mentionCandidateSelectionViewContainer.setVisibility(View.VISIBLE);
mentionCandidateSelectionView.show(mentionCandidates, threadId);
}
@@ -2243,12 +2232,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
inputPanel.setQuote(GlideApp.with(this),
- messageRecord.getDateSent(),
- author,
- body,
- slideDeck,
- recipient,
- threadId);
+ messageRecord.getDateSent(),
+ author,
+ body,
+ slideDeck,
+ recipient,
+ threadId);
} else if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getLinkPreviews().isEmpty()) {
LinkPreview linkPreview = ((MmsMessageRecord) messageRecord).getLinkPreviews().get(0);
@@ -2259,26 +2248,26 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
inputPanel.setQuote(GlideApp.with(this),
- messageRecord.getDateSent(),
- author,
- messageRecord.getBody(),
- slideDeck,
- recipient,
- threadId);
+ messageRecord.getDateSent(),
+ author,
+ messageRecord.getBody(),
+ slideDeck,
+ recipient,
+ threadId);
} else {
inputPanel.setQuote(GlideApp.with(this),
- messageRecord.getDateSent(),
- author,
- messageRecord.getBody(),
- messageRecord.isMms() ? ((MmsMessageRecord) messageRecord).getSlideDeck() : new SlideDeck(),
- recipient,
- threadId);
+ messageRecord.getDateSent(),
+ author,
+ messageRecord.getBody(),
+ messageRecord.isMms() ? ((MmsMessageRecord) messageRecord).getSlideDeck() : new SlideDeck(),
+ recipient,
+ threadId);
}
}
@Override
public void onMessageActionToolbarOpened() {
- searchViewItem.collapseActionView();
+ searchViewItem.collapseActionView();
}
@Override
@@ -2344,8 +2333,9 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
} else if (recipient.getAddress().toString().toLowerCase().equals(userPublicKey)) {
titleTextView.setText(getResources().getString(R.string.note_to_self));
} else {
- boolean hasName = (recipient.getName() != null && !recipient.getName().isEmpty());
- titleTextView.setText(hasName ? recipient.getName() : recipient.getAddress().toString());
+ String displayName = recipient.getName(); // Uses the Contact API internally
+ boolean hasName = (displayName != null);
+ titleTextView.setText(hasName ? displayName : recipient.getAddress().toString());
}
}
@@ -2391,7 +2381,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private void updateMessageStatusProgressBar() {
if (messageStatus != null) {
- messageStatusProgressBar.setAlpha(1.0f);
+ messageStatusProgressBar.setAlpha(1.0f);
switch (messageStatus) {
case "calculatingPoW": setMessageStatusProgressAnimatedIfPossible(25); break;
case "contactingNetwork": setMessageStatusProgressAnimatedIfPossible(50); break;
@@ -2428,7 +2418,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
default: return -1;
}
} else {
- return -1;
+ return -1;
}
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java
index 7467cdcc78..c089feed6b 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java
@@ -49,6 +49,8 @@ import androidx.annotation.DimenRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.annimon.stream.Stream;
+
+import org.session.libsession.messaging.contacts.Contact;
import org.session.libsession.messaging.jobs.AttachmentDownloadJob;
import org.session.libsession.messaging.jobs.JobQueue;
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2;
@@ -889,7 +891,15 @@ public class ConversationItem extends LinearLayout
@SuppressLint("SetTextI18n")
private void setGroupMessageStatus(MessageRecord messageRecord, Recipient recipient) {
if (groupThread && !messageRecord.isOutgoing()) {
- String displayName = recipient.toShortString();
+ String sessionID = recipient.getAddress().serialize();
+ Contact contact = DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(sessionID);
+ String displayName;
+ if (contact != null) {
+ Contact.ContactContext context = (this.conversationRecipient.isOpenGroupRecipient()) ? Contact.ContactContext.OPEN_GROUP : Contact.ContactContext.REGULAR;
+ displayName = contact.displayName(context);
+ } else {
+ displayName = sessionID;
+ }
this.groupSender.setText(displayName);
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java
index ea534c35f8..9a87fa8730 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java
@@ -17,11 +17,8 @@
package org.thoughtcrime.securesms.database;
import android.content.Context;
-
import androidx.annotation.NonNull;
-
import net.sqlcipher.database.SQLiteDatabase;
-
import org.thoughtcrime.securesms.attachments.DatabaseAttachmentProvider;
import org.thoughtcrime.securesms.crypto.AttachmentSecret;
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;
@@ -34,6 +31,7 @@ import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase;
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
import org.thoughtcrime.securesms.loki.database.LokiUserDatabase;
import org.thoughtcrime.securesms.loki.database.SessionJobDatabase;
+import org.thoughtcrime.securesms.loki.database.SessionContactDatabase;
public class DatabaseFactory {
@@ -55,16 +53,13 @@ public class DatabaseFactory {
private final GroupReceiptDatabase groupReceiptDatabase;
private final SearchDatabase searchDatabase;
private final JobDatabase jobDatabase;
-
- // Loki
private final LokiAPIDatabase lokiAPIDatabase;
private final LokiMessageDatabase lokiMessageDatabase;
private final LokiThreadDatabase lokiThreadDatabase;
private final LokiUserDatabase lokiUserDatabase;
private final LokiBackupFilesDatabase lokiBackupFilesDatabase;
private final SessionJobDatabase sessionJobDatabase;
-
- // Refactor
+ private final SessionContactDatabase sessionContactDatabase;
private final Storage storage;
private final DatabaseAttachmentProvider attachmentProvider;
@@ -157,6 +152,10 @@ public class DatabaseFactory {
public static SessionJobDatabase getSessionJobDatabase(Context context) {
return getInstance(context).sessionJobDatabase;
}
+
+ public static SessionContactDatabase getSessionContactDatabase(Context context) {
+ return getInstance(context).sessionContactDatabase;
+ }
// endregion
// region Refactor
@@ -202,6 +201,7 @@ public class DatabaseFactory {
this.storage = new Storage(context, databaseHelper);
this.attachmentProvider = new DatabaseAttachmentProvider(context, databaseHelper);
this.sessionJobDatabase = new SessionJobDatabase(context, databaseHelper);
+ this.sessionContactDatabase = new SessionContactDatabase(context, databaseHelper);
}
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java
index d2b6ace217..287a6d365c 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java
@@ -248,6 +248,7 @@ public class RecipientDatabase extends Database {
ContentValues contentValues = new ContentValues(1);
contentValues.put(SYSTEM_DISPLAY_NAME, profileName);
updateOrInsert(recipient.getAddress(), contentValues);
+ recipient.resolve().setName(profileName);
recipient.resolve().setProfileName(profileName);
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt
index 8266107692..f57318cd5b 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.database
import android.content.Context
import android.net.Uri
import org.session.libsession.database.StorageProtocol
+import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.jobs.AttachmentUploadJob
import org.session.libsession.messaging.jobs.Job
import org.session.libsession.messaging.jobs.JobQueue
@@ -79,23 +80,6 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(ourRecipient, newValue))
}
- override fun getProfileKeyForRecipient(recipientPublicKey: String): ByteArray? {
- val address = Address.fromSerialized(recipientPublicKey)
- val recipient = Recipient.from(context, address, false)
- return recipient.profileKey
- }
-
- override fun getDisplayNameForRecipient(recipientPublicKey: String): String? {
- val database = DatabaseFactory.getLokiUserDatabase(context)
- return database.getDisplayName(recipientPublicKey)
- }
-
- override fun setProfileKeyForRecipient(recipientPublicKey: String, profileKey: ByteArray) {
- val address = Address.fromSerialized(recipientPublicKey)
- val recipient = Recipient.from(context, address, false)
- DatabaseFactory.getRecipientDatabase(context).setProfileKey(recipient, profileKey)
- }
-
override fun getOrGenerateRegistrationID(): Int {
var registrationID = TextSecurePreferences.getLocalRegistrationId(context)
if (registrationID == 0) {
@@ -507,16 +491,16 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
return threadId
}
- override fun getDisplayName(publicKey: String): String? {
- return DatabaseFactory.getLokiUserDatabase(context).getDisplayName(publicKey)
+ override fun getContactWithSessionID(sessionID: String): Contact? {
+ return DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(sessionID)
}
- override fun setDisplayName(publicKey: String, newName: String) {
- DatabaseFactory.getLokiUserDatabase(context).setDisplayName(publicKey, newName)
+ override fun getAllContacts(): Set {
+ return DatabaseFactory.getSessionContactDatabase(context).getAllContacts()
}
- override fun getProfilePictureURL(publicKey: String): String? {
- return DatabaseFactory.getLokiUserDatabase(context).getProfilePictureURL(publicKey)
+ override fun setContact(contact: Contact) {
+ DatabaseFactory.getSessionContactDatabase(context).setContact(contact)
}
override fun getRecipientSettings(address: Address): Recipient.RecipientSettings? {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
index d6c62f8f15..349f7a082b 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
@@ -28,6 +28,7 @@ import org.thoughtcrime.securesms.loki.database.LokiBackupFilesDatabase;
import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase;
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
import org.thoughtcrime.securesms.loki.database.LokiUserDatabase;
+import org.thoughtcrime.securesms.loki.database.SessionContactDatabase;
import org.thoughtcrime.securesms.loki.database.SessionJobDatabase;
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsMigration;
@@ -57,9 +58,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
private static final int lokiV23 = 44;
private static final int lokiV24 = 45;
private static final int lokiV25 = 46;
+ private static final int lokiV26 = 47;
// Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
- private static final int DATABASE_VERSION = lokiV25;
+ private static final int DATABASE_VERSION = lokiV26;
private static final String DATABASE_NAME = "signal.db";
private final Context context;
@@ -124,11 +126,11 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
db.execSQL(LokiThreadDatabase.getCreateSessionResetTableCommand());
db.execSQL(LokiThreadDatabase.getCreatePublicChatTableCommand());
db.execSQL(LokiUserDatabase.getCreateDisplayNameTableCommand());
- db.execSQL(LokiUserDatabase.getCreateServerDisplayNameTableCommand());
db.execSQL(LokiBackupFilesDatabase.getCreateTableCommand());
db.execSQL(SessionJobDatabase.getCreateSessionJobTableCommand());
db.execSQL(LokiMessageDatabase.getUpdateMessageIDTableForType());
db.execSQL(LokiMessageDatabase.getUpdateMessageMappingTable());
+ db.execSQL(SessionContactDatabase.getCreateSessionContactTableCommand());
executeStatements(db, SmsDatabase.CREATE_INDEXS);
executeStatements(db, MmsDatabase.CREATE_INDEXS);
@@ -298,6 +300,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
db.execSQL(SessionJobDatabase.getCreateSessionJobTableCommand());
}
+ if (oldVersion < lokiV26) {
+ db.execSQL(SessionContactDatabase.getCreateSessionContactTableCommand());
+ }
+
db.setTransactionSuccessful();
} finally {
db.endTransaction();
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt
index f8ed445146..84fd67da53 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt
@@ -132,12 +132,8 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
})
// Set up remaining components if needed
val application = ApplicationContext.getInstance(this)
- val apiDB = DatabaseFactory.getLokiAPIDatabase(this)
- val threadDB = DatabaseFactory.getLokiThreadDatabase(this)
- val userDB = DatabaseFactory.getLokiUserDatabase(this)
val userPublicKey = TextSecurePreferences.getLocalNumber(this)
if (userPublicKey != null) {
- MentionsManager.configureIfNeeded(userPublicKey, userDB)
OpenGroupManager.startPolling()
JobQueue.shared.resumePendingJobs()
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt
index c521c45c9e..ac342a707c 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt
@@ -72,7 +72,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) {
super.onCreate(savedInstanceState, isReady)
setContentView(R.layout.activity_settings)
- val displayName = DatabaseFactory.getLokiUserDatabase(this).getDisplayName(hexEncodedPublicKey)
+ val displayName = TextSecurePreferences.getProfileName(this) ?: hexEncodedPublicKey
glide = GlideApp.with(this)
profilePictureView.glide = glide
profilePictureView.publicKey = hexEncodedPublicKey
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt
index 15e76ac0ec..91f04adef8 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt
@@ -278,14 +278,6 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
}
}
- override fun getLastMessageServerID(group: Long, server: String): Long? {
- val database = databaseHelper.readableDatabase
- val index = "$server.$group"
- return database.get(lastMessageServerIDTable, "$lastMessageServerIDTableIndex = ?", wrap(index)) { cursor ->
- cursor.getInt(lastMessageServerID)
- }?.toLong()
- }
-
override fun getLastMessageServerID(room: String, server: String): Long? {
val database = databaseHelper.writableDatabase
val index = "$server.$room"
@@ -294,13 +286,6 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
}?.toLong()
}
- override fun setLastMessageServerID(group: Long, server: String, newValue: Long) {
- val database = databaseHelper.writableDatabase
- val index = "$server.$group"
- val row = wrap(mapOf( lastMessageServerIDTableIndex to index, lastMessageServerID to newValue.toString() ))
- database.insertOrUpdate(lastMessageServerIDTable, row, "$lastMessageServerIDTableIndex = ?", wrap(index))
- }
-
override fun setLastMessageServerID(room: String, server: String, newValue: Long) {
val database = databaseHelper.writableDatabase
val index = "$server.$room"
@@ -308,26 +293,12 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
database.insertOrUpdate(lastMessageServerIDTable, row, "$lastMessageServerIDTableIndex = ?", wrap(index))
}
- fun removeLastMessageServerID(group: Long, server: String) {
- val database = databaseHelper.writableDatabase
- val index = "$server.$group"
- database.delete(lastMessageServerIDTable,"$lastMessageServerIDTableIndex = ?", wrap(index))
- }
-
fun removeLastMessageServerID(room: String, server:String) {
val database = databaseHelper.writableDatabase
val index = "$server.$room"
database.delete(lastMessageServerIDTable, "$lastMessageServerIDTableIndex = ?", wrap(index))
}
- override fun getLastDeletionServerID(group: Long, server: String): Long? {
- val database = databaseHelper.readableDatabase
- val index = "$server.$group"
- return database.get(lastDeletionServerIDTable, "$lastDeletionServerIDTableIndex = ?", wrap(index)) { cursor ->
- cursor.getInt(lastDeletionServerID)
- }?.toLong()
- }
-
override fun getLastDeletionServerID(room: String, server: String): Long? {
val database = databaseHelper.readableDatabase
val index = "$server.$room"
@@ -336,13 +307,6 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
}?.toLong()
}
- override fun setLastDeletionServerID(group: Long, server: String, newValue: Long) {
- val database = databaseHelper.writableDatabase
- val index = "$server.$group"
- val row = wrap(mapOf( lastDeletionServerIDTableIndex to index, lastDeletionServerID to newValue.toString() ))
- database.insertOrUpdate(lastDeletionServerIDTable, row, "$lastDeletionServerIDTableIndex = ?", wrap(index))
- }
-
override fun setLastDeletionServerID(room: String, server: String, newValue: Long) {
val database = databaseHelper.writableDatabase
val index = "$server.$room"
@@ -392,32 +356,6 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
database.insertOrUpdate(userCountTable, row, "$publicChatID = ?", wrap(index))
}
- override fun getSessionRequestSentTimestamp(publicKey: String): Long? {
- val database = databaseHelper.readableDatabase
- return database.get(sessionRequestSentTimestampTable, "${LokiAPIDatabase.publicKey} = ?", wrap(publicKey)) { cursor ->
- cursor.getLong(LokiAPIDatabase.timestamp)
- }?.toLong()
- }
-
- override fun setSessionRequestSentTimestamp(publicKey: String, newValue: Long) {
- val database = databaseHelper.writableDatabase
- val row = wrap(mapOf( LokiAPIDatabase.publicKey to publicKey, LokiAPIDatabase.timestamp to newValue.toString() ))
- database.insertOrUpdate(sessionRequestSentTimestampTable, row, "${LokiAPIDatabase.publicKey} = ?", wrap(publicKey))
- }
-
- override fun getSessionRequestProcessedTimestamp(publicKey: String): Long? {
- val database = databaseHelper.readableDatabase
- return database.get(sessionRequestProcessedTimestampTable, "${LokiAPIDatabase.publicKey} = ?", wrap(publicKey)) { cursor ->
- cursor.getInt(LokiAPIDatabase.timestamp)
- }?.toLong()
- }
-
- override fun setSessionRequestProcessedTimestamp(publicKey: String, newValue: Long) {
- val database = databaseHelper.writableDatabase
- val row = wrap(mapOf(LokiAPIDatabase.publicKey to publicKey, LokiAPIDatabase.timestamp to newValue.toString()))
- database.insertOrUpdate(sessionRequestProcessedTimestampTable, row, "${LokiAPIDatabase.publicKey} = ?", wrap(publicKey))
- }
-
override fun getOpenGroupPublicKey(server: String): String? {
val database = databaseHelper.readableDatabase
return database.get(openGroupPublicKeyTable, "${LokiAPIDatabase.server} = ?", wrap(server)) { cursor ->
@@ -431,27 +369,6 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
database.insertOrUpdate(openGroupPublicKeyTable, row, "${LokiAPIDatabase.server} = ?", wrap(server))
}
- override fun getOpenGroupProfilePictureURL(group: Long, server: String): String? {
- val database = databaseHelper.readableDatabase
- val index = "$server.$group"
- return database.get(openGroupProfilePictureTable, "$publicChatID = ?", wrap(index)) { cursor ->
- cursor.getString(openGroupProfilePicture)
- }?.toString()
- }
-
- override fun setOpenGroupProfilePictureURL(group: Long, server: String, newValue: String) {
- val database = databaseHelper.writableDatabase
- val index = "$server.$group"
- val row = wrap(mapOf(publicChatID to index, openGroupProfilePicture to newValue))
- database.insertOrUpdate(openGroupProfilePictureTable, row, "$publicChatID = ?", wrap(index))
- }
-
- fun clearOpenGroupProfilePictureURL(group: Long, server: String): Boolean {
- val database = databaseHelper.writableDatabase
- val index = "$server.$group"
- return database.delete(openGroupProfilePictureTable, "$publicChatID = ?", arrayOf(index)) > 0
- }
-
override fun getLastSnodePoolRefreshDate(): Date? {
val time = TextSecurePreferences.getLastSnodePoolRefreshDate(context)
if (time <= 0) { return null }
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt
index bc2d71f7c6..83e64f884c 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt
@@ -37,11 +37,6 @@ class LokiMessageDatabase(context: Context, helper: SQLCipherOpenHelper) : Datab
}
- override fun getQuoteServerID(quoteID: Long, quoteePublicKey: String): Long? {
- val message = DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(quoteID, quoteePublicKey)
- return if (message != null) getServerID(message.getId(), !message.isMms) else null
- }
-
fun getServerID(messageID: Long): Long? {
val database = databaseHelper.readableDatabase
return database.get(messageIDTable, "${Companion.messageID} = ?", arrayOf(messageID.toString())) { cursor ->
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiUserDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiUserDatabase.kt
index 1a7efd48ff..fba0d64b36 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiUserDatabase.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiUserDatabase.kt
@@ -1,19 +1,12 @@
package org.thoughtcrime.securesms.loki.database
-import android.content.ContentValues
import android.content.Context
-import android.database.sqlite.SQLiteDatabase
-import org.session.libsignal.utilities.Log
-import org.session.libsession.utilities.Address
import org.thoughtcrime.securesms.database.Database
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
import org.thoughtcrime.securesms.loki.utilities.get
-import org.thoughtcrime.securesms.loki.utilities.insertOrUpdate
-import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.TextSecurePreferences
-import org.session.libsignal.database.LokiUserDatabaseProtocol
-class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiUserDatabaseProtocol {
+class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) {
companion object {
// Shared
@@ -28,7 +21,7 @@ class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database
@JvmStatic val createServerDisplayNameTableCommand = "CREATE TABLE $serverDisplayNameTable ($publicKey TEXT, $serverID TEXT, $displayName TEXT, PRIMARY KEY ($publicKey, $serverID));"
}
- override fun getDisplayName(publicKey: String): String? {
+ fun getDisplayName(publicKey: String): String? {
if (publicKey == TextSecurePreferences.getLocalNumber(context)) {
return TextSecurePreferences.getProfileName(context)
} else {
@@ -44,21 +37,4 @@ class LokiUserDatabase(context: Context, helper: SQLCipherOpenHelper) : Database
}
}
}
-
- fun setDisplayName(publicKey: String, displayName: String) {
- val database = databaseHelper.writableDatabase
- val row = ContentValues(2)
- row.put(Companion.publicKey, publicKey)
- row.put(Companion.displayName, displayName)
- database.insertOrUpdate(displayNameTable, row, "${Companion.publicKey} = ?", arrayOf( publicKey ))
- Recipient.from(context, Address.fromSerialized(publicKey), false).notifyListeners()
- }
-
- override fun getProfilePictureURL(publicKey: String): String? {
- return if (publicKey == TextSecurePreferences.getLocalNumber(context)) {
- TextSecurePreferences.getProfilePictureURL(context)
- } else {
- Recipient.from(context, Address.fromSerialized(publicKey), false).resolve().profileAvatar
- }
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/SessionContactDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/SessionContactDatabase.kt
new file mode 100644
index 0000000000..7d5e93b502
--- /dev/null
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/SessionContactDatabase.kt
@@ -0,0 +1,81 @@
+package org.thoughtcrime.securesms.loki.database
+
+import android.content.ContentValues
+import android.content.Context
+import net.sqlcipher.Cursor
+import org.session.libsession.messaging.contacts.Contact
+import org.session.libsignal.utilities.Base64
+import org.thoughtcrime.securesms.database.Database
+import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
+import org.thoughtcrime.securesms.loki.utilities.*
+
+class SessionContactDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) {
+
+ companion object {
+ private const val sessionContactTable = "session_contact_database"
+ const val sessionID = "session_id"
+ const val name = "name"
+ const val nickname = "nickname"
+ const val profilePictureURL = "profile_picture_url"
+ const val profilePictureFileName = "profile_picture_file_name"
+ const val profilePictureEncryptionKey = "profile_picture_encryption_key"
+ const val threadID = "thread_id"
+ const val isTrusted = "is_trusted"
+ @JvmStatic val createSessionContactTableCommand =
+ "CREATE TABLE $sessionContactTable " +
+ "($sessionID STRING PRIMARY KEY, " +
+ "$name TEXT DEFAULT NULL, " +
+ "$nickname TEXT DEFAULT NULL, " +
+ "$profilePictureURL TEXT DEFAULT NULL, " +
+ "$profilePictureFileName TEXT DEFAULT NULL, " +
+ "$profilePictureEncryptionKey BLOB DEFAULT NULL, " +
+ "$threadID INTEGER DEFAULT -1, " +
+ "$isTrusted INTEGER DEFAULT 0);"
+ }
+
+ fun getContactWithSessionID(sessionID: String): Contact? {
+ val database = databaseHelper.readableDatabase
+ return database.get(sessionContactTable, "${SessionContactDatabase.sessionID} = ?", arrayOf( sessionID )) { cursor ->
+ contactFromCursor(cursor)
+ }
+ }
+
+ fun getAllContacts(): Set {
+ val database = databaseHelper.readableDatabase
+ return database.getAll(sessionContactTable, null, null) { cursor ->
+ contactFromCursor(cursor)
+ }.toSet()
+ }
+
+ fun setContact(contact: Contact) {
+ val database = databaseHelper.writableDatabase
+ val contentValues = ContentValues(8)
+ contentValues.put(sessionID, contact.sessionID)
+ contentValues.put(name, contact.name)
+ contentValues.put(nickname, contact.nickname)
+ contentValues.put(profilePictureURL, contact.profilePictureURL)
+ contentValues.put(profilePictureFileName, contact.profilePictureFileName)
+ contact.profilePictureEncryptionKey?.let {
+ contentValues.put(profilePictureEncryptionKey, Base64.encodeBytes(it))
+ }
+ contentValues.put(threadID, threadID)
+ contentValues.put(isTrusted, if (contact.isTrusted) 1 else 0)
+ database.insertOrUpdate(sessionContactTable, contentValues, "$sessionID = ?", arrayOf( contact.sessionID ))
+ notifyConversationListListeners()
+ }
+
+ private fun contactFromCursor(cursor: Cursor): Contact {
+ val sessionID = cursor.getString(sessionID)
+ val contact = Contact(sessionID)
+ contact.name = cursor.getStringOrNull(name)
+ contact.nickname = cursor.getStringOrNull(nickname)
+ contact.profilePictureURL = cursor.getStringOrNull(profilePictureURL)
+ contact.profilePictureFileName = cursor.getStringOrNull(profilePictureFileName)
+ cursor.getStringOrNull(profilePictureEncryptionKey)?.let {
+ contact.profilePictureEncryptionKey = Base64.decode(it)
+ }
+ contact.threadID = cursor.getLong(threadID)
+ contact.isTrusted = cursor.getInt(isTrusted) != 0
+ return contact
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/UserDetailsBottomSheet.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/UserDetailsBottomSheet.kt
index 3d884f7440..c020fc3aee 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/UserDetailsBottomSheet.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/dialogs/UserDetailsBottomSheet.kt
@@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.loki.dialogs
+import android.annotation.SuppressLint
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
@@ -8,14 +9,19 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.inputmethod.EditorInfo
+import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import kotlinx.android.synthetic.main.fragment_user_details_bottom_sheet.*
-import kotlinx.android.synthetic.main.view_conversation.view.*
import network.loki.messenger.R
+import org.session.libsession.messaging.contacts.Contact
+import org.session.libsession.utilities.Address
+import org.session.libsession.utilities.recipients.Recipient
+import org.session.libsession.utilities.SSKEnvironment
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.mms.GlideApp
-public class UserDetailsBottomSheet : BottomSheetDialogFragment() {
+class UserDetailsBottomSheet : BottomSheetDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_user_details_bottom_sheet, container, false)
@@ -24,11 +30,38 @@ public class UserDetailsBottomSheet : BottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val publicKey = arguments?.getString("publicKey") ?: return dismiss()
+ val recipient = Recipient.from(requireContext(), Address.fromSerialized(publicKey), false)
profilePictureView.publicKey = publicKey
profilePictureView.glide = GlideApp.with(this)
profilePictureView.isLarge = true
profilePictureView.update()
- nameTextView.text = DatabaseFactory.getLokiUserDatabase(requireContext()).getDisplayName(publicKey) ?: "Anonymous"
+ nameTextViewContainer.visibility = View.VISIBLE
+ nameTextViewContainer.setOnClickListener {
+ nameTextViewContainer.visibility = View.INVISIBLE
+ nameEditTextContainer.visibility = View.VISIBLE
+ nicknameEditText.text = null
+ nicknameEditText.requestFocus()
+ showSoftKeyboard()
+ }
+ cancelNicknameEditingButton.setOnClickListener {
+ nicknameEditText.clearFocus()
+ hideSoftKeyboard()
+ nameTextViewContainer.visibility = View.VISIBLE
+ nameEditTextContainer.visibility = View.INVISIBLE
+ }
+ saveNicknameButton.setOnClickListener {
+ saveNickName(recipient)
+ }
+ nicknameEditText.setOnEditorActionListener { _, actionId, _ ->
+ when (actionId) {
+ EditorInfo.IME_ACTION_DONE -> {
+ saveNickName(recipient)
+ return@setOnEditorActionListener true
+ }
+ else -> return@setOnEditorActionListener false
+ }
+ }
+ nameTextView.text = recipient.name ?: publicKey // Uses the Contact API internally
publicKeyTextView.text = publicKey
copyButton.setOnClickListener {
val clipboard = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
@@ -37,4 +70,32 @@ public class UserDetailsBottomSheet : BottomSheetDialogFragment() {
Toast.makeText(requireContext(), R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show()
}
}
+
+ fun saveNickName(recipient: Recipient) {
+ nicknameEditText.clearFocus()
+ hideSoftKeyboard()
+ nameTextViewContainer.visibility = View.VISIBLE
+ nameEditTextContainer.visibility = View.INVISIBLE
+ var newNickName: String? = null
+ if (nicknameEditText.text.isNotEmpty()) {
+ newNickName = nicknameEditText.text.toString()
+ }
+ val publicKey = recipient.address.serialize()
+ val contactDB = DatabaseFactory.getSessionContactDatabase(context)
+ val contact = contactDB.getContactWithSessionID(publicKey) ?: Contact(publicKey)
+ contact.nickname = newNickName
+ contactDB.setContact(contact)
+ nameTextView.text = recipient.name ?: publicKey // Uses the Contact API internally
+ }
+
+ @SuppressLint("ServiceCast")
+ fun showSoftKeyboard() {
+ val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
+ imm?.showSoftInput(nicknameEditText, 0)
+ }
+
+ fun hideSoftKeyboard() {
+ val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
+ imm?.hideSoftInputFromWindow(nicknameEditText.windowToken, 0)
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt
index b270cdecf6..1f8bdca7ad 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionMetaProtocol.kt
@@ -1,15 +1,8 @@
package org.thoughtcrime.securesms.loki.protocol
-import android.content.Context
-import org.thoughtcrime.securesms.ApplicationContext
import org.session.libsession.utilities.Address
-import org.thoughtcrime.securesms.database.DatabaseFactory
-import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob
import org.session.libsession.utilities.recipients.Recipient
-import org.session.libsession.utilities.TextSecurePreferences
-import org.session.libsignal.messages.SignalServiceContent
import org.session.libsignal.messages.SignalServiceDataMessage
-import java.security.MessageDigest
object SessionMetaProtocol {
@@ -39,19 +32,6 @@ object SessionMetaProtocol {
return shouldIgnoreMessage
}
- @JvmStatic
- fun handleProfileUpdateIfNeeded(context: Context, content: SignalServiceContent) {
- val displayName = content.senderDisplayName.orNull() ?: return
- if (displayName.isBlank()) { return }
- val userPublicKey = TextSecurePreferences.getLocalNumber(context)
- val sender = content.sender.toLowerCase()
- if (userPublicKey == sender) {
- // Update the user's local name if the message came from their master device
- TextSecurePreferences.setProfileName(context, displayName)
- }
- DatabaseFactory.getLokiUserDatabase(context).setDisplayName(sender, displayName)
- }
-
@JvmStatic
fun canUserReplyToNotification(recipient: Recipient): Boolean {
// TODO return !recipient.address.isRSSFeed
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/DatabaseUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/DatabaseUtilities.kt
index 140586930f..23834fb9af 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/DatabaseUtilities.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/DatabaseUtilities.kt
@@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.loki.utilities
import android.content.ContentValues
+import androidx.core.database.getStringOrNull
import net.sqlcipher.Cursor
import net.sqlcipher.database.SQLiteDatabase
import org.session.libsignal.utilities.Base64
@@ -56,4 +57,8 @@ fun Cursor.getLong(columnName: String): Long {
fun Cursor.getBase64EncodedData(columnName: String): ByteArray {
return Base64.decode(getString(columnName))
+}
+
+fun Cursor.getStringOrNull(columnName: String): String? {
+ return getStringOrNull(getColumnIndexOrThrow(columnName))
}
\ No newline at end of file
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt
index faef8f0cc3..000b61db89 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt
@@ -15,7 +15,7 @@ object MentionManagerUtilities {
val members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.address.toGroupString(), false).map { it.address.serialize() }
result.addAll(members)
} else {
- if (MentionsManager.shared.userPublicKeyCache[threadID] != null) { return }
+ if (MentionsManager.userPublicKeyCache[threadID] != null) { return }
val messageDatabase = DatabaseFactory.getMmsSmsDatabase(context)
val reader = messageDatabase.readerFor(messageDatabase.getConversation(threadID))
var record: MessageRecord? = reader.next
@@ -30,6 +30,6 @@ object MentionManagerUtilities {
reader.close()
result.add(TextSecurePreferences.getLocalNumber(context)!!)
}
- MentionsManager.shared.userPublicKeyCache[threadID] = result
+ MentionsManager.userPublicKeyCache[threadID] = result
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionUtilities.kt
index 300d5466a0..45fda301d8 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionUtilities.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionUtilities.kt
@@ -9,6 +9,7 @@ import android.text.style.StyleSpan
import android.util.Range
import network.loki.messenger.R
import nl.komponents.kovenant.combine.Tuple2
+import org.session.libsession.messaging.contacts.Contact
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.session.libsession.utilities.TextSecurePreferences
import java.util.regex.Pattern
@@ -23,6 +24,8 @@ object MentionUtilities {
@JvmStatic
fun highlightMentions(text: CharSequence, isOutgoingMessage: Boolean, threadID: Long, context: Context): SpannableString {
var text = text
+ val threadDB = DatabaseFactory.getThreadDatabase(context)
+ val isOpenGroup = threadDB.getRecipientForThreadId(threadID)?.isOpenGroupRecipient ?: false
val pattern = Pattern.compile("@[0-9a-fA-F]*")
var matcher = pattern.matcher(text)
val mentions = mutableListOf, String>>()
@@ -31,10 +34,12 @@ object MentionUtilities {
if (matcher.find(startIndex)) {
while (true) {
val publicKey = text.subSequence(matcher.start() + 1, matcher.end()).toString() // +1 to get rid of the @
- val userDisplayName: String? = if (publicKey.toLowerCase() == userPublicKey.toLowerCase()) {
+ val userDisplayName: String? = if (publicKey.equals(userPublicKey, ignoreCase = true)) {
TextSecurePreferences.getProfileName(context)
} else {
- DatabaseFactory.getLokiUserDatabase(context).getDisplayName(publicKey)
+ val contact = DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(publicKey)
+ val context = if (isOpenGroup) Contact.ContactContext.OPEN_GROUP else Contact.ContactContext.REGULAR
+ contact?.displayName(context)
}
if (userDisplayName != null) {
text = text.subSequence(0, matcher.start()).toString() + "@" + userDisplayName + text.subSequence(matcher.end(), text.length)
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/NotificationUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/NotificationUtilities.kt
deleted file mode 100644
index ad3d35f809..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/NotificationUtilities.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-@file:JvmName("NotificationUtilities")
-package org.thoughtcrime.securesms.loki.utilities
-
-import android.content.Context
-import org.thoughtcrime.securesms.database.DatabaseFactory
-import org.session.libsession.utilities.recipients.Recipient
-
-fun getOpenGroupDisplayName(recipient: Recipient, threadRecipient: Recipient, context: Context): String {
- val publicKey = recipient.address.toString()
- val displayName = DatabaseFactory.getLokiUserDatabase(context).getDisplayName(publicKey)
- // FIXME: Add short ID here?
- return displayName ?: publicKey
-}
\ No newline at end of file
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt
index e1a308b645..efbaa24dbd 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt
@@ -2,13 +2,15 @@ package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.graphics.Typeface
-import android.text.TextUtils
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.view_conversation.view.*
import network.loki.messenger.R
+import org.session.libsession.messaging.contacts.Contact
+import org.session.libsession.utilities.recipients.Recipient
+import org.session.libsession.utilities.SSKEnvironment
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities.populateUserPublicKeyCacheIfNeeded
@@ -56,7 +58,7 @@ class ConversationView : LinearLayout {
}
profilePictureView.glide = glide
profilePictureView.update(thread.recipient, thread.threadId)
- val senderDisplayName = if (thread.recipient.isLocalNumber) context.getString(R.string.note_to_self) else if (!thread.recipient.name.isNullOrEmpty()) thread.recipient.name else thread.recipient.address.toString()
+ val senderDisplayName = getUserDisplayName(thread.recipient) ?: thread.recipient.address.toString()
btnGroupNameDisplay.text = senderDisplayName
timestampTextView.text = DateUtils.getBriefRelativeTimeSpanString(context, Locale.getDefault(), thread.date)
muteIndicatorImageView.visibility = if (thread.recipient.isMuted) VISIBLE else GONE
@@ -85,9 +87,12 @@ class ConversationView : LinearLayout {
profilePictureView.recycle()
}
- private fun getUserDisplayName(publicKey: String?): String? {
- if (TextUtils.isEmpty(publicKey)) return null
- return DatabaseFactory.getLokiUserDatabase(context).getDisplayName(publicKey!!)
+ private fun getUserDisplayName(recipient: Recipient): String? {
+ if (recipient.isLocalNumber) {
+ return context.getString(R.string.note_to_self)
+ } else {
+ return recipient.name // Internally uses the Contact API
+ }
}
// endregion
}
\ No newline at end of file
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt
index 2226e9ef8b..e2de25ca90 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt
@@ -11,6 +11,7 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
import kotlinx.android.synthetic.main.view_profile_picture.view.*
import network.loki.messenger.R
import org.session.libsession.avatars.ProfileContactPhoto
+import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.mentions.MentionsManager
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.recipients.Recipient
@@ -57,19 +58,15 @@ class ProfilePictureView : RelativeLayout {
// region Updating
fun update(recipient: Recipient, threadID: Long) {
- fun getUserDisplayName(publicKey: String?): String? {
- if (publicKey == null || publicKey.isBlank()) {
- return null
- } else {
- val result = DatabaseFactory.getLokiUserDatabase(context).getDisplayName(publicKey)
- return result ?: publicKey
- }
+ fun getUserDisplayName(publicKey: String): String {
+ val contact = DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(publicKey)
+ return contact?.displayName(Contact.ContactContext.REGULAR) ?: publicKey
}
fun isOpenGroupWithProfilePicture(recipient: Recipient): Boolean {
return recipient.isOpenGroupRecipient && recipient.groupAvatarId != null
}
if (recipient.isGroupRecipient && !isOpenGroupWithProfilePicture(recipient)) {
- val users = MentionsManager.shared.userPublicKeyCache[threadID]?.toMutableList() ?: mutableListOf()
+ val users = MentionsManager.userPublicKeyCache[threadID]?.toMutableList() ?: mutableListOf()
users.remove(TextSecurePreferences.getLocalNumber(context))
val randomUsers = users.sorted().toMutableList() // Sort to provide a level of stability
if (users.count() == 1) {
@@ -86,7 +83,8 @@ class ProfilePictureView : RelativeLayout {
recipient.name == "Session Updates" ||
recipient.name == "Session Public Chat"
} else {
- publicKey = recipient.address.toString()
+ val publicKey = recipient.address.toString()
+ this.publicKey = publicKey
displayName = getUserDisplayName(publicKey)
additionalPublicKey = null
isRSSFeed = false
diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/UserView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/UserView.kt
index 4e35ba1869..7dae953974 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/UserView.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/UserView.kt
@@ -8,6 +8,7 @@ import android.widget.LinearLayout
import kotlinx.android.synthetic.main.view_conversation.view.profilePictureView
import kotlinx.android.synthetic.main.view_user.view.*
import network.loki.messenger.R
+import org.session.libsession.messaging.contacts.Contact
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities
import org.thoughtcrime.securesms.mms.GlideRequests
@@ -48,13 +49,9 @@ class UserView : LinearLayout {
// region Updating
fun bind(user: Recipient, glide: GlideRequests, actionIndicator: ActionIndicator, isSelected: Boolean = false) {
- fun getUserDisplayName(publicKey: String?): String? {
- if (publicKey == null || publicKey.isBlank()) {
- return null
- } else {
- val result = DatabaseFactory.getLokiUserDatabase(context).getDisplayName(publicKey)
- return result ?: publicKey
- }
+ fun getUserDisplayName(publicKey: String): String {
+ val contact = DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(publicKey)
+ return contact?.displayName(Contact.ContactContext.REGULAR) ?: publicKey
}
val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(user)
MentionManagerUtilities.populateUserPublicKeyCacheIfNeeded(threadID, context) // FIXME: This is a bad place to do this
diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java
index 9527282d39..f094cea12c 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MultipleRecipientNotificationBuilder.java
@@ -8,14 +8,14 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import android.text.SpannableStringBuilder;
-
+import org.session.libsession.messaging.contacts.Contact;
+import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.loki.activities.HomeActivity;
-import org.thoughtcrime.securesms.loki.utilities.NotificationUtilities;
+import org.thoughtcrime.securesms.loki.database.SessionContactDatabase;
import org.session.libsession.utilities.NotificationPrivacyPreference;
import org.session.libsession.utilities.recipients.Recipient;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
-
import java.util.LinkedList;
import java.util.List;
@@ -49,8 +49,15 @@ public class MultipleRecipientNotificationBuilder extends AbstractNotificationBu
public void setMostRecentSender(Recipient recipient, Recipient threadRecipient) {
String displayName = recipient.toShortString();
- if (threadRecipient.isGroupRecipient()) {
- displayName = NotificationUtilities.getOpenGroupDisplayName(recipient, threadRecipient, context);
+ if (threadRecipient.isOpenGroupRecipient()) {
+ SessionContactDatabase contactDB = DatabaseFactory.getSessionContactDatabase(context);
+ String sessionID = recipient.getAddress().serialize();
+ Contact contact = contactDB.getContactWithSessionID(sessionID);
+ if (contact != null) {
+ displayName = contact.displayName(Contact.ContactContext.OPEN_GROUP);
+ } else {
+ displayName = sessionID;
+ }
}
if (privacy.isDisplayContact()) {
setContentText(context.getString(R.string.MessageNotifier_most_recent_from_s, displayName));
@@ -71,8 +78,15 @@ public class MultipleRecipientNotificationBuilder extends AbstractNotificationBu
public void addMessageBody(@NonNull Recipient sender, Recipient threadRecipient, @Nullable CharSequence body) {
String displayName = sender.toShortString();
- if (threadRecipient.isGroupRecipient()) {
- displayName = NotificationUtilities.getOpenGroupDisplayName(sender, threadRecipient, context);
+ if (threadRecipient.isOpenGroupRecipient()) {
+ SessionContactDatabase contactDB = DatabaseFactory.getSessionContactDatabase(context);
+ String sessionID = sender.getAddress().serialize();
+ Contact contact = contactDB.getContactWithSessionID(sessionID);
+ if (contact != null) {
+ displayName = contact.displayName(Contact.ContactContext.OPEN_GROUP);
+ } else {
+ displayName = sessionID;
+ }
}
if (privacy.isDisplayMessage()) {
SpannableStringBuilder builder = new SpannableStringBuilder();
diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java
index 0ed628034f..008779301b 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/SingleRecipientNotificationBuilder.java
@@ -15,22 +15,21 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.text.SpannableStringBuilder;
-
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationCompat.Action;
import androidx.core.app.RemoteInput;
-
import com.bumptech.glide.load.engine.DiskCacheStrategy;
-
import org.session.libsession.avatars.ContactColors;
import org.session.libsession.avatars.ContactPhoto;
import org.session.libsession.avatars.GeneratedContactPhoto;
+import org.session.libsession.messaging.contacts.Contact;
import org.session.libsignal.utilities.Log;
+import org.thoughtcrime.securesms.database.DatabaseFactory;
+import org.thoughtcrime.securesms.loki.database.SessionContactDatabase;
import org.thoughtcrime.securesms.loki.utilities.AvatarPlaceholderGenerator;
-import org.thoughtcrime.securesms.loki.utilities.NotificationUtilities;
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader;
import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.mms.Slide;
@@ -40,11 +39,9 @@ import org.session.libsession.utilities.recipients.Recipient;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.session.libsession.utilities.TextSecurePreferences;
import org.session.libsession.utilities.Util;
-
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
-
import network.loki.messenger.R;
public class SingleRecipientNotificationBuilder extends AbstractNotificationBuilder {
@@ -121,8 +118,16 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
{
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
- if (privacy.isDisplayContact() && threadRecipients.isGroupRecipient()) {
- String displayName = NotificationUtilities.getOpenGroupDisplayName(individualRecipient, threadRecipients, context);
+ if (privacy.isDisplayContact() && threadRecipients.isOpenGroupRecipient()) {
+ String displayName;
+ SessionContactDatabase contactDB = DatabaseFactory.getSessionContactDatabase(context);
+ String sessionID = individualRecipient.getAddress().serialize();
+ Contact contact = contactDB.getContactWithSessionID(sessionID);
+ if (contact != null) {
+ displayName = contact.displayName(Contact.ContactContext.OPEN_GROUP);
+ } else {
+ displayName = sessionID;
+ }
if (displayName != null) {
stringBuilder.append(Util.getBoldedString(displayName + ": "));
}
@@ -209,8 +214,16 @@ public class SingleRecipientNotificationBuilder extends AbstractNotificationBuil
{
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
- if (privacy.isDisplayContact() && threadRecipient.isGroupRecipient()) {
- String displayName = NotificationUtilities.getOpenGroupDisplayName(individualRecipient, threadRecipient, context);
+ if (privacy.isDisplayContact() && threadRecipient.isOpenGroupRecipient()) {
+ String displayName;
+ SessionContactDatabase contactDB = DatabaseFactory.getSessionContactDatabase(context);
+ String sessionID = individualRecipient.getAddress().serialize();
+ Contact contact = contactDB.getContactWithSessionID(sessionID);
+ if (contact != null) {
+ displayName = contact.displayName(Contact.ContactContext.OPEN_GROUP);
+ } else {
+ displayName = sessionID;
+ }
if (displayName != null) {
stringBuilder.append(Util.getBoldedString(displayName + ": "));
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt
index 7bb7970ea6..e7fdbc509f 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt
+++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt
@@ -1,22 +1,70 @@
package org.thoughtcrime.securesms.sskenvironment
import android.content.Context
+import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.SSKEnvironment
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob
-class ProfileManager: SSKEnvironment.ProfileManagerProtocol {
- override fun setDisplayName(context: Context, recipient: Recipient, displayName: String) {
- DatabaseFactory.getLokiUserDatabase(context).setDisplayName(recipient.address.serialize(), displayName)
+class ProfileManager : SSKEnvironment.ProfileManagerProtocol {
+
+ override fun setNickname(context: Context, recipient: Recipient, nickname: String?) {
+ val sessionID = recipient.address.serialize()
+ val contactDatabase = DatabaseFactory.getSessionContactDatabase(context)
+ var contact = contactDatabase.getContactWithSessionID(sessionID)
+ if (contact == null) contact = Contact(sessionID)
+ contact.threadID = DatabaseFactory.getStorage(context).getThreadId(recipient.address)
+ if (contact.nickname != nickname) {
+ contact.nickname = nickname
+ contactDatabase.setContact(contact)
+ }
+ }
+
+ override fun setName(context: Context, recipient: Recipient, name: String) {
+ // New API
+ val sessionID = recipient.address.serialize()
+ val contactDatabase = DatabaseFactory.getSessionContactDatabase(context)
+ var contact = contactDatabase.getContactWithSessionID(sessionID)
+ if (contact == null) contact = Contact(sessionID)
+ contact.threadID = DatabaseFactory.getStorage(context).getThreadId(recipient.address)
+ if (contact.name != name) {
+ contact.name = name
+ contactDatabase.setContact(contact)
+ }
+ // Old API
+ val database = DatabaseFactory.getRecipientDatabase(context)
+ database.setProfileName(recipient, name)
+ recipient.notifyListeners()
}
override fun setProfilePictureURL(context: Context, recipient: Recipient, profilePictureURL: String) {
- ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(recipient, profilePictureURL))
+ val job = RetrieveProfileAvatarJob(recipient, profilePictureURL)
+ ApplicationContext.getInstance(context).jobManager.add(job)
+ val sessionID = recipient.address.serialize()
+ val contactDatabase = DatabaseFactory.getSessionContactDatabase(context)
+ var contact = contactDatabase.getContactWithSessionID(sessionID)
+ if (contact == null) contact = Contact(sessionID)
+ contact.threadID = DatabaseFactory.getStorage(context).getThreadId(recipient.address)
+ if (contact.profilePictureURL != profilePictureURL) {
+ contact.profilePictureURL = profilePictureURL
+ contactDatabase.setContact(contact)
+ }
}
override fun setProfileKey(context: Context, recipient: Recipient, profileKey: ByteArray) {
+ // New API
+ val sessionID = recipient.address.serialize()
+ val contactDatabase = DatabaseFactory.getSessionContactDatabase(context)
+ var contact = contactDatabase.getContactWithSessionID(sessionID)
+ if (contact == null) contact = Contact(sessionID)
+ contact.threadID = DatabaseFactory.getStorage(context).getThreadId(recipient.address)
+ if (!contact.profilePictureEncryptionKey.contentEquals(profileKey)) {
+ contact.profilePictureEncryptionKey = profileKey
+ contactDatabase.setContact(contact)
+ }
+ // Old API
val database = DatabaseFactory.getRecipientDatabase(context)
database.setProfileKey(recipient, profileKey)
}
diff --git a/app/src/main/res/layout/conversation_activity.xml b/app/src/main/res/layout/conversation_activity.xml
index ba9f7f27e1..e261a8f384 100644
--- a/app/src/main/res/layout/conversation_activity.xml
+++ b/app/src/main/res/layout/conversation_activity.xml
@@ -55,6 +55,7 @@
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:background="@null"
android:maxLines="1"
android:ellipsize="end"
android:text="Conversation"
diff --git a/app/src/main/res/layout/fragment_user_details_bottom_sheet.xml b/app/src/main/res/layout/fragment_user_details_bottom_sheet.xml
index 705317e32d..993e05615f 100644
--- a/app/src/main/res/layout/fragment_user_details_bottom_sheet.xml
+++ b/app/src/main/res/layout/fragment_user_details_bottom_sheet.xml
@@ -16,25 +16,95 @@
android:id="@+id/profilePictureView"
android:layout_width="@dimen/large_profile_picture_size"
android:layout_height="@dimen/large_profile_picture_size"
- android:layout_marginTop="@dimen/large_spacing" />
+ android:layout_marginTop="@dimen/large_spacing"/>
-
+ android:gravity="center">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a6244533f0..8c325d6787 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -813,8 +813,10 @@
Select a file
Select a backup file and enter the passphrase it was created with.
30-digit passphrase
-
+
This is taking a while, would you like to skip?
Or join one of theseā¦
+ Enter a nickname
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index dd6d4fc576..3a798194c2 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -137,7 +137,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/libsession/src/main/res/values/themes.xml b/libsession/src/main/res/values/themes.xml
deleted file mode 100644
index 4239aebee4..0000000000
--- a/libsession/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,294 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/libsignal/src/main/java/org/session/libsignal/database/LokiAPIDatabaseProtocol.kt b/libsignal/src/main/java/org/session/libsignal/database/LokiAPIDatabaseProtocol.kt
index 4202c34741..2390b29768 100644
--- a/libsignal/src/main/java/org/session/libsignal/database/LokiAPIDatabaseProtocol.kt
+++ b/libsignal/src/main/java/org/session/libsignal/database/LokiAPIDatabaseProtocol.kt
@@ -19,24 +19,14 @@ interface LokiAPIDatabaseProtocol {
fun setReceivedMessageHashValues(publicKey: String, newValue: Set)
fun getAuthToken(server: String): String?
fun setAuthToken(server: String, newValue: String?)
- fun getLastMessageServerID(group: Long, server: String): Long?
- fun setLastMessageServerID(group: Long, server: String, newValue: Long)
- fun getLastDeletionServerID(group: Long, server: String): Long?
- fun setLastDeletionServerID(group: Long, server: String, newValue: Long)
fun setUserCount(group: Long, server: String, newValue: Int)
+ fun setUserCount(room: String, server: String, newValue: Int)
fun getLastMessageServerID(room: String, server: String): Long?
fun setLastMessageServerID(room: String, server: String, newValue: Long)
fun getLastDeletionServerID(room: String, server: String): Long?
fun setLastDeletionServerID(room: String, server: String, newValue: Long)
- fun setUserCount(room: String, server: String, newValue: Int)
- fun getSessionRequestSentTimestamp(publicKey: String): Long?
- fun setSessionRequestSentTimestamp(publicKey: String, newValue: Long)
- fun getSessionRequestProcessedTimestamp(publicKey: String): Long?
- fun setSessionRequestProcessedTimestamp(publicKey: String, newValue: Long)
fun getOpenGroupPublicKey(server: String): String?
fun setOpenGroupPublicKey(server: String, newValue: String)
- fun setOpenGroupProfilePictureURL(group: Long, server: String, newValue: String)
- fun getOpenGroupProfilePictureURL(group: Long, server: String): String?
fun getLastSnodePoolRefreshDate(): Date?
fun setLastSnodePoolRefreshDate(newValue: Date)
fun getUserX25519KeyPair(): ECKeyPair
diff --git a/libsignal/src/main/java/org/session/libsignal/database/LokiMessageDatabaseProtocol.kt b/libsignal/src/main/java/org/session/libsignal/database/LokiMessageDatabaseProtocol.kt
index e7c740f6b4..633471bf5e 100644
--- a/libsignal/src/main/java/org/session/libsignal/database/LokiMessageDatabaseProtocol.kt
+++ b/libsignal/src/main/java/org/session/libsignal/database/LokiMessageDatabaseProtocol.kt
@@ -2,6 +2,5 @@ package org.session.libsignal.database
interface LokiMessageDatabaseProtocol {
- fun getQuoteServerID(quoteID: Long, quoteePublicKey: String): Long?
fun setServerID(messageID: Long, serverID: Long, isSms: Boolean)
}
diff --git a/libsignal/src/main/java/org/session/libsignal/database/LokiUserDatabaseProtocol.kt b/libsignal/src/main/java/org/session/libsignal/database/LokiUserDatabaseProtocol.kt
deleted file mode 100644
index e22ecb1059..0000000000
--- a/libsignal/src/main/java/org/session/libsignal/database/LokiUserDatabaseProtocol.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.session.libsignal.database
-
-interface LokiUserDatabaseProtocol {
-
- fun getDisplayName(publicKey: String): String?
- fun getProfilePictureURL(publicKey: String): String?
-}