Skip to content

Commit c197125

Browse files
committed
Merge branch 'dev' into refactor/avatar-cleanup
2 parents 76b9075 + eee71fd commit c197125

File tree

54 files changed

+2750
-770
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2750
-770
lines changed

app/build.gradle.kts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,6 @@ dependencies {
386386
implementation(libs.subsampling.scale.image.view) {
387387
exclude(group = "com.android.support", module = "support-annotations")
388388
}
389-
implementation(libs.tooltips) {
390-
exclude(group = "com.android.support", module = "appcompat-v7")
391-
}
392389
implementation(libs.stream)
393390
implementation(libs.androidx.sqlite.ktx)
394391
implementation(libs.sqlcipher.android)

app/src/main/java/org/session/libsession/utilities/StringSubKeys.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,11 @@ object StringSubstitutionConstants {
4949
const val STORE_VARIANT_KEY: StringSubKey = "storevariant"
5050
const val APP_PRO_KEY: StringSubKey = "app_pro"
5151
const val PRO_KEY: StringSubKey = "pro"
52+
const val CURRENT_PLAN_KEY: StringSubKey = "current_plan"
53+
const val SELECTED_PLAN_KEY: StringSubKey = "selected_plan"
54+
const val PLATFORM_STORE_KEY: StringSubKey = "platform_store"
55+
const val PLATFORM_ACCOUNT_KEY: StringSubKey = "platform_account"
56+
const val MONTHLY_PRICE_KEY: StringSubKey = "monthly_price"
57+
const val PRICE_KEY: StringSubKey = "price"
58+
const val PERCENT_KEY: StringSubKey = "percent"
5259
}

app/src/main/java/org/session/libsession/utilities/TextSecurePreferences.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import org.session.libsession.utilities.TextSecurePreferences.Companion.SHOWN_CA
4545
import org.session.libsession.utilities.TextSecurePreferences.Companion.SHOWN_CALL_WARNING
4646
import org.session.libsession.utilities.TextSecurePreferences.Companion._events
4747
import org.session.libsignal.utilities.Log
48+
import org.thoughtcrime.securesms.debugmenu.DebugMenuViewModel
4849
import org.thoughtcrime.securesms.pro.ProStatusManager
4950
import org.thoughtcrime.securesms.util.DateUtils.Companion.secondsToInstant
5051
import org.thoughtcrime.securesms.util.DateUtils.Companion.toEpochSeconds
@@ -211,6 +212,12 @@ interface TextSecurePreferences {
211212
fun getDebugMessageFeatures(): Set<ProStatusManager.MessageProFeature>
212213
fun setDebugMessageFeatures(features: Set<ProStatusManager.MessageProFeature>)
213214

215+
fun getDebugSubscriptionType(): DebugMenuViewModel.DebugSubscriptionStatus?
216+
fun setDebugSubscriptionType(status: DebugMenuViewModel.DebugSubscriptionStatus?)
217+
218+
fun setSubscriptionProvider(provider: String)
219+
fun getSubscriptionProvider(): String?
220+
214221
var deprecationStateOverride: String?
215222
var deprecatedTimeOverride: ZonedDateTime?
216223
var deprecatingStartTimeOverride: ZonedDateTime?
@@ -367,6 +374,9 @@ interface TextSecurePreferences {
367374
const val IN_APP_REVIEW_STATE = "in_app_review_state"
368375

369376
const val DEBUG_MESSAGE_FEATURES = "debug_message_features"
377+
const val DEBUG_SUBSCRIPTION_STATUS = "debug_subscription_status"
378+
379+
const val SUBSCRIPTION_PROVIDER = "session_subscription_provider"
370380

371381
@JvmStatic
372382
fun getConfigurationMessageSynced(context: Context): Boolean {
@@ -1745,4 +1755,22 @@ class AppTextSecurePreferences @Inject constructor(
17451755
override fun setDebugMessageFeatures(features: Set<ProStatusManager.MessageProFeature>) {
17461756
setStringSetPreference(TextSecurePreferences.DEBUG_MESSAGE_FEATURES, features.map { it.name }.toSet())
17471757
}
1758+
1759+
override fun getDebugSubscriptionType(): DebugMenuViewModel.DebugSubscriptionStatus? {
1760+
return getStringPreference(TextSecurePreferences.DEBUG_SUBSCRIPTION_STATUS, null)?.let {
1761+
DebugMenuViewModel.DebugSubscriptionStatus.valueOf(it)
1762+
}
1763+
}
1764+
1765+
override fun setDebugSubscriptionType(status: DebugMenuViewModel.DebugSubscriptionStatus?) {
1766+
setStringPreference(TextSecurePreferences.DEBUG_SUBSCRIPTION_STATUS, status?.name)
1767+
}
1768+
1769+
override fun getSubscriptionProvider(): String? {
1770+
return getStringPreference(TextSecurePreferences.SUBSCRIPTION_PROVIDER, null)
1771+
}
1772+
1773+
override fun setSubscriptionProvider(provider: String) {
1774+
setStringPreference(TextSecurePreferences.SUBSCRIPTION_PROVIDER, provider)
1775+
}
17481776
}

app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,6 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
356356
private val adapter by lazy {
357357
val adapter = ConversationAdapter(
358358
this,
359-
null,
360359
storage.getLastSeen(viewModel.threadId),
361360
false,
362361
onItemPress = { message, position, view, event ->
@@ -367,7 +366,7 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
367366
},
368367
onItemLongPress = { message, position, view ->
369368
// long pressing message for blocked users should show unblock dialog
370-
if (viewModel.recipient.blocked == true) unblock()
369+
if (viewModel.recipient.blocked) unblock()
371370
else {
372371
if (!viewModel.isMessageRequestThread) {
373372
showConversationReaction(message, view)
@@ -384,6 +383,7 @@ class ConversationActivityV2 : ScreenLockActionBarActivity(), InputBarDelegate,
384383
downloadPendingAttachment = viewModel::downloadPendingAttachment,
385384
retryFailedAttachments = viewModel::retryFailedAttachments,
386385
glide = glide,
386+
threadRecipientProvider = viewModel::recipient,
387387
)
388388
adapter.visibleMessageViewDelegate = this
389389
adapter

app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@ import android.database.Cursor
55
import android.view.MotionEvent
66
import android.view.View
77
import android.view.ViewGroup
8-
import androidx.annotation.WorkerThread
9-
import androidx.lifecycle.LifecycleCoroutineScope
108
import androidx.recyclerview.widget.RecyclerView.ViewHolder
119
import com.bumptech.glide.RequestManager
1210
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
11+
import org.session.libsession.utilities.recipients.Recipient
1312
import org.thoughtcrime.securesms.conversation.v2.messages.ControlMessageView
1413
import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageView
1514
import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageViewDelegate
1615
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter
16+
import org.thoughtcrime.securesms.database.MmsSmsColumns
17+
import org.thoughtcrime.securesms.database.MmsSmsDatabase
1718
import org.thoughtcrime.securesms.database.model.MessageId
1819
import org.thoughtcrime.securesms.database.model.MessageRecord
1920
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
2021
import java.util.concurrent.atomic.AtomicLong
21-
import kotlin.math.min
2222
import kotlin.math.max
23+
import kotlin.math.min
2324

2425
class ConversationAdapter(
2526
context: Context,
26-
cursor: Cursor?,
2727
originalLastSeen: Long,
2828
private val isReversed: Boolean,
2929
private val onItemPress: (MessageRecord, Int, VisibleMessageView, MotionEvent) -> Unit,
@@ -32,8 +32,9 @@ class ConversationAdapter(
3232
private val onDeselect: (MessageRecord) -> Unit,
3333
private val downloadPendingAttachment: (DatabaseAttachment) -> Unit,
3434
private val retryFailedAttachments: (List<DatabaseAttachment>) -> Unit,
35-
private val glide: RequestManager
36-
) : CursorRecyclerViewAdapter<ViewHolder>(context, cursor) {
35+
private val glide: RequestManager,
36+
private val threadRecipientProvider: () -> Recipient,
37+
) : CursorRecyclerViewAdapter<ViewHolder>(context) {
3738
private val messageDB by lazy { DatabaseComponent.get(context).mmsSmsDatabase() }
3839
var selectedItems = mutableSetOf<MessageRecord>()
3940
var isAdmin: Boolean = false
@@ -52,42 +53,40 @@ class ConversationAdapter(
5253

5354
private val expandedMessageIds = mutableSetOf<MessageId>()
5455

55-
56-
sealed class ViewType(val rawValue: Int) {
57-
object Visible : ViewType(0)
58-
object Control : ViewType(1)
59-
60-
companion object {
61-
62-
val allValues: Map<Int, ViewType> get() = mapOf(
63-
Visible.rawValue to Visible,
64-
Control.rawValue to Control
65-
)
66-
}
56+
init {
57+
setHasStableIds(true)
6758
}
6859

6960
class VisibleMessageViewHolder(val view: VisibleMessageView) : ViewHolder(view)
7061
class ControlMessageViewHolder(val view: ControlMessageView) : ViewHolder(view)
7162

7263
override fun getItemViewType(cursor: Cursor): Int {
7364
val message = getMessage(cursor)!!
74-
if (message.isControlMessage) { return ViewType.Control.rawValue }
75-
return ViewType.Visible.rawValue
65+
if (message.isControlMessage) { return VIEW_TYPE_CONTROL }
66+
return VIEW_TYPE_VISIBLE
7667
}
7768

78-
override fun onCreateItemViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
79-
@Suppress("NAME_SHADOWING")
80-
val viewType = ViewType.allValues[viewType]
69+
override fun onCreateViewHolder(
70+
parent: ViewGroup,
71+
viewType: Int
72+
): ViewHolder {
8173
return when (viewType) {
82-
ViewType.Visible -> VisibleMessageViewHolder(VisibleMessageView(context))
83-
ViewType.Control -> ControlMessageViewHolder(ControlMessageView(context))
74+
VIEW_TYPE_VISIBLE -> VisibleMessageViewHolder(VisibleMessageView(context))
75+
VIEW_TYPE_CONTROL -> ControlMessageViewHolder(ControlMessageView(context))
8476
else -> throw IllegalStateException("Unexpected view type: $viewType.")
8577
}
8678
}
8779

88-
override fun onBindItemViewHolder(viewHolder: ViewHolder, cursor: Cursor) {
80+
override fun getItemId(cursor: Cursor): Long {
81+
// Try to make a unique id out of the real message id, which is a composite structure: (id, is_mms)
82+
// It assumes that the id won't exceed a signed long, which is not the most correct but it's good enough.
83+
val id = cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.ID))
84+
val isMms = cursor.getString(cursor.getColumnIndexOrThrow(MmsSmsDatabase.TRANSPORT)) == MmsSmsDatabase.SMS_TRANSPORT
85+
return if (isMms) id else -id
86+
}
87+
88+
override fun onBindItemViewHolder(viewHolder: ViewHolder, cursor: Cursor, position: Int) {
8989
val message = getMessage(cursor)!!
90-
val position = viewHolder.adapterPosition
9190
val messageBefore = getMessageBefore(position, cursor)
9291
when (viewHolder) {
9392
is VisibleMessageViewHolder -> {
@@ -99,6 +98,7 @@ class ConversationAdapter(
9998

10099
visibleMessageView.bind(
101100
message = message,
101+
threadRecipient = threadRecipientProvider(),
102102
previous = messageBefore,
103103
next = getMessageAfter(position, cursor),
104104
glide = glide,
@@ -199,7 +199,11 @@ class ConversationAdapter(
199199
if (position == null || position == -1) {
200200
toRemove += selected
201201
} else {
202-
val item = getMessage(getCursorAtPositionOrThrow(position))
202+
val item = cursor?.let {
203+
it.moveToPosition(position)
204+
getMessage(it)
205+
}
206+
203207
if (item == null || item.isDeleted) {
204208
toDeselect += selected
205209
}
@@ -270,4 +274,9 @@ class ConversationAdapter(
270274
val maxReactionTimestamp = message.reactions.maxOf { it.dateReceived }
271275
return max(message.timestamp, maxReactionTimestamp)
272276
}
277+
278+
companion object {
279+
private const val VIEW_TYPE_VISIBLE = 1
280+
private const val VIEW_TYPE_CONTROL = 2
281+
}
273282
}

app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ import org.session.libsession.database.StorageProtocol
6969
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
7070
import org.session.libsession.utilities.NonTranslatableStringConstants
7171
import org.session.libsession.utilities.StringSubstitutionConstants.APP_PRO_KEY
72+
import org.session.libsession.utilities.StringSubstitutionConstants.PRO_KEY
7273
import org.thoughtcrime.securesms.MediaPreviewActivity
7374
import org.thoughtcrime.securesms.ScreenLockActionBarActivity
7475
import org.thoughtcrime.securesms.database.model.MessageId
@@ -83,13 +84,14 @@ import org.thoughtcrime.securesms.ui.Divider
8384
import org.thoughtcrime.securesms.ui.GenericProCTA
8485
import org.thoughtcrime.securesms.ui.GetString
8586
import org.thoughtcrime.securesms.ui.HorizontalPagerIndicator
86-
import org.thoughtcrime.securesms.ui.LargeItemButton
87+
import org.thoughtcrime.securesms.ui.ItemButton
8788
import org.thoughtcrime.securesms.ui.LongMessageProCTA
8889
import org.thoughtcrime.securesms.ui.ProBadgeText
8990
import org.thoughtcrime.securesms.ui.ProCTAFeature
9091
import org.thoughtcrime.securesms.ui.TitledText
9192
import org.thoughtcrime.securesms.ui.UserProfileModal
9293
import org.thoughtcrime.securesms.ui.components.Avatar
94+
import org.thoughtcrime.securesms.ui.components.annotatedStringResource
9395
import org.thoughtcrime.securesms.ui.setComposeContent
9496
import org.thoughtcrime.securesms.ui.theme.LocalColors
9597
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
@@ -441,42 +443,42 @@ fun CellButtons(
441443
Cell(modifier = Modifier.padding(horizontal = LocalDimensions.current.spacing)) {
442444
Column {
443445
onReply?.let {
444-
LargeItemButton(
445-
R.string.reply,
446+
ItemButton(
447+
annotatedStringResource(R.string.reply),
446448
R.drawable.ic_reply,
447449
onClick = it
448450
)
449451
Divider()
450452
}
451453

452454
onResend?.let {
453-
LargeItemButton(
454-
R.string.resend,
455+
ItemButton(
456+
annotatedStringResource(R.string.resend),
455457
R.drawable.ic_repeat_2,
456458
onClick = it
457459
)
458460
Divider()
459461
}
460462

461-
LargeItemButton(
462-
R.string.messageCopy,
463+
ItemButton(
464+
annotatedStringResource(R.string.messageCopy),
463465
R.drawable.ic_copy,
464466
onClick = onCopy
465467
)
466468
Divider()
467469

468470
onSave?.let {
469-
LargeItemButton(
470-
R.string.save,
471+
ItemButton(
472+
annotatedStringResource(R.string.save),
471473
R.drawable.ic_arrow_down_to_line,
472474
onClick = it
473475
)
474476
Divider()
475477
}
476478

477479
onDelete?.let {
478-
LargeItemButton(
479-
R.string.delete,
480+
ItemButton(
481+
annotatedStringResource(R.string.delete),
480482
R.drawable.ic_trash_2,
481483
colors = dangerButtonColors(),
482484
onClick = it

app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailsViewModel.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,16 @@ data class MessageDetailsState(
356356
val proBadgeClickable: Boolean = false,
357357
) {
358358
val fromTitle = GetString(R.string.from)
359-
val canReply: Boolean get() = !readOnly && record?.isOpenGroupInvitation != true && error == null
359+
// can reply if we:
360+
// - are not read only
361+
// - are not an open group invitation
362+
// - do not have any errors
363+
// - are not in a sending state
364+
val canReply: Boolean get() = !readOnly
365+
&& record?.isOpenGroupInvitation != true
366+
&& error == null
367+
&& record?.isFailed == false
368+
&& record?.isSending == false
360369
val canDelete: Boolean get() = !readOnly
361370
}
362371

app/src/main/java/org/thoughtcrime/securesms/conversation/v2/input_bar/InputBar.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import android.widget.TextView
1616
import androidx.core.view.isGone
1717
import androidx.core.view.isVisible
1818
import com.bumptech.glide.RequestManager
19+
import dagger.hilt.android.AndroidEntryPoint
1920
import network.loki.messenger.R
2021
import network.loki.messenger.databinding.ViewInputBarBinding
2122
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
@@ -49,6 +50,7 @@ enum class VoiceRecorderState {
4950
ShuttingDownAfterRecord
5051
}
5152

53+
@AndroidEntryPoint
5254
@SuppressLint("ClickableViewAccessibility")
5355
class InputBar @JvmOverloads constructor(
5456
context: Context,

0 commit comments

Comments
 (0)