Improve message requests, add megaphone.

This commit is contained in:
Alex Hart
2020-02-19 18:08:34 -04:00
committed by Greyson Parrelli
parent dc689d325b
commit 9e5f64c431
83 changed files with 2406 additions and 735 deletions

View File

@@ -55,7 +55,8 @@ public class Recipient {
public static final Recipient UNKNOWN = new Recipient(RecipientId.UNKNOWN, new RecipientDetails());
private static final String TAG = Log.tag(Recipient.class);
private static final FallbackPhotoProvider DEFAULT_FALLBACK_PHOTO_PROVIDER = new FallbackPhotoProvider();
private static final String TAG = Log.tag(Recipient.class);
private final RecipientId id;
private final boolean resolving;
@@ -567,20 +568,28 @@ public class Recipient {
}
public @NonNull Drawable getFallbackContactPhotoDrawable(Context context, boolean inverted) {
return getFallbackContactPhoto().asDrawable(context, getColor().toAvatarColor(context), inverted);
return getFallbackContactPhotoDrawable(context, inverted, DEFAULT_FALLBACK_PHOTO_PROVIDER);
}
public @NonNull Drawable getSmallFallbackContactPhotoDrawable(Context context, boolean inverted) {
return getFallbackContactPhoto().asSmallDrawable(context, getColor().toAvatarColor(context), inverted);
public @NonNull Drawable getFallbackContactPhotoDrawable(Context context, boolean inverted, @Nullable FallbackPhotoProvider fallbackPhotoProvider) {
return getFallbackContactPhoto(Util.firstNonNull(fallbackPhotoProvider, DEFAULT_FALLBACK_PHOTO_PROVIDER)).asDrawable(context, getColor().toAvatarColor(context), inverted);
}
public @NonNull Drawable getSmallFallbackContactPhotoDrawable(Context context, boolean inverted, @Nullable FallbackPhotoProvider fallbackPhotoProvider) {
return getFallbackContactPhoto(Util.firstNonNull(fallbackPhotoProvider, DEFAULT_FALLBACK_PHOTO_PROVIDER)).asSmallDrawable(context, getColor().toAvatarColor(context), inverted);
}
public @NonNull FallbackContactPhoto getFallbackContactPhoto() {
if (localNumber) return new ResourceContactPhoto(R.drawable.ic_note_to_self);
if (isResolving()) return new TransparentContactPhoto();
else if (isGroupInternal()) return new ResourceContactPhoto(R.drawable.ic_group_outline_40, R.drawable.ic_group_outline_20, R.drawable.ic_group_large);
else if (isGroup()) return new ResourceContactPhoto(R.drawable.ic_group_outline_40, R.drawable.ic_group_outline_20, R.drawable.ic_group_large);
else if (!TextUtils.isEmpty(name)) return new GeneratedContactPhoto(name, R.drawable.ic_profile_outline_40);
else return new ResourceContactPhoto(R.drawable.ic_profile_outline_40, R.drawable.ic_profile_outline_20, R.drawable.ic_person_large);
return getFallbackContactPhoto(DEFAULT_FALLBACK_PHOTO_PROVIDER);
}
public @NonNull FallbackContactPhoto getFallbackContactPhoto(@NonNull FallbackPhotoProvider fallbackPhotoProvider) {
if (localNumber) return fallbackPhotoProvider.getPhotoForLocalNumber();
if (isResolving()) return fallbackPhotoProvider.getPhotoForResolvingRecipient();
else if (isGroupInternal()) return fallbackPhotoProvider.getPhotoForGroup();
else if (isGroup()) return fallbackPhotoProvider.getPhotoForGroup();
else if (!TextUtils.isEmpty(name)) return fallbackPhotoProvider.getPhotoForRecipientWithName(name);
else return fallbackPhotoProvider.getPhotoForRecipientWithoutName();
}
public @Nullable ContactPhoto getContactPhoto() {
@@ -734,6 +743,29 @@ public class Recipient {
return Objects.hash(id);
}
public static class FallbackPhotoProvider {
public @NonNull FallbackContactPhoto getPhotoForLocalNumber() {
return new ResourceContactPhoto(R.drawable.ic_note_34, R.drawable.ic_note_24);
}
public @NonNull FallbackContactPhoto getPhotoForResolvingRecipient() {
return new TransparentContactPhoto();
}
public @NonNull FallbackContactPhoto getPhotoForGroup() {
return new ResourceContactPhoto(R.drawable.ic_group_outline_34, R.drawable.ic_group_outline_20, R.drawable.ic_group_outline_48);
}
public @NonNull FallbackContactPhoto getPhotoForRecipientWithName(String name) {
return new GeneratedContactPhoto(name, R.drawable.ic_profile_outline_40);
}
public @NonNull FallbackContactPhoto getPhotoForRecipientWithoutName() {
return new ResourceContactPhoto(R.drawable.ic_profile_outline_40, R.drawable.ic_profile_outline_20, R.drawable.ic_profile_outline_48);
}
}
private static class MissingAddressError extends AssertionError {
}

View File

@@ -11,6 +11,8 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.GroupDatabase;
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase;
import org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.database.ThreadDatabase;
@@ -108,16 +110,55 @@ public class RecipientUtil {
ApplicationDependencies.getJobManager().add(new MultiDeviceBlockedUpdateJob());
}
@WorkerThread
public static boolean isThreadMessageRequestAccepted(@NonNull Context context, long threadId) {
if (!FeatureFlags.messageRequests()) {
return true;
}
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
Recipient recipient = threadDatabase.getRecipientForThreadId(threadId);
boolean hasSentSecureMessage = DatabaseFactory.getMmsSmsDatabase(context)
.getOutgoingSecureConversationCount(threadId) != 0;
boolean noSecureMessagesInThread = DatabaseFactory.getMmsSmsDatabase(context)
.getSecureConversationCount(threadId) == 0;
if (recipient == null || hasSentSecureMessage || noSecureMessagesInThread) {
return true;
}
Recipient resolved = recipient.resolve();
return resolved.isProfileSharing() || resolved.isSystemContact();
}
@WorkerThread
public static boolean isRecipientMessageRequestAccepted(@NonNull Context context, @Nullable Recipient recipient) {
if (recipient == null || !FeatureFlags.messageRequests()) return true;
Recipient resolved = recipient.resolve();
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
long threadId = threadDatabase.getThreadIdFor(resolved);
boolean hasSentMessage = threadDatabase.getLastSeenAndHasSent(threadId).second() == Boolean.TRUE;
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(resolved);
boolean hasSentMessage = DatabaseFactory.getMmsSmsDatabase(context)
.getOutgoingSecureConversationCount(threadId) != 0;
boolean noSecureMessagesInThread = DatabaseFactory.getMmsSmsDatabase(context)
.getSecureConversationCount(threadId) == 0;
return hasSentMessage || resolved.isProfileSharing() || resolved.isSystemContact();
return noSecureMessagesInThread || hasSentMessage || resolved.isProfileSharing() || resolved.isSystemContact();
}
@WorkerThread
public static void shareProfileIfFirstSecureMessage(@NonNull Context context, @NonNull Recipient recipient) {
if (!FeatureFlags.messageRequests()) {
return;
}
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient);
boolean firstMessage = DatabaseFactory.getMmsSmsDatabase(context)
.getOutgoingSecureConversationCount(threadId) == 0;
if (firstMessage) {
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient.getId(), true);
}
}
}