diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 4081e4b5cb..e8c9f184a1 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -57,6 +57,7 @@ import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.Pair; +import android.util.TypedValue; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuInflater; @@ -230,6 +231,7 @@ import org.thoughtcrime.securesms.util.views.Stub; import org.whispersystems.libsignal.InvalidMessageException; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.loki.api.LokiAPI; +import org.whispersystems.signalservice.loki.api.LokiPublicChat; import org.whispersystems.signalservice.loki.api.LokiStorageAPI; import org.whispersystems.signalservice.loki.api.PairingAuthorisation; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; @@ -445,6 +447,14 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity LokiAPIUtilities.INSTANCE.populateUserHexEncodedPublicKeyCacheIfNeeded(threadId, this); + LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); + if (publicChat != null) { + ApplicationContext.getInstance(this).getLokiPublicChatAPI().getUserCount(publicChat.getChannel(), publicChat.getServer()).success(integer -> { + updateSubtitleTextView(); + return Unit.INSTANCE; + }); + } + View rootView = findViewById(R.id.rootView); rootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> { int height = rootView.getRootView().getHeight() - rootView.getHeight(); @@ -3130,11 +3140,23 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } else if (recipient.isMuted()) { muteIndicatorImageView.setVisibility(View.VISIBLE); actionBarSubtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault())); - } else if (recipient.isGroupRecipient()) { - actionBarSubtitleTextView.setText("26 members"); + } else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Loki Messenger Updates") && !recipient.getName().equals("Loki News")) { + LokiPublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); + if (publicChat != null) { + Integer userCount = DatabaseFactory.getLokiAPIDatabase(this).getUserCount(publicChat.getChannel(), publicChat.getServer()); + if (userCount == null) { userCount = 0; } + if (userCount > 2500) { + actionBarSubtitleTextView.setText("2500+ members"); + } else { + actionBarSubtitleTextView.setText(userCount + " members"); + } + } else { + actionBarSubtitleTextView.setVisibility(View.GONE); + } } else { actionBarSubtitleTextView.setVisibility(View.GONE); } + titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension((actionBarSubtitleTextView.getVisibility() == View.GONE) ? R.dimen.very_large_font_size : R.dimen.large_font_size)); } private void setMessageStatusProgressAnimatedIfPossible(int progress) { diff --git a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 2cf4269ca9..138505d68d 100644 --- a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -71,8 +71,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { private static final int lokiV2 = 23; private static final int lokiV3 = 24; private static final int lokiV4 = 25; + private static final int lokiV5 = 26; - private static final int DATABASE_VERSION = lokiV4; // Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes + private static final int DATABASE_VERSION = lokiV5; // Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes private static final String DATABASE_NAME = "signal.db"; private final Context context; @@ -127,6 +128,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { db.execSQL(LokiAPIDatabase.getCreateLastMessageServerIDTableCommand()); db.execSQL(LokiAPIDatabase.getCreateLastDeletionServerIDTableCommand()); db.execSQL(LokiAPIDatabase.getCreatePairingAuthorisationTableCommand()); + db.execSQL(LokiAPIDatabase.getCreateUserCountTableCommand()); db.execSQL(LokiPreKeyBundleDatabase.getCreateTableCommand()); db.execSQL(LokiPreKeyRecordDatabase.getCreateTableCommand()); db.execSQL(LokiMessageDatabase.getCreateMessageFriendRequestTableCommand()); @@ -519,6 +521,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { db.execSQL(LokiMessageDatabase.getCreateMessageToThreadMappingTableCommand()); } + if (oldVersion < lokiV5) { + db.execSQL(LokiAPIDatabase.getCreateUserCountTableCommand()); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); diff --git a/src/org/thoughtcrime/securesms/loki/LokiAPIDatabase.kt b/src/org/thoughtcrime/securesms/loki/LokiAPIDatabase.kt index 91526991e5..b65597dec7 100644 --- a/src/org/thoughtcrime/securesms/loki/LokiAPIDatabase.kt +++ b/src/org/thoughtcrime/securesms/loki/LokiAPIDatabase.kt @@ -55,6 +55,11 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( private val grantSignature = "grant_signature" @JvmStatic val createPairingAuthorisationTableCommand = "CREATE TABLE $pairingAuthorisationCache ($primaryDevicePublicKey TEXT, $secondaryDevicePublicKey TEXT, " + "$requestSignature TEXT NULLABLE DEFAULT NULL, $grantSignature TEXT NULLABLE DEFAULT NULL, PRIMARY KEY ($primaryDevicePublicKey, $secondaryDevicePublicKey));" + // User count cache + private val userCountCache = "loki_user_count_cache" + private val publicChatID = "public_chat_id" + private val userCount = "user_count" + @JvmStatic val createUserCountTableCommand = "CREATE TABLE $userCountCache ($publicChatID STRING PRIMARY KEY, $userCount INTEGER DEFAULT 0);" } override fun getSwarmCache(hexEncodedPublicKey: String): Set? { @@ -194,6 +199,21 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( val database = databaseHelper.writableDatabase database.delete(pairingAuthorisationCache, "${Companion.primaryDevicePublicKey} = ? OR ${Companion.secondaryDevicePublicKey} = ?", arrayOf( primaryDevicePublicKey, secondaryDevicePublicKey )) } + + fun getUserCount(group: Long, server: String): Int? { + val database = databaseHelper.readableDatabase + val index = "$server.$group" + return database.get(userCountCache, "$publicChatID = ?", wrap(index)) { cursor -> + cursor.getInt(userCount) + }?.toInt() + } + + override fun setUserCount(userCount: Int, group: Long, server: String) { + val database = databaseHelper.writableDatabase + val index = "$server.$group" + val row = wrap(mapOf( publicChatID to index, LokiAPIDatabase.userCount to userCount.toString() )) + database.insertOrUpdate(userCountCache, row, "$publicChatID = ?", wrap(index)) + } } // region Convenience diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt index e7e2b34865..db2e7676ab 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt @@ -203,6 +203,10 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe override fun run() { AsyncTask.execute { threadDatabase.deleteConversation(threadID) + val publicChat = DatabaseFactory.getLokiThreadDatabase(activity).getPublicChat(threadID) + if (publicChat != null) { + ApplicationContext.getInstance(activity).lokiPublicChatAPI!!.leave(publicChat.channel, publicChat.server) + } MessageNotifier.updateNotification(activity) } } diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt index c57d1b6d25..d6ef797828 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt @@ -74,6 +74,7 @@ class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCode application.lokiPublicChatManager.addChat(url, channel).successUi { lokiPublicChatAPI.getMessages(channel, url) lokiPublicChatAPI.setDisplayName(displayName, url) + lokiPublicChatAPI.join(channel, url) val profileKey: ByteArray = ProfileKeyUtil.getProfileKey(this) val profileUrl: String? = TextSecurePreferences.getProfileAvatarUrl(this) lokiPublicChatAPI.setProfilePicture(url, profileKey, profileUrl)