mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-19 16:41:31 +00:00
Implement moderator tags
This commit is contained in:
parent
7cc7f907fe
commit
b67efcf2ab
30
res/drawable/icon_crown.xml
Normal file
30
res/drawable/icon_crown.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="512dp"
|
||||||
|
android:height="512dp"
|
||||||
|
android:viewportWidth="512"
|
||||||
|
android:viewportHeight="512">
|
||||||
|
<path
|
||||||
|
android:pathData="m419.25,369.977h-326.5c-4.988,0 -9.648,-2.465 -12.457,-6.586 -43.078,-63.172 -46.383,-184.691 -46.633,-202.73 -0.016,-0.707 -0.023,-1.422 -0.023,-2.133 0,-8.316 6.734,-15.063 15.051,-15.078h0.031c8.301,0 15.047,6.715 15.078,15.02 0,0.102 0.004,0.992 0.039,2.57 1.328,42.902 36.645,77.391 79.863,77.391 44.059,0 79.902,-35.844 79.902,-79.902 0,-8.328 6.754,-15.078 15.078,-15.078h34.637c8.328,0 15.078,6.75 15.078,15.078 0,44.059 35.848,79.902 79.906,79.902 43.258,0 78.598,-34.551 79.867,-77.508 0.027,-1.508 0.035,-2.352 0.035,-2.449 0.031,-8.309 6.773,-15.023 15.078,-15.023h0.027c8.316,0.016 15.051,6.762 15.051,15.078 0,0.715 -0.008,1.426 -0.02,2.137 -0.254,18.035 -3.559,139.559 -46.633,202.73 -2.809,4.117 -7.473,6.582 -12.457,6.582zM419.25,369.977"
|
||||||
|
android:fillColor="#fff780"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m463.309,143.449c-0.008,0 -0.016,0 -0.027,0 -8.301,0 -15.047,6.715 -15.078,15.02 0,0.102 -0.004,0.945 -0.035,2.453 -1.27,42.953 -36.609,77.508 -79.867,77.508 -44.059,0 -79.902,-35.844 -79.902,-79.902 0,-8.328 -6.754,-15.078 -15.078,-15.078h-17.316v226.523h163.246c4.988,0 9.648,-2.465 12.457,-6.582 43.078,-63.172 46.383,-184.695 46.633,-202.73 0.016,-0.707 0.023,-1.422 0.023,-2.133 -0.004,-8.316 -6.738,-15.063 -15.055,-15.078zM463.309,143.449"
|
||||||
|
android:fillColor="#ffc02e"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m256,92c-26.863,0 -48.719,21.855 -48.719,48.719s21.855,48.715 48.719,48.715 48.719,-21.852 48.719,-48.715 -21.855,-48.719 -48.719,-48.719zM256,92"
|
||||||
|
android:fillColor="#ffc02e"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m256.004,92v97.438c26.863,-0.004 48.715,-21.855 48.715,-48.719s-21.855,-48.715 -48.715,-48.719zM256.004,92"
|
||||||
|
android:fillColor="#ffa73b"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m48.719,129.598c-26.863,0 -48.719,21.855 -48.719,48.719 0,26.863 21.855,48.719 48.719,48.719s48.715,-21.855 48.715,-48.719c0,-26.863 -21.852,-48.719 -48.715,-48.719zM48.719,129.598"
|
||||||
|
android:fillColor="#ffc02e"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m463.281,129.598c-26.863,0 -48.715,21.855 -48.715,48.719 0,26.859 21.852,48.715 48.715,48.715s48.719,-21.855 48.719,-48.715c0,-26.863 -21.855,-48.719 -48.719,-48.719zM463.281,129.598"
|
||||||
|
android:fillColor="#ffa73b"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m419.25,419.441h-326.5c-8.328,0 -15.078,-6.75 -15.078,-15.078v-44.965h356.656v44.965c0,8.328 -6.75,15.078 -15.078,15.078zM419.25,419.441"
|
||||||
|
android:fillColor="#ffc02e"/>
|
||||||
|
<path
|
||||||
|
android:pathData="m256.004,419.441h163.246c8.328,0 15.078,-6.75 15.078,-15.078v-44.965h-178.324zM256.004,419.441"
|
||||||
|
android:fillColor="#ffa73b"/>
|
||||||
|
</vector>
|
@ -23,7 +23,7 @@
|
|||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:clipChildren="false">
|
android:clipChildren="false">
|
||||||
|
|
||||||
<FrameLayout
|
<RelativeLayout
|
||||||
android:id="@+id/contact_photo_container"
|
android:id="@+id/contact_photo_container"
|
||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -39,7 +39,15 @@
|
|||||||
android:cropToPadding="true"
|
android:cropToPadding="true"
|
||||||
android:contentDescription="@string/conversation_item_received__contact_photo_description" />
|
android:contentDescription="@string/conversation_item_received__contact_photo_description" />
|
||||||
|
|
||||||
</FrameLayout>
|
<ImageView
|
||||||
|
android:id="@+id/moderator_icon_image_view"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:src="@drawable/icon_crown"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentBottom="true" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -413,8 +413,8 @@ public class ConversationFragment extends Fragment
|
|||||||
boolean isSentByUser = ((MessageRecord)messageRecords.toArray()[0]).isOutgoing();
|
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_copy_public_key).setVisible(isLokiPublicChat && selectedMessageCount == 1 && !isSentByUser);
|
||||||
menu.findItem(R.id.menu_context_reply).setVisible(isLokiPublicChat && selectedMessageCount == 1);
|
menu.findItem(R.id.menu_context_reply).setVisible(isLokiPublicChat && selectedMessageCount == 1);
|
||||||
LokiAPIDatabase lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(getContext());
|
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(getContext());
|
||||||
boolean userCanModerate = lokiAPIDatabase.isModerator(LokiGroupChatAPI.getPublicChatServerID(), LokiGroupChatAPI.getPublicChatServer());
|
boolean userCanModerate = LokiGroupChatAPI.Companion.isUserModerator(userHexEncodedPublicKey, LokiGroupChatAPI.getPublicChatServerID(), LokiGroupChatAPI.getPublicChatServer());
|
||||||
boolean isDeleteOptionVisible = isLokiPublicChat && selectedMessageCount == 1 && (isSentByUser || userCanModerate);
|
boolean isDeleteOptionVisible = isLokiPublicChat && selectedMessageCount == 1 && (isSentByUser || userCanModerate);
|
||||||
menu.findItem(R.id.menu_context_delete_message).setVisible(isDeleteOptionVisible);
|
menu.findItem(R.id.menu_context_delete_message).setVisible(isDeleteOptionVisible);
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,6 +45,7 @@ import android.util.AttributeSet;
|
|||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
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.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
|
||||||
import org.thoughtcrime.securesms.stickers.StickerUrl;
|
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.thoughtcrime.securesms.util.views.Stub;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -142,6 +153,7 @@ public class ConversationItem extends LinearLayout
|
|||||||
private TextView groupSenderProfileName;
|
private TextView groupSenderProfileName;
|
||||||
private View groupSenderHolder;
|
private View groupSenderHolder;
|
||||||
private AvatarImageView contactPhoto;
|
private AvatarImageView contactPhoto;
|
||||||
|
private ImageView moderatorIconImageView;
|
||||||
private ViewGroup contactPhotoHolder;
|
private ViewGroup contactPhotoHolder;
|
||||||
private AlertView alertView;
|
private AlertView alertView;
|
||||||
private ViewGroup container;
|
private ViewGroup container;
|
||||||
@ -198,6 +210,7 @@ public class ConversationItem extends LinearLayout
|
|||||||
this.groupSenderProfileName = findViewById(R.id.group_message_sender_profile);
|
this.groupSenderProfileName = findViewById(R.id.group_message_sender_profile);
|
||||||
this.alertView = findViewById(R.id.indicators_parent);
|
this.alertView = findViewById(R.id.indicators_parent);
|
||||||
this.contactPhoto = findViewById(R.id.contact_photo);
|
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.contactPhotoHolder = findViewById(R.id.contact_photo_container);
|
||||||
this.bodyBubble = findViewById(R.id.body_bubble);
|
this.bodyBubble = findViewById(R.id.body_bubble);
|
||||||
this.mediaThumbnailStub = new Stub<>(findViewById(R.id.image_view_stub));
|
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())) {
|
if (!next.isPresent() || next.get().isUpdate() || !current.getRecipient().getAddress().equals(next.get().getRecipient().getAddress())) {
|
||||||
contactPhoto.setVisibility(VISIBLE);
|
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 {
|
} else {
|
||||||
contactPhoto.setVisibility(GONE);
|
contactPhoto.setVisibility(GONE);
|
||||||
|
moderatorIconImageView.setVisibility(GONE);
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
groupSenderHolder.setVisibility(GONE);
|
groupSenderHolder.setVisibility(GONE);
|
||||||
|
|
||||||
if (contactPhotoHolder != null) {
|
if (contactPhotoHolder != null) {
|
||||||
contactPhotoHolder.setVisibility(GONE);
|
contactPhotoHolder.setVisibility(GONE);
|
||||||
|
moderatorIconImageView.setVisibility(GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,6 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
db.execSQL(LokiAPIDatabase.getCreateGroupChatAuthTokenTableCommand());
|
db.execSQL(LokiAPIDatabase.getCreateGroupChatAuthTokenTableCommand());
|
||||||
db.execSQL(LokiAPIDatabase.getCreateLastMessageServerIDTableCommand());
|
db.execSQL(LokiAPIDatabase.getCreateLastMessageServerIDTableCommand());
|
||||||
db.execSQL(LokiAPIDatabase.getCreateLastDeletionServerIDTableCommand());
|
db.execSQL(LokiAPIDatabase.getCreateLastDeletionServerIDTableCommand());
|
||||||
db.execSQL(LokiAPIDatabase.getCreateModerationPermissionTableCommand());
|
|
||||||
db.execSQL(LokiPreKeyBundleDatabase.getCreateTableCommand());
|
db.execSQL(LokiPreKeyBundleDatabase.getCreateTableCommand());
|
||||||
db.execSQL(LokiPreKeyRecordDatabase.getCreateTableCommand());
|
db.execSQL(LokiPreKeyRecordDatabase.getCreateTableCommand());
|
||||||
db.execSQL(LokiMessageDatabase.getCreateTableCommand());
|
db.execSQL(LokiMessageDatabase.getCreateTableCommand());
|
||||||
|
@ -45,11 +45,6 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(
|
|||||||
private val lastDeletionServerIDCacheIndex = "loki_api_last_deletion_server_id_cache_index"
|
private val lastDeletionServerIDCacheIndex = "loki_api_last_deletion_server_id_cache_index"
|
||||||
private val lastDeletionServerID = "last_deletion_server_id"
|
private val lastDeletionServerID = "last_deletion_server_id"
|
||||||
@JvmStatic val createLastDeletionServerIDTableCommand = "CREATE TABLE $lastDeletionServerIDCache ($lastDeletionServerIDCacheIndex STRING PRIMARY KEY, $lastDeletionServerID INTEGER DEFAULT 0);"
|
@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>? {
|
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() ))
|
val row = wrap(mapOf( lastDeletionServerIDCacheIndex to index, lastDeletionServerID to newValue.toString() ))
|
||||||
database.insertOrUpdate(lastDeletionServerIDCache, row, "$lastDeletionServerIDCacheIndex = ?", wrap(index))
|
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
|
// region Convenience
|
||||||
|
@ -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() {
|
override fun run() {
|
||||||
pollForModerationPermission()
|
pollForModerators()
|
||||||
handler.postDelayed(this, pollForModerationPermissionInterval)
|
handler.postDelayed(this, pollForModeratorsInterval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
@ -71,7 +71,7 @@ class LokiGroupChatPoller(private val context: Context, private val group: LokiG
|
|||||||
companion object {
|
companion object {
|
||||||
private val pollForNewMessagesInterval: Long = 4 * 1000
|
private val pollForNewMessagesInterval: Long = 4 * 1000
|
||||||
private val pollForDeletedMessagesInterval: Long = 20 * 1000
|
private val pollForDeletedMessagesInterval: Long = 20 * 1000
|
||||||
private val pollForModerationPermissionInterval: Long = 10 * 60 * 1000
|
private val pollForModeratorsInterval: Long = 10 * 60 * 1000
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
@ -80,14 +80,14 @@ class LokiGroupChatPoller(private val context: Context, private val group: LokiG
|
|||||||
if (hasStarted) return
|
if (hasStarted) return
|
||||||
pollForNewMessagesTask.run()
|
pollForNewMessagesTask.run()
|
||||||
pollForDeletedMessagesTask.run()
|
pollForDeletedMessagesTask.run()
|
||||||
pollForModerationPermissionTask.run()
|
pollForModeratorsTask.run()
|
||||||
hasStarted = true
|
hasStarted = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
handler.removeCallbacks(pollForNewMessagesTask)
|
handler.removeCallbacks(pollForNewMessagesTask)
|
||||||
handler.removeCallbacks(pollForDeletedMessagesTask)
|
handler.removeCallbacks(pollForDeletedMessagesTask)
|
||||||
handler.removeCallbacks(pollForModerationPermissionTask)
|
handler.removeCallbacks(pollForModeratorsTask)
|
||||||
hasStarted = false
|
hasStarted = false
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
@ -189,11 +189,8 @@ class LokiGroupChatPoller(private val context: Context, private val group: LokiG
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pollForModerationPermission() {
|
private fun pollForModerators() {
|
||||||
api.userHasModerationPermission(group.serverID, group.server).success { isModerator ->
|
api.getModerators(group.serverID, group.server)
|
||||||
val lokiAPIDatabase = DatabaseFactory.getLokiAPIDatabase(context)
|
|
||||||
lokiAPIDatabase.setIsModerator(group.serverID, group.server, isModerator)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user