feat: member counts in v2 open group ConversationActivity

This commit is contained in:
jubb 2021-05-05 13:52:15 +10:00
parent d8e9e372d3
commit 35aec04ac9
8 changed files with 83 additions and 16 deletions

View File

@ -90,6 +90,7 @@ import org.session.libsession.messaging.messages.signal.OutgoingSecureMediaMessa
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; import org.session.libsession.messaging.messages.signal.OutgoingTextMessage;
import org.session.libsession.messaging.messages.visible.VisibleMessage; import org.session.libsession.messaging.messages.visible.VisibleMessage;
import org.session.libsession.messaging.open_groups.OpenGroup; import org.session.libsession.messaging.open_groups.OpenGroup;
import org.session.libsession.messaging.open_groups.OpenGroupV2;
import org.session.libsession.messaging.sending_receiving.MessageSender; import org.session.libsession.messaging.sending_receiving.MessageSender;
import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.sending_receiving.attachments.Attachment;
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview;
@ -374,9 +375,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(threadId, this); MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(threadId, this);
OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId);
OpenGroupV2 openGroupV2 = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadId);
if (publicChat != null) { if (publicChat != null) {
// Request open group info update and handle the successful result in #onOpenGroupInfoUpdated(). // Request open group info update and handle the successful result in #onOpenGroupInfoUpdated().
PublicChatInfoUpdateWorker.scheduleInstant(this, publicChat.getServer(), publicChat.getChannel()); PublicChatInfoUpdateWorker.scheduleInstant(this, publicChat.getServer(), publicChat.getChannel());
} else if (openGroupV2 != null) {
PublicChatInfoUpdateWorker.scheduleInstant(this, openGroupV2.getServer(), openGroupV2.getRoom());
} }
View rootView = findViewById(R.id.rootView); View rootView = findViewById(R.id.rootView);
@ -1397,11 +1401,17 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onOpenGroupInfoUpdated(OpenGroupUtilities.GroupInfoUpdatedEvent event) { public void onOpenGroupInfoUpdated(OpenGroupUtilities.GroupInfoUpdatedEvent event) {
OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId);
OpenGroupV2 openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadId);
if (publicChat != null && if (publicChat != null &&
publicChat.getChannel() == event.getChannel() && publicChat.getChannel() == event.getChannel() &&
publicChat.getServer().equals(event.getUrl())) { publicChat.getServer().equals(event.getUrl())) {
this.updateSubtitleTextView(); this.updateSubtitleTextView();
} }
if (openGroup != null &&
openGroup.getRoom().equals(event.getRoom()) &&
openGroup.getServer().equals(event.getUrl())) {
this.updateSubtitleTextView();
}
} }
//////// Helper Methods //////// Helper Methods
@ -2335,10 +2345,15 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
subtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault())); subtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault()));
} else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Session Updates") && !recipient.getName().equals("Loki News")) { } else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Session Updates") && !recipient.getName().equals("Loki News")) {
OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId);
OpenGroupV2 openGroup = DatabaseFactory.getLokiThreadDatabase(this).getOpenGroupChat(threadId);
if (publicChat != null) { if (publicChat != null) {
Integer userCount = DatabaseFactory.getLokiAPIDatabase(this).getUserCount(publicChat.getChannel(), publicChat.getServer()); Integer userCount = DatabaseFactory.getLokiAPIDatabase(this).getUserCount(publicChat.getChannel(), publicChat.getServer());
if (userCount == null) { userCount = 0; } if (userCount == null) { userCount = 0; }
subtitleTextView.setText(userCount + " members"); subtitleTextView.setText(userCount + " members");
} else if (openGroup != null) {
Integer userCount = DatabaseFactory.getLokiAPIDatabase(this).getUserCount(openGroup.getRoom(),openGroup.getServer());
if (userCount == null) { userCount = 0; }
subtitleTextView.setText(userCount + " members");
} else if (PublicKeyValidation.isValid(recipient.getAddress().toString())) { } else if (PublicKeyValidation.isValid(recipient.getAddress().toString())) {
subtitleTextView.setText(recipient.getAddress().toString()); subtitleTextView.setText(recipient.getAddress().toString());
} else { } else {

View File

@ -330,7 +330,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
DatabaseFactory.getLokiAPIDatabase(context).removeLastDeletionServerID(room, server) DatabaseFactory.getLokiAPIDatabase(context).removeLastDeletionServerID(room, server)
} }
override fun setUserCount(room: String, server: String, newValue: Long) { override fun setUserCount(room: String, server: String, newValue: Int) {
DatabaseFactory.getLokiAPIDatabase(context).setUserCount(room, server, newValue) DatabaseFactory.getLokiAPIDatabase(context).setUserCount(room, server, newValue)
} }

