Show smaller quote chains within larger quote chains.

main
Greyson Parrelli 2022-12-07 15:33:27 -05:00 zatwierdzone przez Alex Hart
rodzic 56f6888d49
commit f207a82d2f
4 zmienionych plików z 56 dodań i 9 usunięć

Wyświetl plik

@ -482,7 +482,7 @@ public class ConversationAdapter
/** /**
* Momentarily highlights a mention at the requested position. * Momentarily highlights a mention at the requested position.
*/ */
void pulseAtPosition(int position) { public void pulseAtPosition(int position) {
if (position >= 0 && position < getItemCount()) { if (position >= 0 && position < getItemCount()) {
int correctedPosition = isHeaderPosition(position) ? position + 1 : position; int correctedPosition = isHeaderPosition(position) ? position + 1 : position;

Wyświetl plik

@ -10,6 +10,8 @@ import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import org.thoughtcrime.securesms.R import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment import org.thoughtcrime.securesms.components.FixedRoundedCornerBottomSheetDialogFragment
import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager
@ -93,7 +95,16 @@ class MessageQuotesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment() {
messageAdapter.submitList(messages) { messageAdapter.submitList(messages) {
if (firstRender) { if (firstRender) {
(list.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(messages.size - 1, 100) val targetMessageId = MessageId.deserialize(arguments?.getString(KEY_MESSAGE_ID, null) ?: throw IllegalArgumentException())
val targetMessagePosition = messages.indexOfFirst { it.messageRecord.id == targetMessageId.id && it.messageRecord.isMms == targetMessageId.mms }
(list.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(targetMessagePosition, 100)
if (targetMessagePosition != messages.size - 1) {
(dialog as BottomSheetDialog).behavior.state = BottomSheetBehavior.STATE_EXPANDED
messageAdapter.pulseAtPosition(targetMessagePosition)
}
firstRender = false firstRender = false
} else if (!list.canScrollVertically(1)) { } else if (!list.canScrollVertically(1)) {
list.layoutManager?.scrollToPosition(0) list.layoutManager?.scrollToPosition(0)

Wyświetl plik

@ -35,28 +35,30 @@ class MessageQuotesRepository {
} }
val databaseObserver: DatabaseObserver = ApplicationDependencies.getDatabaseObserver() val databaseObserver: DatabaseObserver = ApplicationDependencies.getDatabaseObserver()
val observer = DatabaseObserver.Observer { emitter.onNext(getMessageInQuoteChainSync(application, messageId)) } val observer = DatabaseObserver.Observer { emitter.onNext(getMessagesInQuoteChainSync(application, messageId)) }
databaseObserver.registerConversationObserver(threadId, observer) databaseObserver.registerConversationObserver(threadId, observer)
emitter.setCancellable { databaseObserver.unregisterObserver(observer) } emitter.setCancellable { databaseObserver.unregisterObserver(observer) }
emitter.onNext(getMessageInQuoteChainSync(application, messageId)) emitter.onNext(getMessagesInQuoteChainSync(application, messageId))
} }
} }
@WorkerThread @WorkerThread
private fun getMessageInQuoteChainSync(application: Application, messageId: MessageId): List<ConversationMessage> { private fun getMessagesInQuoteChainSync(application: Application, messageId: MessageId): List<ConversationMessage> {
var originalRecord: MessageRecord? = if (messageId.mms) { val rootMessageId: MessageId = SignalDatabase.mmsSms.getRootOfQuoteChain(messageId)
SignalDatabase.mms.getMessageRecordOrNull(messageId.id)
var originalRecord: MessageRecord? = if (rootMessageId.mms) {
SignalDatabase.mms.getMessageRecordOrNull(rootMessageId.id)
} else { } else {
SignalDatabase.sms.getMessageRecordOrNull(messageId.id) SignalDatabase.sms.getMessageRecordOrNull(rootMessageId.id)
} }
if (originalRecord == null) { if (originalRecord == null) {
return emptyList() return emptyList()
} }
val replyRecords: List<MessageRecord> = SignalDatabase.mmsSms.getAllMessagesThatQuote(messageId) val replyRecords: List<MessageRecord> = SignalDatabase.mmsSms.getAllMessagesThatQuote(rootMessageId)
val replies: List<ConversationMessage> = ConversationDataSource.ReactionHelper() val replies: List<ConversationMessage> = ConversationDataSource.ReactionHelper()
.apply { .apply {

Wyświetl plik

@ -38,6 +38,7 @@ import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
import org.thoughtcrime.securesms.database.model.MessageExportStatus; import org.thoughtcrime.securesms.database.model.MessageExportStatus;
import org.thoughtcrime.securesms.database.model.MessageId; import org.thoughtcrime.securesms.database.model.MessageId;
import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExportState; import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExportState;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.notifications.v2.DefaultMessageNotifier; import org.thoughtcrime.securesms.notifications.v2.DefaultMessageNotifier;
@ -290,6 +291,39 @@ public class MmsSmsTable extends DatabaseTable {
} }
} }
public MessageId getRootOfQuoteChain(@NonNull MessageId id) {
if (!id.isMms()) {
return id;
}
MmsMessageRecord targetMessage;
try {
targetMessage = (MmsMessageRecord) SignalDatabase.mms().getMessageRecord(id.getId());
} catch (NoSuchMessageException e) {
throw new IllegalArgumentException("Invalid message ID!");
}
if (targetMessage.getQuote() == null) {
return id;
}
String query;
if (targetMessage.getQuote().getAuthor().equals(Recipient.self().getId())) {
query = MmsTable.DATE_SENT + " = " + targetMessage.getQuote().getId() + " AND (" + MmsSmsColumns.TYPE + " & " + MmsSmsColumns.Types.BASE_TYPE_MASK + ") = " + MmsSmsColumns.Types.BASE_SENT_TYPE;
} else {
query = MmsTable.DATE_SENT + " = " + targetMessage.getQuote().getId() + " AND " + MmsTable.RECIPIENT_ID + " = '" + targetMessage.getQuote().getAuthor().serialize() + "'";
}
try (Reader reader = new Reader(queryTables(PROJECTION, query, null, "1", false))) {
MessageRecord record;
if ((record = reader.getNext()) != null) {
return getRootOfQuoteChain(new MessageId(record.getId(), record.isMms()));
}
}
return id;
}
public List<MessageRecord> getAllMessagesThatQuote(@NonNull MessageId id) { public List<MessageRecord> getAllMessagesThatQuote(@NonNull MessageId id) {
MessageRecord targetMessage; MessageRecord targetMessage;
try { try {