mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-17 13:48:26 +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:clipChildren="false">
|
||||
|
||||
<FrameLayout
|
||||
<RelativeLayout
|
||||
android:id="@+id/contact_photo_container"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="wrap_content"
|
||||
@ -39,7 +39,15 @@
|
||||
android:cropToPadding="true"
|
||||
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
|
||||
android:layout_width="match_parent"
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user