mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-30 13:35:18 +00:00
fix: NPE in highlighting messages for OGv2, deletion and moderation working
This commit is contained in:
parent
7f0962b3d4
commit
9d4a2d1505
@ -409,11 +409,11 @@ public class ConversationFragment extends Fragment
|
|||||||
}
|
}
|
||||||
menu.findItem(R.id.menu_context_copy_public_key).setVisible(selectedMessageCount == 1 && !areAllSentByUser);
|
menu.findItem(R.id.menu_context_copy_public_key).setVisible(selectedMessageCount == 1 && !areAllSentByUser);
|
||||||
menu.findItem(R.id.menu_context_reply).setVisible(selectedMessageCount == 1);
|
menu.findItem(R.id.menu_context_reply).setVisible(selectedMessageCount == 1);
|
||||||
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(getContext());
|
String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(requireContext());
|
||||||
boolean userCanModerate =
|
boolean userCanModerate =
|
||||||
(isPublicChat &&
|
(isPublicChat &&
|
||||||
(OpenGroupAPI.isUserModerator(userHexEncodedPublicKey, publicChat.getChannel(), publicChat.getServer())
|
((publicChat != null && OpenGroupAPI.isUserModerator(userHexEncodedPublicKey, publicChat.getChannel(), publicChat.getServer()))
|
||||||
|| OpenGroupAPIV2.isUserModerator(userHexEncodedPublicKey, openGroupChat.getRoom(), openGroupChat.getServer()))
|
|| (openGroupChat != null && OpenGroupAPIV2.isUserModerator(userHexEncodedPublicKey, openGroupChat.getRoom(), openGroupChat.getServer())))
|
||||||
);
|
);
|
||||||
boolean isDeleteOptionVisible = !isPublicChat || (areAllSentByUser || userCanModerate);
|
boolean isDeleteOptionVisible = !isPublicChat || (areAllSentByUser || userCanModerate);
|
||||||
// allow banning if moderating a public chat and only one user's messages are selected
|
// allow banning if moderating a public chat and only one user's messages are selected
|
||||||
@ -515,6 +515,7 @@ public class ConversationFragment extends Fragment
|
|||||||
builder.setCancelable(true);
|
builder.setCancelable(true);
|
||||||
|
|
||||||
PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId);
|
PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId);
|
||||||
|
OpenGroupV2 openGroupChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getOpenGroupChat(threadId);
|
||||||
|
|
||||||
builder.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() {
|
builder.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -525,7 +526,7 @@ public class ConversationFragment extends Fragment
|
|||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected Void doInBackground(MessageRecord... messageRecords) {
|
protected Void doInBackground(MessageRecord... messageRecords) {
|
||||||
if (publicChat != null) {
|
if (publicChat != null || openGroupChat != null) {
|
||||||
ArrayList<Long> serverIDs = new ArrayList<>();
|
ArrayList<Long> serverIDs = new ArrayList<>();
|
||||||
ArrayList<Long> ignoredMessages = new ArrayList<>();
|
ArrayList<Long> ignoredMessages = new ArrayList<>();
|
||||||
ArrayList<Long> failedMessages = new ArrayList<>();
|
ArrayList<Long> failedMessages = new ArrayList<>();
|
||||||
@ -561,6 +562,28 @@ public class ConversationFragment extends Fragment
|
|||||||
Log.w("Loki", "Couldn't delete message due to error: " + e.toString() + ".");
|
Log.w("Loki", "Couldn't delete message due to error: " + e.toString() + ".");
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
} else if (openGroupChat != null) {
|
||||||
|
for (Long serverId : serverIDs) {
|
||||||
|
OpenGroupAPIV2
|
||||||
|
.deleteMessage(serverId, openGroupChat.getRoom(), openGroupChat.getServer())
|
||||||
|
.success(l -> {
|
||||||
|
for (MessageRecord messageRecord : messageRecords) {
|
||||||
|
Long serverID = DatabaseFactory.getLokiMessageDatabase(getContext()).getServerID(messageRecord.id);
|
||||||
|
if (serverID != null && serverID.equals(serverId)) {
|
||||||
|
if (messageRecord.isMms()) {
|
||||||
|
DatabaseFactory.getMmsDatabase(getContext()).delete(messageRecord.getId());
|
||||||
|
} else {
|
||||||
|
DatabaseFactory.getSmsDatabase(getContext()).deleteMessage(messageRecord.getId());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}).fail(e->{
|
||||||
|
Log.e("Loki", "Couldn't delete message due to error",e);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (MessageRecord messageRecord : messageRecords) {
|
for (MessageRecord messageRecord : messageRecords) {
|
||||||
@ -597,7 +620,8 @@ public class ConversationFragment extends Fragment
|
|||||||
builder.setTitle(R.string.ConversationFragment_ban_selected_user);
|
builder.setTitle(R.string.ConversationFragment_ban_selected_user);
|
||||||
builder.setCancelable(true);
|
builder.setCancelable(true);
|
||||||
|
|
||||||
PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId);
|
final PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId);
|
||||||
|
final OpenGroupV2 openGroupChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getOpenGroupChat(threadId);
|
||||||
|
|
||||||
builder.setPositiveButton(R.string.ban, (dialog, which) -> {
|
builder.setPositiveButton(R.string.ban, (dialog, which) -> {
|
||||||
ConversationAdapter chatAdapter = getListAdapter();
|
ConversationAdapter chatAdapter = getListAdapter();
|
||||||
@ -616,7 +640,17 @@ public class ConversationFragment extends Fragment
|
|||||||
Log.d("Loki", "User banned");
|
Log.d("Loki", "User banned");
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
}).fail(e -> {
|
}).fail(e -> {
|
||||||
Log.d("Loki", "Couldn't ban user due to error: " + e.toString() + ".");
|
Log.e("Loki", "Couldn't ban user due to error",e);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
} else if (openGroupChat != null) {
|
||||||
|
OpenGroupAPIV2
|
||||||
|
.ban(userPublicKey, openGroupChat.getRoom(), openGroupChat.getServer())
|
||||||
|
.success(l -> {
|
||||||
|
Log.d("Loki", "User banned");
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
}).fail(e -> {
|
||||||
|
Log.e("Loki", "Failed to ban user",e);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -580,7 +580,9 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
|||||||
val mmsDb = DatabaseFactory.getMmsDatabase(context)
|
val mmsDb = DatabaseFactory.getMmsDatabase(context)
|
||||||
val cursor = mmsDb.getMessage(mmsId)
|
val cursor = mmsDb.getMessage(mmsId)
|
||||||
val reader = mmsDb.readerFor(cursor)
|
val reader = mmsDb.readerFor(cursor)
|
||||||
return reader.next.threadId
|
val threadId = reader.next.threadId
|
||||||
|
cursor.close()
|
||||||
|
return threadId
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSessionRequestSentTimestamp(publicKey: String): Long? {
|
override fun getSessionRequestSentTimestamp(publicKey: String): Long? {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package org.session.libsession.messaging.opengroups
|
package org.session.libsession.messaging.opengroups
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.PropertyNamingStrategy
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonNaming
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
@ -36,8 +38,6 @@ object OpenGroupAPIV2 {
|
|||||||
const val DEFAULT_SERVER = "https://sog.ibolpap.finance"
|
const val DEFAULT_SERVER = "https://sog.ibolpap.finance"
|
||||||
private const val DEFAULT_SERVER_PUBLIC_KEY = "b464aa186530c97d6bcf663a3a3b7465a5f782beaa67c83bee99468824b4aa10"
|
private const val DEFAULT_SERVER_PUBLIC_KEY = "b464aa186530c97d6bcf663a3a3b7465a5f782beaa67c83bee99468824b4aa10"
|
||||||
|
|
||||||
// https://sog.ibolpap.finance/main?public_key=b464aa186530c97d6bcf663a3a3b7465a5f782beaa67c83bee99468824b4aa10
|
|
||||||
|
|
||||||
val defaultRooms = MutableSharedFlow<List<DefaultGroup>>(replay = 1)
|
val defaultRooms = MutableSharedFlow<List<DefaultGroup>>(replay = 1)
|
||||||
|
|
||||||
private val sharedContext = Kovenant.createContext()
|
private val sharedContext = Kovenant.createContext()
|
||||||
@ -64,6 +64,13 @@ object OpenGroupAPIV2 {
|
|||||||
val imageID: String?
|
val imageID: String?
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy::class)
|
||||||
|
data class CompactPollRequest(val roomId: String,
|
||||||
|
val authToken: String,
|
||||||
|
val fromDeletionServerId: Long?,
|
||||||
|
val fromMessageServerId: Long?
|
||||||
|
)
|
||||||
|
|
||||||
data class CompactPollResult(val messages: List<OpenGroupMessageV2>,
|
data class CompactPollResult(val messages: List<OpenGroupMessageV2>,
|
||||||
val deletions: List<Long>,
|
val deletions: List<Long>,
|
||||||
val moderators: List<String>
|
val moderators: List<String>
|
||||||
@ -83,7 +90,9 @@ object OpenGroupAPIV2 {
|
|||||||
val useOnionRouting: Boolean = true
|
val useOnionRouting: Boolean = true
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createBody(parameters: Any): RequestBody {
|
private fun createBody(parameters: Any?): RequestBody? {
|
||||||
|
if (parameters == null) return null
|
||||||
|
|
||||||
val parametersAsJSON = JsonUtil.toJson(parameters)
|
val parametersAsJSON = JsonUtil.toJson(parameters)
|
||||||
return RequestBody.create(MediaType.get("application/json"), parametersAsJSON)
|
return RequestBody.create(MediaType.get("application/json"), parametersAsJSON)
|
||||||
}
|
}
|
||||||
@ -111,9 +120,9 @@ object OpenGroupAPIV2 {
|
|||||||
}
|
}
|
||||||
when (request.verb) {
|
when (request.verb) {
|
||||||
GET -> requestBuilder.get()
|
GET -> requestBuilder.get()
|
||||||
PUT -> requestBuilder.put(createBody(request.parameters!!))
|
PUT -> requestBuilder.put(createBody(request.parameters))
|
||||||
POST -> requestBuilder.post(createBody(request.parameters!!))
|
POST -> requestBuilder.post(createBody(request.parameters))
|
||||||
DELETE -> requestBuilder.delete(createBody(request.parameters!!))
|
DELETE -> requestBuilder.delete(createBody(request.parameters))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!request.room.isNullOrEmpty()) {
|
if (!request.room.isNullOrEmpty()) {
|
||||||
@ -145,21 +154,6 @@ object OpenGroupAPIV2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun downloadOpenGroupProfilePicture(imageUrl: String): ByteArray? {
|
|
||||||
Log.d("Loki", "Downloading open group profile picture from \"$imageUrl\".")
|
|
||||||
val outputStream = ByteArrayOutputStream()
|
|
||||||
try {
|
|
||||||
DownloadUtilities.downloadFile(outputStream, imageUrl, FileServerAPI.maxFileSize, null)
|
|
||||||
Log.d("Loki", "Open group profile picture was successfully loaded from \"$imageUrl\"")
|
|
||||||
return outputStream.toByteArray()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.d("Loki", "Failed to download open group profile picture from \"$imageUrl\" due to error: $e.")
|
|
||||||
return null
|
|
||||||
} finally {
|
|
||||||
outputStream.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun downloadOpenGroupProfilePicture(roomID: String, server: String): Promise<ByteArray, Exception> {
|
fun downloadOpenGroupProfilePicture(roomID: String, server: String): Promise<ByteArray, Exception> {
|
||||||
val request = Request(verb = GET, room = roomID, server = server, endpoint = "rooms/$roomID/image", isAuthRequired = false)
|
val request = Request(verb = GET, room = roomID, server = server, endpoint = "rooms/$roomID/image", isAuthRequired = false)
|
||||||
return send(request).map(sharedContext) { json ->
|
return send(request).map(sharedContext) { json ->
|
||||||
@ -291,8 +285,9 @@ object OpenGroupAPIV2 {
|
|||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Message Deletion
|
// region Message Deletion
|
||||||
|
@JvmStatic
|
||||||
fun deleteMessage(serverID: Long, room: String, server: String): Promise<Unit, Exception> {
|
fun deleteMessage(serverID: Long, room: String, server: String): Promise<Unit, Exception> {
|
||||||
val request = Request(verb = DELETE, room = room, server = server, endpoint = "message/$serverID")
|
val request = Request(verb = DELETE, room = room, server = server, endpoint = "messages/$serverID")
|
||||||
return send(request).map(sharedContext) {
|
return send(request).map(sharedContext) {
|
||||||
Log.d("Loki", "Deleted server message")
|
Log.d("Loki", "Deleted server message")
|
||||||
}
|
}
|
||||||
@ -306,9 +301,9 @@ object OpenGroupAPIV2 {
|
|||||||
}
|
}
|
||||||
val request = Request(verb = GET, room = room, server = server, endpoint = "deleted_messages", queryParameters = queryParameters)
|
val request = Request(verb = GET, room = room, server = server, endpoint = "deleted_messages", queryParameters = queryParameters)
|
||||||
return send(request).map(sharedContext) { json ->
|
return send(request).map(sharedContext) { json ->
|
||||||
@Suppress("UNCHECKED_CAST") val serverIDs = json["ids"] as? List<Long>
|
@Suppress("UNCHECKED_CAST") val serverIDs = (json["ids"] as? List<Int>)?.map { it.toLong() }
|
||||||
?: throw Error.PARSING_FAILED
|
?: throw Error.PARSING_FAILED
|
||||||
val lastMessageServerId = storage.getLastMessageServerId(room, server) ?: 0
|
val lastMessageServerId = storage.getLastDeletionServerId(room, server) ?: 0
|
||||||
val serverID = serverIDs.maxOrNull() ?: 0
|
val serverID = serverIDs.maxOrNull() ?: 0
|
||||||
if (serverID > lastMessageServerId) {
|
if (serverID > lastMessageServerId) {
|
||||||
storage.setLastDeletionServerId(room, server, serverID)
|
storage.setLastDeletionServerId(room, server, serverID)
|
||||||
@ -330,6 +325,7 @@ object OpenGroupAPIV2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
fun ban(publicKey: String, room: String, server: String): Promise<Unit, Exception> {
|
fun ban(publicKey: String, room: String, server: String): Promise<Unit, Exception> {
|
||||||
val parameters = mapOf("public_key" to publicKey)
|
val parameters = mapOf("public_key" to publicKey)
|
||||||
val request = Request(verb = POST, room = room, server = server, endpoint = "block_list", parameters = parameters)
|
val request = Request(verb = POST, room = room, server = server, endpoint = "block_list", parameters = parameters)
|
||||||
@ -351,8 +347,11 @@ object OpenGroupAPIV2 {
|
|||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region General
|
// region General
|
||||||
// fun getCompactPoll(): Promise<CompactPollResult, Exception> {
|
// fun getCompactPoll(rooms: List<String>, server: String): Promise<Map<String,CompactPollResult>, Exception> {
|
||||||
// val request = Request()
|
// val request = Request(verb = POST, room = null, server = server, endpoint = "compact_poll", isAuthRequired = false)
|
||||||
|
//
|
||||||
|
// // build a request for all rooms
|
||||||
|
//
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fun getDefaultRoomsIfNeeded(): Promise<List<DefaultGroup>, Exception> {
|
fun getDefaultRoomsIfNeeded(): Promise<List<DefaultGroup>, Exception> {
|
||||||
@ -362,8 +361,9 @@ object OpenGroupAPIV2 {
|
|||||||
val earlyGroups = groups.map { group ->
|
val earlyGroups = groups.map { group ->
|
||||||
DefaultGroup(group.id, group.name, null)
|
DefaultGroup(group.id, group.name, null)
|
||||||
}
|
}
|
||||||
defaultRooms.replayCache.firstOrNull()?.let { groups ->
|
// see if we have any cached rooms, and if they already have images, don't overwrite with early non-image results
|
||||||
if (groups.none { it.image?.isNotEmpty() == true}) {
|
defaultRooms.replayCache.firstOrNull()?.let { replayed ->
|
||||||
|
if (replayed.none { it.image?.isNotEmpty() == true}) {
|
||||||
defaultRooms.tryEmit(earlyGroups)
|
defaultRooms.tryEmit(earlyGroups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user