mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-21 10:51:36 +00:00
Public chat avatar handling.
Fix note to self.
This commit is contained in:
parent
0cefac1bce
commit
280d866df3
@ -43,6 +43,8 @@ import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
|||||||
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||||
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
|
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
|
||||||
|
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
|
||||||
|
import org.thoughtcrime.securesms.database.Address;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseContentProviders;
|
import org.thoughtcrime.securesms.database.DatabaseContentProviders;
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||||
import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule;
|
import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule;
|
||||||
@ -75,6 +77,7 @@ import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
|||||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||||
import org.thoughtcrime.securesms.providers.BlobProvider;
|
import org.thoughtcrime.securesms.providers.BlobProvider;
|
||||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
|
import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
|
||||||
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
|
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
|
||||||
import org.thoughtcrime.securesms.service.IncomingMessageObserver;
|
import org.thoughtcrime.securesms.service.IncomingMessageObserver;
|
||||||
@ -207,6 +210,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
|||||||
checkNeedsRevocation();
|
checkNeedsRevocation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
updatePublicChatProfileAvatarIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -597,6 +601,26 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
|||||||
if (lokiNewsFeedPoller != null) lokiNewsFeedPoller.startIfNeeded();
|
if (lokiNewsFeedPoller != null) lokiNewsFeedPoller.startIfNeeded();
|
||||||
if (lokiMessengerUpdatesFeedPoller != null) lokiMessengerUpdatesFeedPoller.startIfNeeded();
|
if (lokiMessengerUpdatesFeedPoller != null) lokiMessengerUpdatesFeedPoller.startIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updatePublicChatProfileAvatarIfNeeded() {
|
||||||
|
AsyncTask.execute(() -> {
|
||||||
|
LokiPublicChatAPI publicChatAPI = getLokiPublicChatAPI();
|
||||||
|
if (publicChatAPI != null) {
|
||||||
|
byte[] profileKey = ProfileKeyUtil.getProfileKey(this);
|
||||||
|
String url = TextSecurePreferences.getProfileAvatarUrl(this);
|
||||||
|
String ourMasterDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(this);
|
||||||
|
if (ourMasterDevice != null) {
|
||||||
|
Recipient masterDevice = Recipient.from(this, Address.fromSerialized(ourMasterDevice), false).resolve();
|
||||||
|
profileKey = masterDevice.getProfileKey();
|
||||||
|
url = masterDevice.getProfileAvatar();
|
||||||
|
}
|
||||||
|
Set<String> servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers();
|
||||||
|
for (String server : servers) {
|
||||||
|
publicChatAPI.setProfileAvatar(server, profileKey, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
public void checkNeedsRevocation() {
|
public void checkNeedsRevocation() {
|
||||||
|
@ -67,6 +67,7 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@ -421,7 +422,9 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje
|
|||||||
|
|
||||||
// Upload was successful with this new profile key, we should set it so the other users know to re-fetch profiles
|
// Upload was successful with this new profile key, we should set it so the other users know to re-fetch profiles
|
||||||
ProfileKeyUtil.setEncodedProfileKey(context, newProfileKey);
|
ProfileKeyUtil.setEncodedProfileKey(context, newProfileKey);
|
||||||
// TODO: Update profile key in public chats here
|
|
||||||
|
// Update profile key on the public chat server
|
||||||
|
ApplicationContext.getInstance(context).updatePublicChatProfileAvatarIfNeeded();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d("Loki", "Failed to upload profile photo: " + e);
|
Log.d("Loki", "Failed to upload profile photo: " + e);
|
||||||
return false;
|
return false;
|
||||||
|
@ -120,24 +120,26 @@ public class AvatarImageView extends AppCompatImageView {
|
|||||||
|
|
||||||
public void setAvatar(@NonNull GlideRequests requestManager, @Nullable Recipient recipient, boolean quickContactEnabled) {
|
public void setAvatar(@NonNull GlideRequests requestManager, @Nullable Recipient recipient, boolean quickContactEnabled) {
|
||||||
if (recipient != null) {
|
if (recipient != null) {
|
||||||
RecipientContactPhoto photo = new RecipientContactPhoto(recipient);
|
if (recipient.isLocalNumber()) {
|
||||||
if (!photo.equals(recipientContactPhoto)) {
|
setImageDrawable(new ResourceContactPhoto(R.drawable.ic_note_to_self).asDrawable(getContext(), recipient.getColor().toAvatarColor(getContext()), inverted));
|
||||||
requestManager.clear(this);
|
} else {
|
||||||
recipientContactPhoto = photo;
|
RecipientContactPhoto photo = new RecipientContactPhoto(recipient);
|
||||||
|
if (!photo.equals(recipientContactPhoto)) {
|
||||||
|
requestManager.clear(this);
|
||||||
|
recipientContactPhoto = photo;
|
||||||
|
|
||||||
Drawable fallbackContactPhotoDrawable = recipient.isLocalNumber()
|
Drawable fallbackContactPhotoDrawable = photo.recipient.getFallbackContactPhotoDrawable(getContext(), inverted);
|
||||||
? new ResourceContactPhoto(R.drawable.ic_note_to_self).asDrawable(getContext(), recipient.getColor().toAvatarColor(getContext()), inverted)
|
|
||||||
: photo.recipient.getFallbackContactPhotoDrawable(getContext(), inverted);
|
|
||||||
|
|
||||||
if (photo.contactPhoto != null) {
|
if (photo.contactPhoto != null) {
|
||||||
requestManager.load(photo.contactPhoto)
|
requestManager.load(photo.contactPhoto)
|
||||||
.fallback(fallbackContactPhotoDrawable)
|
.fallback(fallbackContactPhotoDrawable)
|
||||||
.error(fallbackContactPhotoDrawable)
|
.error(fallbackContactPhotoDrawable)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
.circleCrop()
|
.circleCrop()
|
||||||
.into(this);
|
.into(this);
|
||||||
} else {
|
} else {
|
||||||
setImageDrawable(fallbackContactPhotoDrawable);
|
setImageDrawable(fallbackContactPhotoDrawable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -130,6 +130,7 @@ import org.whispersystems.signalservice.api.messages.shared.SharedContact;
|
|||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
import org.whispersystems.signalservice.loki.api.DeviceLinkingSession;
|
import org.whispersystems.signalservice.loki.api.DeviceLinkingSession;
|
||||||
import org.whispersystems.signalservice.loki.api.LokiAPI;
|
import org.whispersystems.signalservice.loki.api.LokiAPI;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI;
|
||||||
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
import org.whispersystems.signalservice.loki.api.LokiStorageAPI;
|
||||||
import org.whispersystems.signalservice.loki.api.PairingAuthorisation;
|
import org.whispersystems.signalservice.loki.api.PairingAuthorisation;
|
||||||
import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher;
|
import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher;
|
||||||
@ -146,6 +147,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -1442,6 +1444,11 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
|||||||
database.setUnidentifiedAccessMode(recipient, RecipientDatabase.UnidentifiedAccessMode.UNKNOWN);
|
database.setUnidentifiedAccessMode(recipient, RecipientDatabase.UnidentifiedAccessMode.UNKNOWN);
|
||||||
String url = content.senderProfileAvatarUrl.or("");
|
String url = content.senderProfileAvatarUrl.or("");
|
||||||
ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileAvatarJob(recipient, url));
|
ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileAvatarJob(recipient, url));
|
||||||
|
|
||||||
|
// Loki - If the recipient is our master device then we need to go and update our avatar mappings on the public chats
|
||||||
|
if (recipient.isOurMasterDevice()) {
|
||||||
|
ApplicationContext.getInstance(context).updatePublicChatProfileAvatarIfNeeded();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ class DisplayNameActivity : BaseActionBarActivity() {
|
|||||||
application.startRSSFeedPollersIfNeeded()
|
application.startRSSFeedPollersIfNeeded()
|
||||||
val servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers()
|
val servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers()
|
||||||
servers.forEach { publicChatAPI.setDisplayName(name, it) }
|
servers.forEach { publicChatAPI.setDisplayName(name, it) }
|
||||||
|
application.updatePublicChatProfileAvatarIfNeeded()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,9 +6,14 @@ import android.util.Log
|
|||||||
import nl.komponents.kovenant.Promise
|
import nl.komponents.kovenant.Promise
|
||||||
import nl.komponents.kovenant.functional.bind
|
import nl.komponents.kovenant.functional.bind
|
||||||
import nl.komponents.kovenant.then
|
import nl.komponents.kovenant.then
|
||||||
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
|
import org.thoughtcrime.securesms.database.Address
|
||||||
import org.thoughtcrime.securesms.database.DatabaseFactory
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase
|
||||||
import org.thoughtcrime.securesms.jobs.PushDecryptJob
|
import org.thoughtcrime.securesms.jobs.PushDecryptJob
|
||||||
|
import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
import org.whispersystems.libsignal.util.guava.Optional
|
import org.whispersystems.libsignal.util.guava.Optional
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer
|
||||||
@ -21,7 +26,9 @@ import org.whispersystems.signalservice.loki.api.LokiPublicChat
|
|||||||
import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI
|
import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI
|
||||||
import org.whispersystems.signalservice.loki.api.LokiPublicChatMessage
|
import org.whispersystems.signalservice.loki.api.LokiPublicChatMessage
|
||||||
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
|
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
|
||||||
|
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
|
||||||
import org.whispersystems.signalservice.loki.utilities.successBackground
|
import org.whispersystems.signalservice.loki.utilities.successBackground
|
||||||
|
import java.security.MessageDigest
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class LokiPublicChatPoller(private val context: Context, private val group: LokiPublicChat) {
|
class LokiPublicChatPoller(private val context: Context, private val group: LokiPublicChat) {
|
||||||
@ -155,6 +162,7 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki
|
|||||||
val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})"
|
val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})"
|
||||||
DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.hexEncodedPublicKey, senderDisplayName)
|
DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.hexEncodedPublicKey, senderDisplayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
val senderPublicKey = primaryDevice ?: message.hexEncodedPublicKey
|
val senderPublicKey = primaryDevice ?: message.hexEncodedPublicKey
|
||||||
val serviceDataMessage = getDataMessage(message)
|
val serviceDataMessage = getDataMessage(message)
|
||||||
val serviceContent = SignalServiceContent(serviceDataMessage, senderPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false)
|
val serviceContent = SignalServiceContent(serviceDataMessage, senderPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false)
|
||||||
@ -163,6 +171,25 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki
|
|||||||
} else {
|
} else {
|
||||||
PushDecryptJob(context).handleTextMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID))
|
PushDecryptJob(context).handleTextMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update profile avatar if needed
|
||||||
|
val senderRecipient = Recipient.from(context, Address.fromSerialized(senderPublicKey), false)
|
||||||
|
if (message.avatar != null && message.avatar!!.url.isNotEmpty()) {
|
||||||
|
val profileKey = message.avatar!!.profileKey
|
||||||
|
val url = message.avatar!!.url
|
||||||
|
if (senderRecipient.profileKey == null || !MessageDigest.isEqual(senderRecipient.profileKey, profileKey)) {
|
||||||
|
val database = DatabaseFactory.getRecipientDatabase(context)
|
||||||
|
database.setProfileKey(senderRecipient, profileKey)
|
||||||
|
ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(senderRecipient, url))
|
||||||
|
}
|
||||||
|
} else if (senderRecipient.profileAvatar.orEmpty().isNotEmpty()) {
|
||||||
|
// Unset the avatar if we had an avatar before and we're not friends with the person
|
||||||
|
val threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(senderRecipient)
|
||||||
|
val friendRequestStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadId)
|
||||||
|
if (friendRequestStatus != LokiThreadFriendRequestStatus.FRIENDS) {
|
||||||
|
ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(senderRecipient, ""))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fun processOutgoingMessage(message: LokiPublicChatMessage) {
|
fun processOutgoingMessage(message: LokiPublicChatMessage) {
|
||||||
val messageServerID = message.serverID ?: return
|
val messageServerID = message.serverID ?: return
|
||||||
@ -178,6 +205,19 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki
|
|||||||
} else {
|
} else {
|
||||||
PushDecryptJob(context).handleSynchronizeSentTextMessage(transcript)
|
PushDecryptJob(context).handleSynchronizeSentTextMessage(transcript)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loki - If we got a message from our master device then make sure our mappings stay in sync
|
||||||
|
val recipient = Recipient.from(context, Address.fromSerialized(message.hexEncodedPublicKey), false)
|
||||||
|
if (recipient.isOurMasterDevice && message.avatar != null) {
|
||||||
|
val profileKey = message.avatar!!.profileKey
|
||||||
|
val url = message.avatar!!.url
|
||||||
|
if (recipient.profileKey == null || !MessageDigest.isEqual(recipient.profileKey, profileKey)) {
|
||||||
|
val database = DatabaseFactory.getRecipientDatabase(context)
|
||||||
|
database.setProfileKey(recipient, profileKey)
|
||||||
|
database.setProfileAvatar(recipient, url)
|
||||||
|
ApplicationContext.getInstance(context).updatePublicChatProfileAvatarIfNeeded()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var userDevices = setOf<String>()
|
var userDevices = setOf<String>()
|
||||||
var uniqueDevices = setOf<String>()
|
var uniqueDevices = setOf<String>()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user