View File

@ -16,6 +16,25 @@ class PublicChatInfoUpdateWorker(val context: Context, params: WorkerParameters)
private const val DATA_KEY_SERVER_URL = "server_uRL" private const val DATA_KEY_SERVER_URL = "server_uRL"
private const val DATA_KEY_CHANNEL = "channel" private const val DATA_KEY_CHANNEL = "channel"
private const val DATA_KEY_ROOM = "room"
@JvmStatic
fun scheduleInstant(context: Context, serverUrl: String, room :String) {
val workRequest = OneTimeWorkRequestBuilder<PublicChatInfoUpdateWorker>()
.setConstraints(Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.setInputData(workDataOf(
DATA_KEY_SERVER_URL to serverUrl,
DATA_KEY_ROOM to room
))
.build()
WorkManager
.getInstance(context)
.enqueue(workRequest)
}
@JvmStatic @JvmStatic
fun scheduleInstant(context: Context, serverURL: String, channel: Long) { fun scheduleInstant(context: Context, serverURL: String, channel: Long) {
@ -39,7 +58,11 @@ class PublicChatInfoUpdateWorker(val context: Context, params: WorkerParameters)
override fun doWork(): Result { override fun doWork(): Result {
val serverUrl = inputData.getString(DATA_KEY_SERVER_URL)!! val serverUrl = inputData.getString(DATA_KEY_SERVER_URL)!!
val channel = inputData.getLong(DATA_KEY_CHANNEL, -1) val channel = inputData.getLong(DATA_KEY_CHANNEL, -1)
val room = inputData.getString(DATA_KEY_ROOM)
val isOpenGroupV2 = !room.isNullOrEmpty() && channel == -1L
if (!isOpenGroupV2) {
val publicChatId = OpenGroup.getId(channel, serverUrl) val publicChatId = OpenGroup.getId(channel, serverUrl)
return try { return try {
@ -51,5 +74,19 @@ class PublicChatInfoUpdateWorker(val context: Context, params: WorkerParameters)
Log.e(TAG, "Failed to update open group info for $publicChatId", e) Log.e(TAG, "Failed to update open group info for $publicChatId", e)
Result.failure() Result.failure()
} }
} else {
val openGroupId = "$serverUrl.$room"
return try {
Log.v(TAG, "Updating open group info for $openGroupId.")
OpenGroupUtilities.updateGroupInfo(context, serverUrl, room!!)
Log.v(TAG, "Open group info was successfully updated for $openGroupId.")
Result.success()
} catch (e: Exception) {
Log.e(TAG, "Failed to update open group info for $openGroupId", e)
Result.failure()
}
}
} }
} }

View File

@ -385,7 +385,7 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
database.insertOrUpdate(userCountTable, row, "$publicChatID = ?", wrap(index)) database.insertOrUpdate(userCountTable, row, "$publicChatID = ?", wrap(index))
} }
override fun setUserCount(room: String, server: String, newValue: Long) { override fun setUserCount(room: String, server: String, newValue: Int) {
val database = databaseHelper.writableDatabase val database = databaseHelper.writableDatabase
val index = "$server.$room" val index = "$server.$room"
val row = wrap(mapOf( publicChatID to index, userCount to newValue.toString() )) val row = wrap(mapOf( publicChatID to index, userCount to newValue.toString() ))

View File

@ -94,6 +94,21 @@ object OpenGroupUtilities {
EventBus.getDefault().post(GroupInfoUpdatedEvent(url, channel)) EventBus.getDefault().post(GroupInfoUpdatedEvent(url, channel))
} }
@JvmStatic
@WorkerThread
@Throws(Exception::class)
fun updateGroupInfo(context: Context, server: String, room: String) {
val groupId = GroupUtil.getEncodedOpenGroupID("$server.$room".toByteArray())
if (!DatabaseFactory.getGroupDatabase(context).hasGroup(groupId)) {
throw IllegalStateException("Attempt to update open group info for non-existent DB record: $groupId")
}
val info = OpenGroupAPIV2.getInfo(room, server).get() // store info again?
OpenGroupAPIV2.getMemberCount(room, server).get()
EventBus.getDefault().post(GroupInfoUpdatedEvent(server, room = room))
}
/** /**
* Return a generated name for users in the style of `$name (...$hex.takeLast(8))` for public groups * Return a generated name for users in the style of `$name (...$hex.takeLast(8))` for public groups
*/ */
@ -104,5 +119,5 @@ object OpenGroupUtilities {
const val PUBLIC_GROUP_STRING_FORMAT = "%s (...%s)" const val PUBLIC_GROUP_STRING_FORMAT = "%s (...%s)"
data class GroupInfoUpdatedEvent(val url: String, val channel: Long) data class GroupInfoUpdatedEvent(val url: String, val channel: Long = -1, val room: String = "")
} }

