Implement moderator tags

This commit is contained in:
Niels Andriesse
2019-09-12 16:42:52 +10:00
parent 7cc7f907fe
commit b67efcf2ab
7 changed files with 75 additions and 37 deletions

View File

@@ -413,8 +413,8 @@ public class ConversationFragment extends Fragment
boolean isSentByUser = ((MessageRecord)messageRecords.toArray()[0]).isOutgoing();
menu.findItem(R.id.menu_context_copy_public_key).setVisible(isLokiPublicChat && selectedMessageCount == 1 && !isSentByUser);
menu.findItem(R.id.menu_context_reply).setVisible(isLokiPublicChat && selectedMessageCount == 1);
LokiAPIDatabase lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(getContext());
boolean userCanModerate = lokiAPIDatabase.isModerator(LokiGroupChatAPI.getPublicChatServerID(), LokiGroupChatAPI.getPublicChatServer());
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(getContext());
boolean userCanModerate = LokiGroupChatAPI.Companion.isUserModerator(userHexEncodedPublicKey, LokiGroupChatAPI.getPublicChatServerID(), LokiGroupChatAPI.getPublicChatServer());
boolean isDeleteOptionVisible = isLokiPublicChat && selectedMessageCount == 1 && (isSentByUser || userCanModerate);
menu.findItem(R.id.menu_context_delete_message).setVisible(isDeleteOptionVisible);
} else {

View File

@@ -45,6 +45,7 @@ import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
@@ -99,9 +100,19 @@ import org.thoughtcrime.securesms.mms.TextSlide;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
import org.thoughtcrime.securesms.stickers.StickerUrl;
import org.thoughtcrime.securesms.util.*;
import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.GroupUtil;
import org.thoughtcrime.securesms.util.LongClickCopySpan;
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
import org.thoughtcrime.securesms.util.SearchUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.views.Stub;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI;
import java.util.Collections;
import java.util.HashSet;
@@ -142,6 +153,7 @@ public class ConversationItem extends LinearLayout
private TextView groupSenderProfileName;
private View groupSenderHolder;
private AvatarImageView contactPhoto;
private ImageView moderatorIconImageView;
private ViewGroup contactPhotoHolder;
private AlertView alertView;
private ViewGroup container;
@@ -198,6 +210,7 @@ public class ConversationItem extends LinearLayout
this.groupSenderProfileName = findViewById(R.id.group_message_sender_profile);
this.alertView = findViewById(R.id.indicators_parent);
this.contactPhoto = findViewById(R.id.contact_photo);
this.moderatorIconImageView = findViewById(R.id.moderator_icon_image_view);
this.contactPhotoHolder = findViewById(R.id.contact_photo_container);
this.bodyBubble = findViewById(R.id.body_bubble);
this.mediaThumbnailStub = new Stub<>(findViewById(R.id.image_view_stub));
@@ -921,14 +934,25 @@ public class ConversationItem extends LinearLayout
if (!next.isPresent() || next.get().isUpdate() || !current.getRecipient().getAddress().equals(next.get().getRecipient().getAddress())) {
contactPhoto.setVisibility(VISIBLE);
int visibility;
if (conversationRecipient.getName() != null && conversationRecipient.getName().equals("Loki Public Chat")) {
boolean isModerator = LokiGroupChatAPI.Companion.isUserModerator(TextSecurePreferences.getLocalNumber(getContext()), LokiGroupChatAPI.getPublicChatServerID(), LokiGroupChatAPI.getPublicChatServer());
visibility = isModerator ? View.VISIBLE : View.GONE;
} else {
visibility = View.GONE;
}
moderatorIconImageView.setVisibility(visibility);
} else {
contactPhoto.setVisibility(GONE);
moderatorIconImageView.setVisibility(GONE);
}
} else {
groupSenderHolder.setVisibility(GONE);
if (contactPhotoHolder != null) {
contactPhotoHolder.setVisibility(GONE);
moderatorIconImageView.setVisibility(GONE);
}
}
}

View File

@@ -129,7 +129,6 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
db.execSQL(LokiAPIDatabase.getCreateGroupChatAuthTokenTableCommand());
db.execSQL(LokiAPIDatabase.getCreateLastMessageServerIDTableCommand());
db.execSQL(LokiAPIDatabase.getCreateLastDeletionServerIDTableCommand());
db.execSQL(LokiAPIDatabase.getCreateModerationPermissionTableCommand());
db.execSQL(LokiPreKeyBundleDatabase.getCreateTableCommand());
db.execSQL(LokiPreKeyRecordDatabase.getCreateTableCommand());
db.execSQL(LokiMessageDatabase.getCreateTableCommand());

