Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ interface StorageProtocol {
fun trimThreadBefore(threadID: Long, timestamp: Long)
fun getMessageCount(threadID: Long): Long
fun getTotalPinned(): Int
suspend fun getTotalSentProBadges(): Int
suspend fun getTotalSentLongMessages(): Int
fun setPinned(address: Address, isPinned: Boolean)
fun isRead(threadId: Long) : Boolean
fun setThreadCreationDate(threadId: Long, newDate: Long)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.annimon.stream.Stream
import com.bumptech.glide.Glide
import com.squareup.phrase.Phrase
import dagger.Lazy
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.lifecycle.withCreationCallback
import kotlinx.coroutines.CancellationException
Expand Down Expand Up @@ -119,7 +118,6 @@ import org.session.libsignal.crypto.MnemonicCodec
import org.session.libsignal.utilities.ListenableFuture
import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.toHexString
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.FullComposeActivity.Companion.applyCommonPropertiesForCompose
import org.thoughtcrime.securesms.ScreenLockActionBarActivity
import org.thoughtcrime.securesms.audio.AudioRecorderHandle
Expand All @@ -135,7 +133,6 @@ import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companio
import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companion.ON_REPLY
import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companion.ON_RESEND
import org.thoughtcrime.securesms.conversation.v2.MessageDetailActivity.Companion.ON_SAVE
import org.thoughtcrime.securesms.conversation.v2.dialogs.BlockedDialog
import org.thoughtcrime.securesms.conversation.v2.dialogs.LinkPreviewDialog
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarButton
import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarDelegate
Expand All @@ -158,7 +155,6 @@ import org.thoughtcrime.securesms.conversation.v2.utilities.AttachmentManager
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities
import org.thoughtcrime.securesms.conversation.v2.utilities.ResendMessageUtilities
import org.thoughtcrime.securesms.crypto.MnemonicUtilities
import org.thoughtcrime.securesms.database.AttachmentDatabase
import org.thoughtcrime.securesms.database.GroupDatabase
import org.thoughtcrime.securesms.database.LokiMessageDatabase
import org.thoughtcrime.securesms.database.MmsDatabase
Expand Down Expand Up @@ -2076,9 +2072,11 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
override fun sendMessage() {
val recipient = viewModel.recipient

// It shouldn't be possible to send a message to a blocked user anymore.
// But as a safety net:
// show the unblock dialog when trying to send a message to a blocked contact
if (recipient.isStandardRecipient && recipient.blocked) {
BlockedDialog(recipient.address, recipient.displayName()).show(supportFragmentManager, "Blocked Dialog")
unblock()
return
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ class InputBar @JvmOverloads constructor(
fun setCharLimitState(state: InputbarViewModel.InputBarCharLimitState?) {
// handle char limit
if(state != null){
binding.characterLimitText.text = state.count.toString()
binding.characterLimitText.text = state.countFormatted
binding.characterLimitText.setTextColor(if(state.danger) dangerColor else textColor)
binding.characterLimitContainer.setOnClickListener {
delegate?.onCharLimitTapped()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ fun ConversationSettingsDialogs(
iconRes = R.drawable.ic_pro_badge,
iconSize = 40.sp to 18.sp,
style = LocalType.current.large,
textQaTag = stringResource(R.string.qa_cta_body)
)
},
content = { CTAImage(heroImage = R.drawable.cta_hero_group) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity.CLIPBOARD_SERVICE
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import com.squareup.phrase.Phrase
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
Expand Down Expand Up @@ -713,14 +714,17 @@ class ConversationSettingsViewModel @AssistedInject constructor(
private fun pinConversation(){
// check the pin limit before continuing
val totalPins = storage.getTotalPinned()
val maxPins = proStatusManager.getPinnedConversationLimit(recipientRepository.getSelf().isPro)
if(totalPins >= maxPins){
val maxPins =
proStatusManager.getPinnedConversationLimit(recipientRepository.getSelf().isPro)
if (totalPins >= maxPins) {
// the user has reached the pin limit, show the CTA
_dialogState.update {
it.copy(pinCTA = PinProCTA(
overTheLimit = totalPins > maxPins,
proSubscription = proStatusManager.proDataState.value.type
))
it.copy(
pinCTA = PinProCTA(
overTheLimit = totalPins > maxPins,
proSubscription = proStatusManager.proDataState.value.type
)
)
}
} else {
viewModelScope.launch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,32 @@ class MmsDatabase @Inject constructor(
.any { MmsSmsColumns.Types.isOutgoingMessageType(it) }
}

fun getOutgoingMessageProFeatureCount(featureMask: Long): Int {
return getOutgoingProFeatureCountInternal(PRO_MESSAGE_FEATURES, featureMask)
}

fun getOutgoingProfileProFeatureCount(featureMask: Long): Int {
return getOutgoingProFeatureCountInternal(PRO_PROFILE_FEATURES, featureMask)
}

private fun getOutgoingProFeatureCountInternal(column: String, featureMask: Long): Int {
val db = readableDatabase
val outgoingTypes = MmsSmsColumns.Types.OUTGOING_MESSAGE_TYPES.joinToString(",")

// outgoing clause
val outgoingSelection =
"($MESSAGE_BOX & ${MmsSmsColumns.Types.BASE_TYPE_MASK}) IN ($outgoingTypes)"

val where = "($column & $featureMask) != 0 AND $outgoingSelection"

db.query(TABLE_NAME, arrayOf("COUNT(*)"), where, null, null, null, null).use { cursor ->
if (cursor.moveToFirst()) {
return cursor.getInt(0)
}
}
return 0
}

fun isDeletedMessage(id: Long): Boolean =
writableDatabase.query(
TABLE_NAME,
Expand Down Expand Up @@ -703,7 +729,7 @@ class MmsDatabase @Inject constructor(
val deletedMessageIDs: MutableList<Long>
val deletedMessagesThreadIDs = hashSetOf<Long>()

writableDatabase.rawQuery(
writableDatabase.rawQuery(
"DELETE FROM $TABLE_NAME WHERE $where RETURNING $ID, $THREAD_ID",
*whereArgs
).use { cursor ->
Expand Down Expand Up @@ -1055,12 +1081,12 @@ class MmsDatabase @Inject constructor(
val quoteText = retrievedQuote?.body
val quoteMissing = retrievedQuote == null
val quoteDeck = (
(retrievedQuote as? MmsMessageRecord)?.slideDeck ?:
Stream.of(attachmentDatabase.getAttachment(cursor))
.filter { obj: DatabaseAttachment? -> obj!!.isQuote }
.toList()
.let { SlideDeck(context, it) }
)
(retrievedQuote as? MmsMessageRecord)?.slideDeck ?:
Stream.of(attachmentDatabase.getAttachment(cursor))
.filter { obj: DatabaseAttachment? -> obj!!.isQuote }
.toList()
.let { SlideDeck(context, it) }
)
return Quote(
quoteId,
recipientRepository.getRecipientSync(quoteAuthor.toAddress()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
import dagger.hilt.android.qualifiers.ApplicationContext;
import kotlin.Pair;
import kotlin.Triple;
import network.loki.messenger.libsession_util.protocol.ProFeature;
import network.loki.messenger.libsession_util.protocol.ProMessageFeature;

@Singleton
public class MmsSmsDatabase extends Database {
Expand Down Expand Up @@ -427,6 +429,17 @@ public long getConversationCount(long threadId) {
return count;
}

public int getOutgoingMessageProFeatureCount(long featureMask) {
return smsDatabase.get().getOutgoingMessageProFeatureCount(featureMask) +
mmsDatabase.get().getOutgoingMessageProFeatureCount(featureMask);
}

public int getOutgoingProfileProFeatureCount(long featureMask) {
return smsDatabase.get().getOutgoingProfileProFeatureCount(featureMask) +
mmsDatabase.get().getOutgoingProfileProFeatureCount(featureMask);
}


public void incrementReadReceiptCount(SyncMessageId syncMessageId, long timestamp) {
smsDatabase.get().incrementReceiptCount(syncMessageId, false, true);
mmsDatabase.get().incrementReceiptCount(syncMessageId, timestamp, false, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,39 @@ public boolean isOutgoingMessage(long id) {
return isOutgoing;
}

public int getOutgoingMessageProFeatureCount(long featureMask) {
return getOutgoingProFeatureCountInternal(PRO_MESSAGE_FEATURES, featureMask);
}

public int getOutgoingProfileProFeatureCount(long featureMask) {
return getOutgoingProFeatureCountInternal(PRO_PROFILE_FEATURES, featureMask);
}

private int getOutgoingProFeatureCountInternal(@NonNull String columnName, long featureMask) {
SQLiteDatabase db = getReadableDatabase();

// outgoing clause
StringBuilder outgoingTypes = new StringBuilder();
long[] types = MmsSmsColumns.Types.OUTGOING_MESSAGE_TYPES;
for (int i = 0; i < types.length; i++) {
if (i > 0) outgoingTypes.append(",");
outgoingTypes.append(types[i]);
}

String outgoingSelection =
"(" + TYPE + " & " + MmsSmsColumns.Types.BASE_TYPE_MASK + ") IN (" + outgoingTypes + ")";

String where = "(" + columnName + " & " + featureMask + ") != 0 AND " + outgoingSelection;

try (Cursor cursor = db.query(TABLE_NAME, new String[]{"COUNT(*)"}, where, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
return cursor.getInt(0);
}
}

return 0;
}

public boolean isDeletedMessage(long id) {
SQLiteDatabase database = getWritableDatabase();
Cursor cursor = null;
Expand Down
23 changes: 23 additions & 0 deletions app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ import android.content.Context
import android.net.Uri
import dagger.Lazy
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import network.loki.messenger.libsession_util.MutableConversationVolatileConfig
import network.loki.messenger.libsession_util.PRIORITY_PINNED
import network.loki.messenger.libsession_util.PRIORITY_VISIBLE
import network.loki.messenger.libsession_util.ReadableUserGroupsConfig
import network.loki.messenger.libsession_util.protocol.ProFeature
import network.loki.messenger.libsession_util.protocol.ProMessageFeature
import network.loki.messenger.libsession_util.protocol.ProProfileFeature
import network.loki.messenger.libsession_util.util.BlindKeyAPI
import network.loki.messenger.libsession_util.util.Bytes
import network.loki.messenger.libsession_util.util.Conversation
Expand Down Expand Up @@ -945,6 +950,24 @@ open class Storage @Inject constructor(
}
}

override suspend fun getTotalSentProBadges(): Int =
getTotalSentForFeature(ProProfileFeature.PRO_BADGE)

override suspend fun getTotalSentLongMessages(): Int =
getTotalSentForFeature(ProMessageFeature.HIGHER_CHARACTER_LIMIT)

suspend fun getTotalSentForFeature(feature: ProFeature): Int = withContext(Dispatchers.IO) {
val mask = 1L shl feature.bitIndex

when (feature) {
is ProMessageFeature ->
mmsSmsDatabase.getOutgoingMessageProFeatureCount(mask)

is ProProfileFeature ->
mmsSmsDatabase.getOutgoingProfileProFeatureCount(mask)
}
}

override fun setPinned(address: Address, isPinned: Boolean) {
val isLocalNumber = address.address == getUserPublicKey()
configFactory.withMutableUserConfigs { configs ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,8 @@ class HomeViewModel @Inject constructor(
fun setPinned(address: Address, pinned: Boolean) {
// check the pin limit before continuing
val totalPins = storage.getTotalPinned()
val maxPins = proStatusManager.getPinnedConversationLimit(recipientRepository.getSelf().isPro)
val maxPins =
proStatusManager.getPinnedConversationLimit(recipientRepository.getSelf().isPro)
if (pinned && totalPins >= maxPins) {
// the user has reached the pin limit, show the CTA
_dialogsState.update {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,9 @@ fun AnimatedProCTA(

// main message
Text(
modifier = Modifier.align(Alignment.CenterHorizontally),
modifier = Modifier
.qaTag(R.string.qa_cta_body)
.align(Alignment.CenterHorizontally),
text = stringResource(R.string.proAnimatedDisplayPicture),
textAlign = TextAlign.Center,
style = LocalType.current.base.copy(
Expand Down
Loading