View File

@ -79,7 +79,7 @@ interface StorageProtocol {
fun updateTitle(groupID: String, newValue: String) fun updateTitle(groupID: String, newValue: String)
fun updateProfilePicture(groupID: String, newValue: ByteArray) fun updateProfilePicture(groupID: String, newValue: ByteArray)
fun setUserCount(room: String, server: String, newValue: Long) fun setUserCount(room: String, server: String, newValue: Int)
// Last Message Server ID // Last Message Server ID
fun getLastMessageServerId(room: String, server: String): Long? fun getLastMessageServerId(room: String, server: String): Long?

View File

@ -482,10 +482,10 @@ object OpenGroupAPIV2 {
} }
} }
fun getMemberCount(room: String, server: String): Promise<Long, Exception> { fun getMemberCount(room: String, server: String): Promise<Int, Exception> {
val request = Request(verb = GET, room = room, server = server, endpoint = "member_count") val request = Request(verb = GET, room = room, server = server, endpoint = "member_count")
return send(request).map { json -> return send(request).map { json ->
val memberCount = json["member_count"] as? Long ?: throw Error.PARSING_FAILED val memberCount = json["member_count"] as? Int ?: throw Error.PARSING_FAILED
val storage = MessagingModuleConfiguration.shared.storage val storage = MessagingModuleConfiguration.shared.storage
storage.setUserCount(room, server, memberCount) storage.setUserCount(room, server, memberCount)
memberCount memberCount

View File

@ -28,7 +28,7 @@ interface LokiAPIDatabaseProtocol {
fun setLastMessageServerID(room: String, server: String, newValue: Long) fun setLastMessageServerID(room: String, server: String, newValue: Long)
fun getLastDeletionServerID(room: String, server: String): Long? fun getLastDeletionServerID(room: String, server: String): Long?
fun setLastDeletionServerID(room: String, server: String, newValue: Long) fun setLastDeletionServerID(room: String, server: String, newValue: Long)
fun setUserCount(room: String, server: String, newValue: Long) fun setUserCount(room: String, server: String, newValue: Int)
fun getSessionRequestSentTimestamp(publicKey: String): Long? fun getSessionRequestSentTimestamp(publicKey: String): Long?
fun setSessionRequestSentTimestamp(publicKey: String, newValue: Long) fun setSessionRequestSentTimestamp(publicKey: String, newValue: Long)
fun getSessionRequestProcessedTimestamp(publicKey: String): Long? fun getSessionRequestProcessedTimestamp(publicKey: String): Long?