View File

@@ -45,11 +45,6 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
private val lastDeletionServerIDCacheIndex = "loki_api_last_deletion_server_id_cache_index"
private val lastDeletionServerID = "last_deletion_server_id"
@JvmStatic val createLastDeletionServerIDTableCommand = "CREATE TABLE $lastDeletionServerIDCache ($lastDeletionServerIDCacheIndex STRING PRIMARY KEY, $lastDeletionServerID INTEGER DEFAULT 0);"
// Moderation permission cache
private val moderationPermissionCache = "loki_api_moderation_permission_cache"
private val moderationPermissionCacheIndex = "loki_api_moderation_permission_cache_index"
private val isModerator = "is_moderator"
@JvmStatic val createModerationPermissionTableCommand = "CREATE TABLE $moderationPermissionCache ($moderationPermissionCacheIndex STRING PRIMARY KEY, $isModerator INTEGER DEFAULT 0);"
}
override fun getSwarmCache(hexEncodedPublicKey: String): Set<LokiAPITarget>? {
@@ -146,21 +141,6 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
val row = wrap(mapOf( lastDeletionServerIDCacheIndex to index, lastDeletionServerID to newValue.toString() ))
database.insertOrUpdate(lastDeletionServerIDCache, row, "$lastDeletionServerIDCacheIndex = ?", wrap(index))
}
fun isModerator(group: Long, server: String): Boolean {
val database = databaseHelper.readableDatabase
val index = "$server.$group"
return database.get(moderationPermissionCache, "$moderationPermissionCacheIndex = ?", wrap(index)) { cursor ->
cursor.getInt(isModerator)
} == 1
}
fun setIsModerator(group: Long, server: String, newValue: Boolean) {
val database = databaseHelper.writableDatabase
val index = "$server.$group"
val row = wrap(mapOf( moderationPermissionCacheIndex to index, isModerator to (if (newValue) 1 else 0).toString() ))
database.insertOrUpdate(moderationPermissionCache, row, "$moderationPermissionCacheIndex = ?", wrap(index))
}
}
// region Convenience

View File

@@ -58,11 +58,11 @@ class LokiGroupChatPoller(private val context: Context, private val group: LokiG
}
}
private val pollForModerationPermissionTask = object : Runnable {
private val pollForModeratorsTask = object : Runnable {
override fun run() {
pollForModerationPermission()
handler.postDelayed(this, pollForModerationPermissionInterval)
pollForModerators()
handler.postDelayed(this, pollForModeratorsInterval)
}
}
// endregion
@@ -71,7 +71,7 @@ class LokiGroupChatPoller(private val context: Context, private val group: LokiG
companion object {
private val pollForNewMessagesInterval: Long = 4 * 1000
private val pollForDeletedMessagesInterval: Long = 20 * 1000
private val pollForModerationPermissionInterval: Long = 10 * 60 * 1000
private val pollForModeratorsInterval: Long = 10 * 60 * 1000
}
// endregion
@@ -80,14 +80,14 @@ class LokiGroupChatPoller(private val context: Context, private val group: LokiG
if (hasStarted) return
pollForNewMessagesTask.run()
pollForDeletedMessagesTask.run()
pollForModerationPermissionTask.run()
pollForModeratorsTask.run()
hasStarted = true
}
fun stop() {
handler.removeCallbacks(pollForNewMessagesTask)
handler.removeCallbacks(pollForDeletedMessagesTask)
handler.removeCallbacks(pollForModerationPermissionTask)
handler.removeCallbacks(pollForModeratorsTask)
hasStarted = false
}
// endregion
@@ -189,11 +189,8 @@ class LokiGroupChatPoller(private val context: Context, private val group: LokiG
}
}
private fun pollForModerationPermission() {
api.userHasModerationPermission(group.serverID, group.server).success { isModerator ->
val lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(context)
lokiAPIDatabase.setIsModerator(group.serverID, group.server, isModerator)
}
private fun pollForModerators() {
api.getModerators(group.serverID, group.server)
}
// endregion
}